From 6cbad98852e694f28e5bb0498ad0338f96aaebd8 Mon Sep 17 00:00:00 2001 From: xback <1516748650@qq.com> Date: Tue, 7 Apr 2020 17:14:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=B6=E9=97=B4=EF=BC=9A4=E6=9C=887=E6=97=A5?= =?UTF-8?q?=20=E6=8F=90=E4=BA=A4=E4=BA=BA=EF=BC=9A=E5=AD=99=E7=8E=89?= =?UTF-8?q?=E5=85=A8=20=E6=96=B0=E5=A2=9E=E6=89=93=E5=8D=A1=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=80=9F=E4=B9=A6=E8=BF=98=E4=B9=A6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=AE=9A=E6=97=B6=E5=99=A8=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=AE=A4=E7=BB=9F=E8=AE=A1=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=AF=B9=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E5=AE=8C=E5=96=84=E3=80=82=20=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=BC=BA=E9=99=B7=EF=BC=9A=E8=BF=98=E4=B9=A6=E6=97=B6=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E8=87=AA=E5=B7=B1=E6=89=BE=E5=88=B0=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E4=B9=A6=E7=B1=8D=EF=BC=8C=E7=94=B5=E8=84=91=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=AE=8C=E5=90=8E=E4=B8=8D=E8=83=BD=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E5=89=8D=E7=9A=84=E7=8A=B6=E6=80=81=EF=BC=88?= =?UTF-8?q?=E5=A6=82=EF=BC=9A=E4=BD=BF=E7=94=A8=E5=89=8D=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=BA=E6=8D=9F=E5=9D=8F=EF=BC=8C=E4=BD=BF=E7=94=A8=E5=90=8E?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=87=AA=E5=8A=A8=E4=BF=AE=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=EF=BC=89=EF=BC=8Cexcel=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=AF=B9=E5=AE=9E=E4=BD=93=E4=B8=AD=E7=9A=84=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E8=A7=A3=E5=88=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + .../com/syq/controller/BooksController.java | 58 + .../com/syq/controller/ChartController.java | 4 +- .../syq/controller/ComputersController.java | 1 + .../syq/controller/ConsumelogsController.java | 172 + .../controller/ResourcesRoomController.java | 12 +- .../syq/controller/StudentsController.java | 31 + .../syq/controller/TeachersController.java | 34 + src/main/java/com/syq/entity/Books.java | 4 +- src/main/java/com/syq/entity/Computers.java | 2 +- src/main/java/com/syq/entity/Consumelogs.java | 17 +- .../com/syq/repository/BooksRepository.java | 45 + .../syq/repository/ComputersRepository.java | 11 + .../repository/ConsumelogsRepositorty.java | 80 + .../syq/repository/StatisticsRepository.java | 1 + .../com/syq/repository/StudentRepository.java | 19 + .../syq/repository/TeachersRepository.java | 14 + .../java/com/syq/service/BooksService.java | 30 + .../com/syq/service/ComputersService.java | 9 + .../com/syq/service/ConsumelogsService.java | 54 + .../java/com/syq/service/StudentsService.java | 5 + .../java/com/syq/service/TeachersService.java | 5 + .../syq/service/impl/BooksServiceImpl.java | 25 + .../service/impl/ComputersServiceImpl.java | 12 + .../service/impl/ConsumelogsServiceImpl.java | 60 + .../syq/service/impl/StudentsServiceImpl.java | 9 + .../syq/service/impl/TeachersServiceImpl.java | 6 + src/main/java/com/syq/task/MyTask.java | 69 + src/main/resources/static/PayCard.html | 129 + src/main/resources/static/book-fonts.html | 262 + src/main/resources/static/book.html | 455 + src/main/resources/static/bookType.html | 274 + src/main/resources/static/computer-fonts.html | 198 + src/main/resources/static/computer.html | 416 + src/main/resources/static/css/font.css | 16 + src/main/resources/static/css/login.css | 105 + src/main/resources/static/css/theme1.css | 21 + src/main/resources/static/css/theme2.css | 21 + src/main/resources/static/css/theme3.css | 22 + src/main/resources/static/css/theme4.css | 21 + src/main/resources/static/css/theme5.css | 27 + src/main/resources/static/css/xadmin.css | 534 + src/main/resources/static/demo.html | 40 + src/main/resources/static/fonts/iconfont.eot | Bin 0 -> 49600 bytes src/main/resources/static/fonts/iconfont.svg | 477 + src/main/resources/static/fonts/iconfont.ttf | Bin 0 -> 49432 bytes src/main/resources/static/fonts/iconfont.woff | Bin 0 -> 30200 bytes src/main/resources/static/images/aiwrap.png | Bin 0 -> 3032 bytes src/main/resources/static/images/bg.png | Bin 0 -> 28211 bytes src/main/resources/static/images/bimg1.jpg | Bin 0 -> 34501 bytes src/main/resources/static/images/bimg10.jpg | Bin 0 -> 36639 bytes src/main/resources/static/images/bimg2.jpg | Bin 0 -> 30119 bytes src/main/resources/static/images/bimg3.jpg | Bin 0 -> 35312 bytes src/main/resources/static/images/bimg4.jpg | Bin 0 -> 43931 bytes src/main/resources/static/images/bimg5.jpg | Bin 0 -> 26588 bytes src/main/resources/static/images/bimg6.jpg | Bin 0 -> 153396 bytes src/main/resources/static/images/bimg7.jpg | Bin 0 -> 252727 bytes src/main/resources/static/images/bimg8.jpg | Bin 0 -> 101468 bytes src/main/resources/static/images/bimg9.jpg | Bin 0 -> 87054 bytes src/main/resources/static/images/cimg1.jpg | Bin 0 -> 26729 bytes src/main/resources/static/images/cimg10.jpg | Bin 0 -> 14122 bytes src/main/resources/static/images/cimg2.jpg | Bin 0 -> 31189 bytes src/main/resources/static/images/cimg3.jpg | Bin 0 -> 39668 bytes src/main/resources/static/images/cimg4.jpg | Bin 0 -> 28726 bytes src/main/resources/static/images/cimg5.jpg | Bin 0 -> 34346 bytes src/main/resources/static/images/cimg6.jpg | Bin 0 -> 21167 bytes src/main/resources/static/images/cimg7.jpg | Bin 0 -> 54355 bytes src/main/resources/static/images/cimg8.jpg | Bin 0 -> 66661 bytes src/main/resources/static/images/cimg9.jpg | Bin 0 -> 31686 bytes src/main/resources/static/images/timg1.jpg | Bin 0 -> 30302 bytes src/main/resources/static/images/timg2.jpg | Bin 0 -> 110866 bytes src/main/resources/static/index.html | 215 + src/main/resources/static/js/echarts.js | 90902 ++++++++++++++++ src/main/resources/static/js/echarts.min.js | 22 + src/main/resources/static/js/echartsjs.rar | Bin 0 -> 908887 bytes src/main/resources/static/js/global.js | 6 + src/main/resources/static/js/jquery.min.js | 4 + src/main/resources/static/js/xadmin.js | 584 + src/main/resources/static/js/xcity.js | 506 + .../resources/static/lib/layui/css/layui.css | 2 + .../static/lib/layui/css/layui.mobile.css | 2 + .../static/lib/layui/css/modules/code.css | 2 + .../css/modules/laydate/default/laydate.css | 2 + .../css/modules/layer/default/icon-ext.png | Bin 0 -> 5911 bytes .../layui/css/modules/layer/default/icon.png | Bin 0 -> 11493 bytes .../layui/css/modules/layer/default/layer.css | 2 + .../css/modules/layer/default/loading-0.gif | Bin 0 -> 5793 bytes .../css/modules/layer/default/loading-1.gif | Bin 0 -> 701 bytes .../css/modules/layer/default/loading-2.gif | Bin 0 -> 1787 bytes .../static/lib/layui/font/iconfont.eot | Bin 0 -> 40844 bytes .../static/lib/layui/font/iconfont.svg | 473 + .../static/lib/layui/font/iconfont.ttf | Bin 0 -> 40668 bytes .../static/lib/layui/font/iconfont.woff | Bin 0 -> 26744 bytes .../static/lib/layui/images/face/0.gif | Bin 0 -> 2689 bytes .../static/lib/layui/images/face/1.gif | Bin 0 -> 5514 bytes .../static/lib/layui/images/face/10.gif | Bin 0 -> 2797 bytes .../static/lib/layui/images/face/11.gif | Bin 0 -> 4121 bytes .../static/lib/layui/images/face/12.gif | Bin 0 -> 3361 bytes .../static/lib/layui/images/face/13.gif | Bin 0 -> 7425 bytes .../static/lib/layui/images/face/14.gif | Bin 0 -> 2375 bytes .../static/lib/layui/images/face/15.gif | Bin 0 -> 1793 bytes .../static/lib/layui/images/face/16.gif | Bin 0 -> 6721 bytes .../static/lib/layui/images/face/17.gif | Bin 0 -> 4439 bytes .../static/lib/layui/images/face/18.gif | Bin 0 -> 3017 bytes .../static/lib/layui/images/face/19.gif | Bin 0 -> 3040 bytes .../static/lib/layui/images/face/2.gif | Bin 0 -> 3222 bytes .../static/lib/layui/images/face/20.gif | Bin 0 -> 5144 bytes .../static/lib/layui/images/face/21.gif | Bin 0 -> 5191 bytes .../static/lib/layui/images/face/22.gif | Bin 0 -> 9823 bytes .../static/lib/layui/images/face/23.gif | Bin 0 -> 3792 bytes .../static/lib/layui/images/face/24.gif | Bin 0 -> 8096 bytes .../static/lib/layui/images/face/25.gif | Bin 0 -> 3127 bytes .../static/lib/layui/images/face/26.gif | Bin 0 -> 3291 bytes .../static/lib/layui/images/face/27.gif | Bin 0 -> 4377 bytes .../static/lib/layui/images/face/28.gif | Bin 0 -> 2793 bytes .../static/lib/layui/images/face/29.gif | Bin 0 -> 4854 bytes .../static/lib/layui/images/face/3.gif | Bin 0 -> 4017 bytes .../static/lib/layui/images/face/30.gif | Bin 0 -> 2555 bytes .../static/lib/layui/images/face/31.gif | Bin 0 -> 2002 bytes .../static/lib/layui/images/face/32.gif | Bin 0 -> 3481 bytes .../static/lib/layui/images/face/33.gif | Bin 0 -> 2454 bytes .../static/lib/layui/images/face/34.gif | Bin 0 -> 3700 bytes .../static/lib/layui/images/face/35.gif | Bin 0 -> 1800 bytes .../static/lib/layui/images/face/36.gif | Bin 0 -> 2331 bytes .../static/lib/layui/images/face/37.gif | Bin 0 -> 1513 bytes .../static/lib/layui/images/face/38.gif | Bin 0 -> 3615 bytes .../static/lib/layui/images/face/39.gif | Bin 0 -> 6495 bytes .../static/lib/layui/images/face/4.gif | Bin 0 -> 5689 bytes .../static/lib/layui/images/face/40.gif | Bin 0 -> 3154 bytes .../static/lib/layui/images/face/41.gif | Bin 0 -> 3644 bytes .../static/lib/layui/images/face/42.gif | Bin 0 -> 5305 bytes .../static/lib/layui/images/face/43.gif | Bin 0 -> 2674 bytes .../static/lib/layui/images/face/44.gif | Bin 0 -> 4126 bytes .../static/lib/layui/images/face/45.gif | Bin 0 -> 3417 bytes .../static/lib/layui/images/face/46.gif | Bin 0 -> 3007 bytes .../static/lib/layui/images/face/47.gif | Bin 0 -> 2333 bytes .../static/lib/layui/images/face/48.gif | Bin 0 -> 2689 bytes .../static/lib/layui/images/face/49.gif | Bin 0 -> 2315 bytes .../static/lib/layui/images/face/5.gif | Bin 0 -> 4567 bytes .../static/lib/layui/images/face/50.gif | Bin 0 -> 5866 bytes .../static/lib/layui/images/face/51.gif | Bin 0 -> 2785 bytes .../static/lib/layui/images/face/52.gif | Bin 0 -> 777 bytes .../static/lib/layui/images/face/53.gif | Bin 0 -> 2127 bytes .../static/lib/layui/images/face/54.gif | Bin 0 -> 2196 bytes .../static/lib/layui/images/face/55.gif | Bin 0 -> 1971 bytes .../static/lib/layui/images/face/56.gif | Bin 0 -> 2034 bytes .../static/lib/layui/images/face/57.gif | Bin 0 -> 2705 bytes .../static/lib/layui/images/face/58.gif | Bin 0 -> 2258 bytes .../static/lib/layui/images/face/59.gif | Bin 0 -> 10311 bytes .../static/lib/layui/images/face/6.gif | Bin 0 -> 2213 bytes .../static/lib/layui/images/face/60.gif | Bin 0 -> 3245 bytes .../static/lib/layui/images/face/61.gif | Bin 0 -> 2495 bytes .../static/lib/layui/images/face/62.gif | Bin 0 -> 2017 bytes .../static/lib/layui/images/face/63.gif | Bin 0 -> 5871 bytes .../static/lib/layui/images/face/64.gif | Bin 0 -> 6448 bytes .../static/lib/layui/images/face/65.gif | Bin 0 -> 3576 bytes .../static/lib/layui/images/face/66.gif | Bin 0 -> 3029 bytes .../static/lib/layui/images/face/67.gif | Bin 0 -> 2701 bytes .../static/lib/layui/images/face/68.gif | Bin 0 -> 1424 bytes .../static/lib/layui/images/face/69.gif | Bin 0 -> 2431 bytes .../static/lib/layui/images/face/7.gif | Bin 0 -> 3398 bytes .../static/lib/layui/images/face/70.gif | Bin 0 -> 4590 bytes .../static/lib/layui/images/face/71.gif | Bin 0 -> 5304 bytes .../static/lib/layui/images/face/8.gif | Bin 0 -> 4050 bytes .../static/lib/layui/images/face/9.gif | Bin 0 -> 4221 bytes .../static/lib/layui/lay/modules/carousel.js | 2 + .../static/lib/layui/lay/modules/code.js | 2 + .../lib/layui/lay/modules/colorpicker.js | 2 + .../static/lib/layui/lay/modules/element.js | 2 + .../static/lib/layui/lay/modules/flow.js | 2 + .../static/lib/layui/lay/modules/form.js | 2 + .../static/lib/layui/lay/modules/jquery.js | 5 + .../static/lib/layui/lay/modules/laydate.js | 2 + .../static/lib/layui/lay/modules/layedit.js | 2 + .../static/lib/layui/lay/modules/layer.js | 2 + .../static/lib/layui/lay/modules/laypage.js | 2 + .../static/lib/layui/lay/modules/laytpl.js | 2 + .../static/lib/layui/lay/modules/mobile.js | 2 + .../static/lib/layui/lay/modules/rate.js | 2 + .../static/lib/layui/lay/modules/slider.js | 2 + .../static/lib/layui/lay/modules/table.js | 2 + .../static/lib/layui/lay/modules/tree.js | 2 + .../static/lib/layui/lay/modules/upload.js | 2 + .../static/lib/layui/lay/modules/util.js | 2 + .../resources/static/lib/layui/layui.all.js | 5 + src/main/resources/static/lib/layui/layui.js | 2 + src/main/resources/static/login.html | 65 + src/main/resources/static/resources-room.html | 197 + src/main/resources/static/room.html | 291 + src/main/resources/static/sections.html | 278 + src/main/resources/static/select.html | 40 + src/main/resources/static/statistics.html | 185 + src/main/resources/static/students.html | 578 + src/main/resources/static/system.html | 278 + src/main/resources/static/teacher.html | 523 + src/main/resources/static/user.json | 127 + src/main/resources/static/welcome.html | 400 + 197 files changed, 99528 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/syq/controller/ConsumelogsController.java create mode 100644 src/main/java/com/syq/repository/ConsumelogsRepositorty.java create mode 100644 src/main/java/com/syq/service/ConsumelogsService.java create mode 100644 src/main/java/com/syq/service/impl/ConsumelogsServiceImpl.java create mode 100644 src/main/java/com/syq/task/MyTask.java create mode 100644 src/main/resources/static/PayCard.html create mode 100644 src/main/resources/static/book-fonts.html create mode 100644 src/main/resources/static/book.html create mode 100644 src/main/resources/static/bookType.html create mode 100644 src/main/resources/static/computer-fonts.html create mode 100644 src/main/resources/static/computer.html create mode 100644 src/main/resources/static/css/font.css create mode 100644 src/main/resources/static/css/login.css create mode 100644 src/main/resources/static/css/theme1.css create mode 100644 src/main/resources/static/css/theme2.css create mode 100644 src/main/resources/static/css/theme3.css create mode 100644 src/main/resources/static/css/theme4.css create mode 100644 src/main/resources/static/css/theme5.css create mode 100644 src/main/resources/static/css/xadmin.css create mode 100644 src/main/resources/static/demo.html create mode 100644 src/main/resources/static/fonts/iconfont.eot create mode 100644 src/main/resources/static/fonts/iconfont.svg create mode 100644 src/main/resources/static/fonts/iconfont.ttf create mode 100644 src/main/resources/static/fonts/iconfont.woff create mode 100644 src/main/resources/static/images/aiwrap.png create mode 100644 src/main/resources/static/images/bg.png create mode 100644 src/main/resources/static/images/bimg1.jpg create mode 100644 src/main/resources/static/images/bimg10.jpg create mode 100644 src/main/resources/static/images/bimg2.jpg create mode 100644 src/main/resources/static/images/bimg3.jpg create mode 100644 src/main/resources/static/images/bimg4.jpg create mode 100644 src/main/resources/static/images/bimg5.jpg create mode 100644 src/main/resources/static/images/bimg6.jpg create mode 100644 src/main/resources/static/images/bimg7.jpg create mode 100644 src/main/resources/static/images/bimg8.jpg create mode 100644 src/main/resources/static/images/bimg9.jpg create mode 100644 src/main/resources/static/images/cimg1.jpg create mode 100644 src/main/resources/static/images/cimg10.jpg create mode 100644 src/main/resources/static/images/cimg2.jpg create mode 100644 src/main/resources/static/images/cimg3.jpg create mode 100644 src/main/resources/static/images/cimg4.jpg create mode 100644 src/main/resources/static/images/cimg5.jpg create mode 100644 src/main/resources/static/images/cimg6.jpg create mode 100644 src/main/resources/static/images/cimg7.jpg create mode 100644 src/main/resources/static/images/cimg8.jpg create mode 100644 src/main/resources/static/images/cimg9.jpg create mode 100644 src/main/resources/static/images/timg1.jpg create mode 100644 src/main/resources/static/images/timg2.jpg create mode 100644 src/main/resources/static/index.html create mode 100644 src/main/resources/static/js/echarts.js create mode 100644 src/main/resources/static/js/echarts.min.js create mode 100644 src/main/resources/static/js/echartsjs.rar create mode 100644 src/main/resources/static/js/global.js create mode 100644 src/main/resources/static/js/jquery.min.js create mode 100644 src/main/resources/static/js/xadmin.js create mode 100644 src/main/resources/static/js/xcity.js create mode 100644 src/main/resources/static/lib/layui/css/layui.css create mode 100644 src/main/resources/static/lib/layui/css/layui.mobile.css create mode 100644 src/main/resources/static/lib/layui/css/modules/code.css create mode 100644 src/main/resources/static/lib/layui/css/modules/laydate/default/laydate.css create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/icon-ext.png create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/icon.png create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/layer.css create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/loading-0.gif create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/loading-1.gif create mode 100644 src/main/resources/static/lib/layui/css/modules/layer/default/loading-2.gif create mode 100644 src/main/resources/static/lib/layui/font/iconfont.eot create mode 100644 src/main/resources/static/lib/layui/font/iconfont.svg create mode 100644 src/main/resources/static/lib/layui/font/iconfont.ttf create mode 100644 src/main/resources/static/lib/layui/font/iconfont.woff create mode 100644 src/main/resources/static/lib/layui/images/face/0.gif create mode 100644 src/main/resources/static/lib/layui/images/face/1.gif create mode 100644 src/main/resources/static/lib/layui/images/face/10.gif create mode 100644 src/main/resources/static/lib/layui/images/face/11.gif create mode 100644 src/main/resources/static/lib/layui/images/face/12.gif create mode 100644 src/main/resources/static/lib/layui/images/face/13.gif create mode 100644 src/main/resources/static/lib/layui/images/face/14.gif create mode 100644 src/main/resources/static/lib/layui/images/face/15.gif create mode 100644 src/main/resources/static/lib/layui/images/face/16.gif create mode 100644 src/main/resources/static/lib/layui/images/face/17.gif create mode 100644 src/main/resources/static/lib/layui/images/face/18.gif create mode 100644 src/main/resources/static/lib/layui/images/face/19.gif create mode 100644 src/main/resources/static/lib/layui/images/face/2.gif create mode 100644 src/main/resources/static/lib/layui/images/face/20.gif create mode 100644 src/main/resources/static/lib/layui/images/face/21.gif create mode 100644 src/main/resources/static/lib/layui/images/face/22.gif create mode 100644 src/main/resources/static/lib/layui/images/face/23.gif create mode 100644 src/main/resources/static/lib/layui/images/face/24.gif create mode 100644 src/main/resources/static/lib/layui/images/face/25.gif create mode 100644 src/main/resources/static/lib/layui/images/face/26.gif create mode 100644 src/main/resources/static/lib/layui/images/face/27.gif create mode 100644 src/main/resources/static/lib/layui/images/face/28.gif create mode 100644 src/main/resources/static/lib/layui/images/face/29.gif create mode 100644 src/main/resources/static/lib/layui/images/face/3.gif create mode 100644 src/main/resources/static/lib/layui/images/face/30.gif create mode 100644 src/main/resources/static/lib/layui/images/face/31.gif create mode 100644 src/main/resources/static/lib/layui/images/face/32.gif create mode 100644 src/main/resources/static/lib/layui/images/face/33.gif create mode 100644 src/main/resources/static/lib/layui/images/face/34.gif create mode 100644 src/main/resources/static/lib/layui/images/face/35.gif create mode 100644 src/main/resources/static/lib/layui/images/face/36.gif create mode 100644 src/main/resources/static/lib/layui/images/face/37.gif create mode 100644 src/main/resources/static/lib/layui/images/face/38.gif create mode 100644 src/main/resources/static/lib/layui/images/face/39.gif create mode 100644 src/main/resources/static/lib/layui/images/face/4.gif create mode 100644 src/main/resources/static/lib/layui/images/face/40.gif create mode 100644 src/main/resources/static/lib/layui/images/face/41.gif create mode 100644 src/main/resources/static/lib/layui/images/face/42.gif create mode 100644 src/main/resources/static/lib/layui/images/face/43.gif create mode 100644 src/main/resources/static/lib/layui/images/face/44.gif create mode 100644 src/main/resources/static/lib/layui/images/face/45.gif create mode 100644 src/main/resources/static/lib/layui/images/face/46.gif create mode 100644 src/main/resources/static/lib/layui/images/face/47.gif create mode 100644 src/main/resources/static/lib/layui/images/face/48.gif create mode 100644 src/main/resources/static/lib/layui/images/face/49.gif create mode 100644 src/main/resources/static/lib/layui/images/face/5.gif create mode 100644 src/main/resources/static/lib/layui/images/face/50.gif create mode 100644 src/main/resources/static/lib/layui/images/face/51.gif create mode 100644 src/main/resources/static/lib/layui/images/face/52.gif create mode 100644 src/main/resources/static/lib/layui/images/face/53.gif create mode 100644 src/main/resources/static/lib/layui/images/face/54.gif create mode 100644 src/main/resources/static/lib/layui/images/face/55.gif create mode 100644 src/main/resources/static/lib/layui/images/face/56.gif create mode 100644 src/main/resources/static/lib/layui/images/face/57.gif create mode 100644 src/main/resources/static/lib/layui/images/face/58.gif create mode 100644 src/main/resources/static/lib/layui/images/face/59.gif create mode 100644 src/main/resources/static/lib/layui/images/face/6.gif create mode 100644 src/main/resources/static/lib/layui/images/face/60.gif create mode 100644 src/main/resources/static/lib/layui/images/face/61.gif create mode 100644 src/main/resources/static/lib/layui/images/face/62.gif create mode 100644 src/main/resources/static/lib/layui/images/face/63.gif create mode 100644 src/main/resources/static/lib/layui/images/face/64.gif create mode 100644 src/main/resources/static/lib/layui/images/face/65.gif create mode 100644 src/main/resources/static/lib/layui/images/face/66.gif create mode 100644 src/main/resources/static/lib/layui/images/face/67.gif create mode 100644 src/main/resources/static/lib/layui/images/face/68.gif create mode 100644 src/main/resources/static/lib/layui/images/face/69.gif create mode 100644 src/main/resources/static/lib/layui/images/face/7.gif create mode 100644 src/main/resources/static/lib/layui/images/face/70.gif create mode 100644 src/main/resources/static/lib/layui/images/face/71.gif create mode 100644 src/main/resources/static/lib/layui/images/face/8.gif create mode 100644 src/main/resources/static/lib/layui/images/face/9.gif create mode 100644 src/main/resources/static/lib/layui/lay/modules/carousel.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/code.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/colorpicker.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/element.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/flow.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/form.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/jquery.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/laydate.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/layedit.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/layer.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/laypage.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/laytpl.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/mobile.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/rate.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/slider.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/table.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/tree.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/upload.js create mode 100644 src/main/resources/static/lib/layui/lay/modules/util.js create mode 100644 src/main/resources/static/lib/layui/layui.all.js create mode 100644 src/main/resources/static/lib/layui/layui.js create mode 100644 src/main/resources/static/login.html create mode 100644 src/main/resources/static/resources-room.html create mode 100644 src/main/resources/static/room.html create mode 100644 src/main/resources/static/sections.html create mode 100644 src/main/resources/static/select.html create mode 100644 src/main/resources/static/statistics.html create mode 100644 src/main/resources/static/students.html create mode 100644 src/main/resources/static/system.html create mode 100644 src/main/resources/static/teacher.html create mode 100644 src/main/resources/static/user.json create mode 100644 src/main/resources/static/welcome.html diff --git a/pom.xml b/pom.xml index 34c90e5..0bd97de 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,12 @@ spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-quartz + + org.json json diff --git a/src/main/java/com/syq/controller/BooksController.java b/src/main/java/com/syq/controller/BooksController.java index 420982b..f0c687c 100644 --- a/src/main/java/com/syq/controller/BooksController.java +++ b/src/main/java/com/syq/controller/BooksController.java @@ -14,6 +14,7 @@ import com.syq.entity.BookType; import com.syq.entity.Books; import com.syq.entity.ResourcesRoom; import com.syq.service.BooksService; +import com.syq.util.Result; import com.syq.util.ResultInfoUtil; @RestController @@ -75,4 +76,61 @@ public class BooksController { book.setBid(bid); return booksService.deleteBooksById(book); } + + + /** + * @param bid:当前图书id + * @param borrow:当前图书借阅状态 + * @param cardno:当前要借阅者卡号 + * @return + */ + @PutMapping("/borrow") + public Result borrowBook(Integer bid,String borrow,String cardno) { + if(borrow.equals("0")) { + booksService.editBorrowReduceNumber(cardno, bid);//此书没有借阅者的情况时,将借阅状态修改为借阅者状态 + return new Result(0, "借阅成功"); + }else { + Books like = booksService.likeBookByBorrow(cardno, bid);//此书存在借阅者时,模糊查询当前借阅者卡号查看是否已经借阅过此书 + if(like!=null) { + return new Result(1, "您已借阅过此书"); + }else { + borrow += ("-"+ cardno);//此书有借阅者的情况并且不是当前借阅者时,将借阅者卡号拼接进状态中 + booksService.editBorrowReduceNumber(borrow, bid); + return new Result(0, "借阅成功"); + } + + } + } + + + /** + * @param bid:当前图书id + * @param borrow:当前图书借阅状态 + * @param cardno:当前要借阅者卡号 + * @return + */ + @PutMapping("/still") + public Result stillBook(Integer bid,String borrow,String cardno) { + if(borrow.equals("0")) { + return new Result(1, "你未曾借阅此书"); + }else { + Books like = booksService.likeBookByBorrow(cardno, bid);//根据当前借阅者卡号模糊查询,成功则确定您借阅过此书 + if(like!=null) { + String[] result = borrow.split("-"); + String oldborrow = "";//定义新的借阅状态 + for(int i=0;i cList = new ArrayList<>(); for(int i =0;i nums = new ArrayList<>(); + List nums = new ArrayList<>();//用于存放每个月的点击量 for(int j=0;j listComputersByPage(Computers com,Integer page,Integer limit) { + System.out.println(com.toString()); Pageable pageable = PageRequest.of(page-1, limit); return computersService.listComputersByPage(com, pageable); } diff --git a/src/main/java/com/syq/controller/ConsumelogsController.java b/src/main/java/com/syq/controller/ConsumelogsController.java new file mode 100644 index 0000000..165bd2c --- /dev/null +++ b/src/main/java/com/syq/controller/ConsumelogsController.java @@ -0,0 +1,172 @@ +package com.syq.controller; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.syq.entity.Consumelogs; +import com.syq.entity.Students; +import com.syq.entity.Teachers; +import com.syq.service.BooksService; +import com.syq.service.ComputersService; +import com.syq.service.ConsumelogsService; +import com.syq.service.StudentsService; +import com.syq.service.TeachersService; + +@RequestMapping("consumelogs") +@RestController +public class ConsumelogsController { + + @Autowired + private ConsumelogsService consumelogsService; + + @Autowired + private ComputersService computersService; + + @Autowired + private BooksService booksService; + + @Autowired + private StudentsService studentsService; + + @Autowired + private TeachersService teachersService; + + /** + * 根据当前打卡卡号查询该卡号是否有无未结束任务 + * @param cardno + * @return + */ + @GetMapping + public Consumelogs byCardno(String cardno) { + List consumelogs = consumelogsService.findConsumelogByCardno(cardno); + Consumelogs cons = new Consumelogs(); + for (Consumelogs con : consumelogs) { + if(con.getOuttime()==null) { + System.out.println(con.getConid()); + return con; + } + } + return cons; + } + + /** + * 当用户选择资源室后进行添加操作 + * @param log + * @return + */ + @PostMapping + public Integer insertConsumelogs(Consumelogs log,Integer rid,Integer comid,Integer bid) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// Date date +// String inTime = sdf.parse(); + log.setIntime(new Date()); + log.setStatus(1); + return consumelogsService.insertConsumelog(log,rid,comid,bid); + } + + /** + * 根据当前打卡的卡号和资源室id查询改日志下是否已有使用电脑, + * 如果为空将当前点击电脑id填入,如果已有则另外创建 + */ + @PutMapping("/computer") + public Integer editConsumelogsComputer(String cardno,Integer rid,Integer comid) { + Consumelogs consumelog = consumelogsService.findByInTime(cardno, rid); + if(consumelog.getComputers()==null) { + //执行更新 + consumelogsService.insertComputer(comid, consumelog.getConid()); + computersService.editComputerStatus(cardno, comid); + }else { + //执行添加 + Consumelogs log = new Consumelogs(); + log.setCardno(cardno); + log.setIntime(new Date()); + log.setStatus(1); + consumelogsService.insertConsumelog(log, rid, comid, null); + computersService.editComputerStatus(cardno, comid); + consumelog = consumelogsService.findByInTime(cardno, rid); + } + return consumelog.getConid(); + } + + /** + * 根据当前打卡的卡号和资源室id查询改日志下是否已有图书, + * 如果为空将当前点击图书id填入,如果已有则另外创建 + */ + @PutMapping("/book") + public Integer editConsumelogsBook(String cardno,Integer rid,Integer bid) { + Consumelogs consumelog = consumelogsService.findByInTime(cardno, rid); + if(consumelog.getBooks()==null) { + //执行更新 + consumelogsService.insertBook(bid, consumelog.getConid()); + booksService.editBookStatus(cardno, bid); + }else { + //执行添加 + Consumelogs log = new Consumelogs(); + log.setCardno(cardno); + log.setIntime(new Date()); + log.setStatus(1); + consumelogsService.insertConsumelog(log, rid, null, bid); + booksService.editBookStatus(cardno, bid); + consumelog = consumelogsService.findByInTime(cardno, rid); + } + return consumelog.getConid(); + } + + /** + * 离开当前计算机,并将当前日志设置离开时间 + */ + @PutMapping("/OutComputer") + public Integer OutConsumelogsComputer(Integer conid,Integer comid) { + try { + consumelogsService.OutConsumelogs(new Date(), conid); + computersService.editComputerStatus("0", comid); + return 1; + } catch (Exception e) { + return 0; + } + } + + /** + * 离开当前图书,并将当前日志设置离开时间 + */ + @PutMapping("/OutBook") + public Integer OutConsumelogsBook(Integer conid,Integer bid) { + try { + consumelogsService.OutConsumelogs(new Date(), conid); + booksService.editBookStatus("0", bid); + return 1; + } catch (Exception e) { + return 0; + } + } + + + /** + * 离开当前资源室 + */ + @PutMapping("/Out") + public Integer OutConsumelogs(String cardno,Integer rid) { + Consumelogs consumelog = consumelogsService.findByInTime(cardno, rid); + consumelogsService.OutConsumelogs(new Date(), consumelog.getConid()); + StringBuffer sb = new StringBuffer(cardno); + String b = sb.substring(0,1); + Integer x = 0; + if(b.equals("s")) { + Students student = studentsService.findByCardno(cardno); + x = studentsService.editStudentStatus(0, student.getSid()); + } + if(b.equals("t")) { + Teachers teacher = teachersService.findByCardno(cardno); + x = teachersService.editTeacherStatus(0,teacher.getTid()); + } + return x; + } +} diff --git a/src/main/java/com/syq/controller/ResourcesRoomController.java b/src/main/java/com/syq/controller/ResourcesRoomController.java index c6c38fe..5974082 100644 --- a/src/main/java/com/syq/controller/ResourcesRoomController.java +++ b/src/main/java/com/syq/controller/ResourcesRoomController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController; import com.syq.entity.ResourcesRoom; import com.syq.service.ResourcesRoomService; +import com.syq.util.Result; @RestController @RequestMapping("resources") @@ -52,8 +53,15 @@ public class ResourcesRoomController { * @return 添加后的实体信息 */ @PostMapping - public ResourcesRoom insertRoom(ResourcesRoom res) { - return resourcesRoomService.addOrUpdateRoom(res); + public Result insertRoom(ResourcesRoom res) { + List findByDiff = resourcesRoomService.findByDiff(res.getDiff()); + if(findByDiff.size()==10) { + return new Result(1, "不同资源室最多可添加十个"); + }else { + resourcesRoomService.addOrUpdateRoom(res); + return new Result(0, "添加成功"); + } + } /** diff --git a/src/main/java/com/syq/controller/StudentsController.java b/src/main/java/com/syq/controller/StudentsController.java index e8a3df4..941bd5c 100644 --- a/src/main/java/com/syq/controller/StudentsController.java +++ b/src/main/java/com/syq/controller/StudentsController.java @@ -19,6 +19,7 @@ import com.syq.entity.Students; import com.syq.entity.Systeminfo; import com.syq.entity.Teachers; import com.syq.service.StudentsService; +import com.syq.util.Result; import com.syq.util.ResultInfoUtil; @RequestMapping("students") @@ -28,6 +29,36 @@ public class StudentsController { @Autowired // 注入service层数据 private StudentsService studentsService; + /** + * 根据学生id修改学生状态 + */ + @PutMapping("/status") + public Integer editStudentStatus(Integer status, Integer sid) { + Integer x = studentsService.editStudentStatus(status, sid); + System.out.println("x:"+x); + return x; + } + + /** + * 根据学生卡号查询学生信息,用于前台刷卡后获取信息 + * @param cardno + * @return + */ + @GetMapping("/ByCardno") + public Students StudentByCardno(String cardno) { + Students students = studentsService.findByCardno(cardno); + if(students!=null) { + return students; + } + return null; + } + + /** + * 根据学生身份证号和卡号来查询学生,用于表单即时验证 + * @param cardno + * @param idnumber + * @return + */ @GetMapping("/unique") public ResultInfoUtil unique(String cardno,String idnumber) { Students stu = studentsService.findByCardno(cardno); diff --git a/src/main/java/com/syq/controller/TeachersController.java b/src/main/java/com/syq/controller/TeachersController.java index a54abf5..501825a 100644 --- a/src/main/java/com/syq/controller/TeachersController.java +++ b/src/main/java/com/syq/controller/TeachersController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController; import com.syq.entity.Computers; import com.syq.entity.Sections; +import com.syq.entity.Students; import com.syq.entity.Teachers; import com.syq.service.TeachersService; import com.syq.util.ResultInfoUtil; @@ -27,7 +28,40 @@ public class TeachersController { @Autowired private TeachersService teachersService; + + /** + * 根据老师id修改老师状态 + */ + @PutMapping("/status") + public Integer editStudentStatus(Integer status, Integer tid) { + Integer x = teachersService.editTeacherStatus(status, tid); + System.out.println("x:"+x); + return x; + } + /** + * 根据老师卡号查询老师信息,用于前台刷卡后获取信息 + * @param cardno + * @return + */ + @GetMapping("/ByCardno") + public Teachers StudentByCardno(String cardno) { + System.out.println(cardno); + Teachers teachers = teachersService.findByCardno(cardno); + if(teachers!=null) { + return teachers; + }else { + return null; + } + + } + + /** + * 根据老师卡号和身份证号查询,用于做表单即时验证 + * @param cardNo + * @param idnumber + * @return + */ @GetMapping("/unique") public ResultInfoUtil unique(String cardNo,String idnumber) { Teachers tec = teachersService.findByCardno(cardNo); diff --git a/src/main/java/com/syq/entity/Books.java b/src/main/java/com/syq/entity/Books.java index 04ae420..840baec 100644 --- a/src/main/java/com/syq/entity/Books.java +++ b/src/main/java/com/syq/entity/Books.java @@ -27,8 +27,10 @@ public class Books { private String author; //作者 private String press; //出版社 private String pressTime; //出版时间 - private String price; //价格 + private String number; //数量(一开始写了价格在做借书功能时改为数量) private String remark; //备注 + private String status;//状态,0:正常,1:报修,2:报废 + private String borrow;//借书状态 @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "btid") diff --git a/src/main/java/com/syq/entity/Computers.java b/src/main/java/com/syq/entity/Computers.java index 0fff358..79abd3b 100644 --- a/src/main/java/com/syq/entity/Computers.java +++ b/src/main/java/com/syq/entity/Computers.java @@ -26,7 +26,7 @@ public class Computers { private Integer comid;//电脑编号 private String comname;//电脑名称 private String ip;//IP地址 - private Integer status;//状态,0:正常,1:报修,2:报废 + private String status;//状态,0:正常,1:报修,2:报废 private String remark;//备注 @JoinColumn(name = "rid") diff --git a/src/main/java/com/syq/entity/Consumelogs.java b/src/main/java/com/syq/entity/Consumelogs.java index ddae93b..982ae8f 100644 --- a/src/main/java/com/syq/entity/Consumelogs.java +++ b/src/main/java/com/syq/entity/Consumelogs.java @@ -29,30 +29,25 @@ public class Consumelogs { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer conid;//消费编号 - private String cardNo;//卡号 + private String cardno;//卡号 @DateTimeFormat(pattern = "yyyy-MM-dd") - private Date inTime;//进入时间 + private Date intime;//进入时间 @DateTimeFormat(pattern = "yyyy-MM-dd") - private Date outTime;//离开时间 + private Date outtime;//离开时间 private Integer status;//用于统计 - @JoinColumn(name = "bid") - @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER) + @ManyToOne(fetch = FetchType.EAGER) private Books books;//图书 - @JoinColumn(name = "btid") - @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER) - private BookType bookType; - @JoinColumn(name = "comid") - @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER) + @ManyToOne(fetch = FetchType.EAGER) private Computers computers; @JoinColumn(name = "rid") - @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER) + @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER) private ResourcesRoom resourcesRoom; } diff --git a/src/main/java/com/syq/repository/BooksRepository.java b/src/main/java/com/syq/repository/BooksRepository.java index efa9388..17cda88 100644 --- a/src/main/java/com/syq/repository/BooksRepository.java +++ b/src/main/java/com/syq/repository/BooksRepository.java @@ -1,10 +1,55 @@ package com.syq.repository; +import javax.transaction.Transactional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import com.syq.entity.Books; public interface BooksRepository extends JpaRepository, JpaSpecificationExecutor { + /** + * 当有人阅读图书时,将使用者卡号添加进图书状态 + */ + @Transactional + @Modifying + @Query(value = "update books set status = ?1 where bid = ?2 ",nativeQuery = true) + Integer editBookStatus(String cardno,Integer bid); + + /** + * 当有人借阅图书时,将借阅者卡号添加至图书借阅状态,并对该图书数量减1 + */ + @Transactional + @Modifying + @Query(value = "update books set borrow = ?1,number=number-1 where bid = ?2 ",nativeQuery = true) + Integer editBorrowReduceNumber(String borrow,Integer bid); + + /** + * 当有人还书时,将借阅者卡号从图书借阅状态中移除,并对该图书数量加1 + */ + @Transactional + @Modifying + @Query(value = "update books set borrow = ?1,number=number+1 where bid = ?2 ",nativeQuery = true) + Integer editBorrowPlusNumber(String borrow,Integer bid); + + /** + * 根据借阅卡号模糊查询,根据图书id精确查询 + * @param borrow + * @param bid + * @return + */ + @Query(value = "select * from books where borrow like %?1% and bid = ?2 ",nativeQuery = true) + Books likeBookByBorrow(String borrow,Integer bid); + +// /** +// * 根据idcha'x +// * @param borrow +// * @param bid +// * @return +// */ +// @Query(value = "select borrow from books where bid = ?1 ",nativeQuery = true) +// String findBorrow(Integer bid); } diff --git a/src/main/java/com/syq/repository/ComputersRepository.java b/src/main/java/com/syq/repository/ComputersRepository.java index 75533c9..7535558 100644 --- a/src/main/java/com/syq/repository/ComputersRepository.java +++ b/src/main/java/com/syq/repository/ComputersRepository.java @@ -1,7 +1,10 @@ package com.syq.repository; +import javax.transaction.Transactional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import com.syq.entity.Computers; @@ -11,4 +14,12 @@ public interface ComputersRepository extends JpaRepository,J @Query(value = "select * from computers c where c.ip = ?1 ",nativeQuery = true) Computers findByIp(String ip); + + /** + * 当有人使用计算机时,将使用者卡号添加进计算机状态 + */ + @Transactional + @Modifying + @Query(value = "update computers set status = ?1 where comid = ?2 ",nativeQuery = true) + Integer editComputerStatus(String cardno,Integer comid); } diff --git a/src/main/java/com/syq/repository/ConsumelogsRepositorty.java b/src/main/java/com/syq/repository/ConsumelogsRepositorty.java new file mode 100644 index 0000000..416f276 --- /dev/null +++ b/src/main/java/com/syq/repository/ConsumelogsRepositorty.java @@ -0,0 +1,80 @@ +package com.syq.repository; + +import java.util.Date; +import java.util.List; + +import javax.transaction.Transactional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import com.syq.entity.Consumelogs; + +public interface ConsumelogsRepositorty extends JpaRepository,JpaSpecificationExecutor{ + + /** + * 在有人选择资源室后进行添加日志 + * @param status + * @param sid + * @return + */ + @Transactional + @Modifying + @Query(value = "insert into consumelogs(cardno,intime,status,rid,comid,bid) " + + "values(:#{#log.cardno},:#{#log.intime},:#{#log.status},:#{#rid},:#{#comid},:#{#bid})",nativeQuery = true) + Integer insertConsumelog(Consumelogs log,Integer rid,Integer comid,Integer bid); + + /** + * 根据卡号查询该卡号的所有访问量,若有未结束的任务则提示该用户先结束 + * @param cardno + * @return + */ + @Query(value = "select * from consumelogs where cardno = ?1",nativeQuery = true) + List findConsumelogByCardno(String cardno); + + /** + * 根据当前打卡卡号和选择资源室id来查询最新创建的一条数据 + * @param cardno + * @param rid + * @return + */ + @Query(value = "select * from consumelogs where cardno = ?1 and rid = ?2 ORDER BY intime desc limit 1",nativeQuery = true) + Consumelogs findByInTime(String cardno,Integer rid); + + /** + * 如果当前日志并没有明确的计算机被使用则添加计算机 + */ + @Transactional + @Modifying + @Query(value = "update consumelogs set comid = ?1 where conid = ?2 ",nativeQuery = true) + Integer insertComputer(Integer comid,Integer conid); + + /** + * 如果当前日志并没有明确的图书被使用则添加图书 + */ + @Transactional + @Modifying + @Query(value = "update consumelogs set bid = ?1 where conid = ?2 ",nativeQuery = true) + Integer insertBook(Integer bid,Integer conid); + + /** + * 设置日志的离开时间 + */ + @Transactional + @Modifying + @Query(value = "update consumelogs set outtime = ?1 where conid = ?2 ",nativeQuery = true) + Integer OutConsumelogs(Date outtime,Integer conid); + + /** + * 查询每个资源室当天的点击浏览次数 + */ + @Query(value = "select sum(status) from consumelogs where intime >=?1 and outtime < ?2 GROUP BY rid",nativeQuery = true) + List findSumNumber(String intime,String outtime); + + + @Query(value = "select rid from consumelogs where intime >=?1 and outtime < ?2 GROUP BY rid",nativeQuery = true) + List findRoomId(String intime,String outtime); +} + diff --git a/src/main/java/com/syq/repository/StatisticsRepository.java b/src/main/java/com/syq/repository/StatisticsRepository.java index b340ee0..8d28f08 100644 --- a/src/main/java/com/syq/repository/StatisticsRepository.java +++ b/src/main/java/com/syq/repository/StatisticsRepository.java @@ -40,4 +40,5 @@ public interface StatisticsRepository extends JpaRepository */ @Query(value = "select * from statistics where rid in (:rids) and yearx = :yearx and monthx = :monthx ",nativeQuery = true) List findDayByMonthx(List rids,String yearx,String monthx); + } diff --git a/src/main/java/com/syq/repository/StudentRepository.java b/src/main/java/com/syq/repository/StudentRepository.java index 8fe1587..2ed39de 100644 --- a/src/main/java/com/syq/repository/StudentRepository.java +++ b/src/main/java/com/syq/repository/StudentRepository.java @@ -2,8 +2,11 @@ package com.syq.repository; import java.util.List; +import javax.transaction.Transactional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import com.syq.entity.Students; @@ -11,6 +14,11 @@ import com.syq.entity.Students; public interface StudentRepository extends JpaRepository,JpaSpecificationExecutor{ + /** + * 根据系别id查询 + * @param sysid + * @return + */ @Query(value = "select * from students s where s.sysid = ?1 ",nativeQuery = true) List findStudentsBySysid(Integer sysid); /** @@ -28,4 +36,15 @@ public interface StudentRepository extends JpaRepository,JpaS */ @Query(value = "select * from students s where s.idnumber = ?1 ",nativeQuery = true) Students findByIdnumber(String idnumber); + + /** + * 根据学生id更改学生状态 + * @param status + * @param sid + * @return + */ + @Transactional + @Modifying + @Query(value = "update students set status = ?1 where sid = ?2",nativeQuery = true) + Integer editStudentStatus(Integer status,Integer sid); } diff --git a/src/main/java/com/syq/repository/TeachersRepository.java b/src/main/java/com/syq/repository/TeachersRepository.java index 6cbf445..5c8c5da 100644 --- a/src/main/java/com/syq/repository/TeachersRepository.java +++ b/src/main/java/com/syq/repository/TeachersRepository.java @@ -2,8 +2,11 @@ package com.syq.repository; import java.util.List; +import javax.transaction.Transactional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import com.syq.entity.Students; @@ -30,4 +33,15 @@ public interface TeachersRepository extends JpaRepository, Jp */ @Query(value = "select * from teachers t where t.idnumber = ?1 ",nativeQuery = true) Teachers findByIdnumber(String idnumber); + + /** + * 根据老师id更改老师状态 + * @param status + * @param sid + * @return + */ + @Transactional + @Modifying + @Query(value = "update teachers set status = ?1 where tid = ?2",nativeQuery = true) + Integer editTeacherStatus(Integer status,Integer tid); } \ No newline at end of file diff --git a/src/main/java/com/syq/service/BooksService.java b/src/main/java/com/syq/service/BooksService.java index 0175aa6..a532f3e 100644 --- a/src/main/java/com/syq/service/BooksService.java +++ b/src/main/java/com/syq/service/BooksService.java @@ -1,6 +1,10 @@ package com.syq.service; +import javax.transaction.Transactional; + import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import com.syq.entity.Books; import com.syq.util.FenyeUtil; @@ -28,4 +32,30 @@ public interface BooksService { * @param bid */ Integer deleteBooksById(Books book); + + /** + * 当有人使用图书时,将使用者卡号添加进图书状态 + */ + @Transactional + @Modifying + @Query(value = "update books set status = ?1 where bid = ?2 ",nativeQuery = true) + Integer editBookStatus(String cardno,Integer bid); + + /** + * 当有人借阅图书时,将借阅者卡号添加至图书借阅状态,并对该图书数量减1 + */ + Integer editBorrowReduceNumber(String borrow,Integer bid); + + /** + * 当有人还书时,将借阅者卡号从图书借阅状态中移除,并对该图书数量加1 + */ + Integer editBorrowPlusNumber(String borrow,Integer bid); + + /** + * 根据借阅卡号模糊查询,根据图书id精确查询 + * @param borrow + * @param bid + * @return + */ + Books likeBookByBorrow(String borrow,Integer bid); } diff --git a/src/main/java/com/syq/service/ComputersService.java b/src/main/java/com/syq/service/ComputersService.java index 8861427..6839040 100644 --- a/src/main/java/com/syq/service/ComputersService.java +++ b/src/main/java/com/syq/service/ComputersService.java @@ -1,6 +1,10 @@ package com.syq.service; +import javax.transaction.Transactional; + import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import com.syq.entity.Computers; import com.syq.util.FenyeUtil; @@ -37,4 +41,9 @@ public interface ComputersService { * @return */ Computers findByIp(String ip); + + /** + * 当有人使用计算机时,将使用者卡号添加进计算机状态 + */ + Integer editComputerStatus(String cardno,Integer comid); } diff --git a/src/main/java/com/syq/service/ConsumelogsService.java b/src/main/java/com/syq/service/ConsumelogsService.java new file mode 100644 index 0000000..392104d --- /dev/null +++ b/src/main/java/com/syq/service/ConsumelogsService.java @@ -0,0 +1,54 @@ +package com.syq.service; + +import java.util.Date; +import java.util.List; + +import javax.transaction.Transactional; + +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import com.syq.entity.Consumelogs; + +public interface ConsumelogsService { + + /** + * 在有人选择资源室后进行添加日志 + * @param log + * @return + */ + Integer insertConsumelog(Consumelogs log,Integer rid,Integer comid,Integer bid); + + /** + * 根据卡号查询该卡号的所有访问量,若有未结束的任务则提示该用户先结束 + * @param cardno + * @return + */ + List findConsumelogByCardno(String cardno); + + /** + * 查询最新一条 + * @param cardno + * @param rid + * @return + */ + Consumelogs findByInTime(String cardno,Integer rid); + + /** + * 当目前日志没有具体计算机时,添加计算机 + * @param comid + * @param conid + * @return + */ + Integer insertComputer(Integer comid,Integer conid); + + /** + * 如果当前日志并没有明确的图书被使用则添加图书 + */ + Integer insertBook(Integer bid,Integer conid); + + /** + * 设置日志离开时间 + */ + Integer OutConsumelogs(Date outtime,Integer conid); +} diff --git a/src/main/java/com/syq/service/StudentsService.java b/src/main/java/com/syq/service/StudentsService.java index 2fa0441..6176f54 100644 --- a/src/main/java/com/syq/service/StudentsService.java +++ b/src/main/java/com/syq/service/StudentsService.java @@ -12,6 +12,11 @@ import com.syq.util.FenyeUtil; public interface StudentsService { + /** + * 根据学生id更改学生状态 + */ + Integer editStudentStatus(Integer status,Integer sid); + /** * 导出excel */ diff --git a/src/main/java/com/syq/service/TeachersService.java b/src/main/java/com/syq/service/TeachersService.java index e87296f..6996303 100644 --- a/src/main/java/com/syq/service/TeachersService.java +++ b/src/main/java/com/syq/service/TeachersService.java @@ -9,6 +9,11 @@ import com.syq.util.FenyeUtil; public interface TeachersService { + /** + * 根据老师id修改老师状态 + */ + Integer editTeacherStatus(Integer status,Integer tid); + /** * 根据卡号查询学生 * 创建人:孙玉全 diff --git a/src/main/java/com/syq/service/impl/BooksServiceImpl.java b/src/main/java/com/syq/service/impl/BooksServiceImpl.java index 2aa92dd..a3e4761 100644 --- a/src/main/java/com/syq/service/impl/BooksServiceImpl.java +++ b/src/main/java/com/syq/service/impl/BooksServiceImpl.java @@ -95,5 +95,30 @@ public class BooksServiceImpl implements BooksService { } } + @Override + public Integer editBookStatus(String cardno, Integer bid) { + // TODO Auto-generated method stub + return booksRepository.editBookStatus(cardno, bid); + } + + + @Override + public Books likeBookByBorrow(String borrow, Integer bid) { + // TODO Auto-generated method stub + return booksRepository.likeBookByBorrow(borrow, bid); + } + + @Override + public Integer editBorrowReduceNumber(String borrow, Integer bid) { + // TODO Auto-generated method stub + return booksRepository.editBorrowReduceNumber(borrow, bid); + } + + @Override + public Integer editBorrowPlusNumber(String borrow, Integer bid) { + // TODO Auto-generated method stub + return booksRepository.editBorrowPlusNumber(borrow, bid); + } + } diff --git a/src/main/java/com/syq/service/impl/ComputersServiceImpl.java b/src/main/java/com/syq/service/impl/ComputersServiceImpl.java index 5aa9150..35681ee 100644 --- a/src/main/java/com/syq/service/impl/ComputersServiceImpl.java +++ b/src/main/java/com/syq/service/impl/ComputersServiceImpl.java @@ -37,6 +37,9 @@ public class ComputersServiceImpl implements ComputersService { return computersRepository.saveAndFlush(com); } + /** + * 根据ip地址查询电脑,用于表单及时验证 + */ @Override public Computers findByIp(String ip) { // TODO Auto-generated method stub @@ -98,5 +101,14 @@ public class ComputersServiceImpl implements ComputersService { }; } + /** + * 当有人使用计算机时,将使用者卡号添加进计算机状态 + */ + @Override + public Integer editComputerStatus(String cardno, Integer comid) { + // TODO Auto-generated method stub + return computersRepository.editComputerStatus(cardno, comid); + } + } diff --git a/src/main/java/com/syq/service/impl/ConsumelogsServiceImpl.java b/src/main/java/com/syq/service/impl/ConsumelogsServiceImpl.java new file mode 100644 index 0000000..cf67d6b --- /dev/null +++ b/src/main/java/com/syq/service/impl/ConsumelogsServiceImpl.java @@ -0,0 +1,60 @@ +package com.syq.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.syq.entity.Consumelogs; +import com.syq.repository.ConsumelogsRepositorty; +import com.syq.service.ConsumelogsService; + +@Service +public class ConsumelogsServiceImpl implements ConsumelogsService{ + + @Autowired + private ConsumelogsRepositorty consumelogsRepositorty; + + @Override + public Integer insertConsumelog(Consumelogs log,Integer rid,Integer comid,Integer bid) { + // TODO Auto-generated method stub + return consumelogsRepositorty.insertConsumelog(log,rid,comid,bid); + } + + /** + * 根据卡号查询该卡号的所有访问量,若有未结束的任务则提示该用户先结束 + * @param cardno + * @return + */ + @Override + public List findConsumelogByCardno(String cardno) { + // TODO Auto-generated method stub + return consumelogsRepositorty.findConsumelogByCardno(cardno); + } + + @Override + public Consumelogs findByInTime(String cardno, Integer rid) { + // TODO Auto-generated method stub + return consumelogsRepositorty.findByInTime(cardno, rid); + } + + @Override + public Integer insertComputer(Integer comid, Integer conid) { + // TODO Auto-generated method stub + return consumelogsRepositorty.insertComputer(comid, conid); + } + + @Override + public Integer OutConsumelogs(Date outtime, Integer conid) { + // TODO Auto-generated method stub + return consumelogsRepositorty.OutConsumelogs(outtime, conid); + } + + @Override + public Integer insertBook(Integer bid, Integer conid) { + // TODO Auto-generated method stub + return consumelogsRepositorty.insertBook(bid, conid); + } + +} diff --git a/src/main/java/com/syq/service/impl/StudentsServiceImpl.java b/src/main/java/com/syq/service/impl/StudentsServiceImpl.java index 02b1c0b..d675399 100644 --- a/src/main/java/com/syq/service/impl/StudentsServiceImpl.java +++ b/src/main/java/com/syq/service/impl/StudentsServiceImpl.java @@ -170,5 +170,14 @@ public class StudentsServiceImpl implements StudentsService{ return studentRepository.findStudentsBySysid(sysid); } + /** + * 根据学生id修改学生的状态 + */ + @Override + public Integer editStudentStatus(Integer status, Integer sid) { + // TODO Auto-generated method stub + return studentRepository.editStudentStatus(status, sid); + } + } diff --git a/src/main/java/com/syq/service/impl/TeachersServiceImpl.java b/src/main/java/com/syq/service/impl/TeachersServiceImpl.java index 2bf02ba..b131b89 100644 --- a/src/main/java/com/syq/service/impl/TeachersServiceImpl.java +++ b/src/main/java/com/syq/service/impl/TeachersServiceImpl.java @@ -114,5 +114,11 @@ public class TeachersServiceImpl implements TeachersService { return teachersRepository.findByIdnumber(idnumber); } + @Override + public Integer editTeacherStatus(Integer status, Integer tid) { + // TODO Auto-generated method stub + return teachersRepository.editTeacherStatus(status, tid); + } + } diff --git a/src/main/java/com/syq/task/MyTask.java b/src/main/java/com/syq/task/MyTask.java new file mode 100644 index 0000000..c367f73 --- /dev/null +++ b/src/main/java/com/syq/task/MyTask.java @@ -0,0 +1,69 @@ +package com.syq.task; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import com.syq.entity.ResourcesRoom; +import com.syq.entity.Statistics; +import com.syq.repository.ConsumelogsRepositorty; +import com.syq.repository.StatisticsRepository; + + +@Component +@EnableScheduling//启动定时任务 +public class MyTask { + + @Autowired + private ConsumelogsRepositorty consumelogsRepositorty;//注入日志 + + @Autowired + private StatisticsRepository statisticsRepository; + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date date = new Date();//设置当前时间 + Calendar cal = Calendar.getInstance(); +// @Scheduled(fixedRate = 1000*5) + @Scheduled(cron = "0 0 8 * * ?")//每天早上的八点执行 + public void task1() { + cal.setTime(date); + Date time = cal.getTime(); + String outtime = sdf.format(time);//获取当天时间 + + cal.add(Calendar.DAY_OF_WEEK, -1);//当前时间减去一天 + Date time2 = cal.getTime(); + String intime = sdf.format(time2);//获取前一天时间 + + String[] result = intime.split("-"); + String yearx = result[0]+"年"; + String monthx = result[1]+"月"; + String dayx = result[2]+"日"; + System.out.println(yearx); + System.out.println(monthx); + System.out.println(dayx); + + List findSumNumber = consumelogsRepositorty.findSumNumber(intime, outtime); + List findRoomId = consumelogsRepositorty.findRoomId(intime, outtime); + for(int i =0;i + + + + + 刷卡模式 + + + + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+ + + + diff --git a/src/main/resources/static/book-fonts.html b/src/main/resources/static/book-fonts.html new file mode 100644 index 0000000..ed65a23 --- /dev/null +++ b/src/main/resources/static/book-fonts.html @@ -0,0 +1,262 @@ + + + + + + + + + + + +
+ +
+
+ + + + + \ No newline at end of file diff --git a/src/main/resources/static/book.html b/src/main/resources/static/book.html new file mode 100644 index 0000000..94cff8e --- /dev/null +++ b/src/main/resources/static/book.html @@ -0,0 +1,455 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/bookType.html b/src/main/resources/static/bookType.html new file mode 100644 index 0000000..1df30e1 --- /dev/null +++ b/src/main/resources/static/bookType.html @@ -0,0 +1,274 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/computer-fonts.html b/src/main/resources/static/computer-fonts.html new file mode 100644 index 0000000..007a190 --- /dev/null +++ b/src/main/resources/static/computer-fonts.html @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+ +
+
+ + + + + + + diff --git a/src/main/resources/static/computer.html b/src/main/resources/static/computer.html new file mode 100644 index 0000000..5c498f4 --- /dev/null +++ b/src/main/resources/static/computer.html @@ -0,0 +1,416 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + + + diff --git a/src/main/resources/static/css/font.css b/src/main/resources/static/css/font.css new file mode 100644 index 0000000..b83e5b4 --- /dev/null +++ b/src/main/resources/static/css/font.css @@ -0,0 +1,16 @@ +@font-face { + font-family: 'iconfont'; + src: url('../fonts/iconfont.eot'); + src: url('../fonts/iconfont.eot?#iefix') format('embedded-opentype'), + url('../fonts/iconfont.woff') format('woff'), + url('../fonts/iconfont.ttf') format('truetype'), + url('../fonts/iconfont.svg#iconfont') format('svg'); +} +.iconfont{ + font-family:"iconfont" !important; + font-size:16px;font-style:normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} + diff --git a/src/main/resources/static/css/login.css b/src/main/resources/static/css/login.css new file mode 100644 index 0000000..10b8f33 --- /dev/null +++ b/src/main/resources/static/css/login.css @@ -0,0 +1,105 @@ +/* +* @Author: xuebingsi +* @Date: 2019-04-01 13:37:17 +* @Last Modified by: zhibinm +* @Last Modified time: 2019-04-01 13:37:19 +*/ +.login-bg{ + /*background: #eeeeee url() 0 0 no-repeat;*/ + background:url(../images/bg.png) no-repeat center; + background-size: cover; + overflow: hidden; +} +.login{ + margin: 120px auto 0 auto; + min-height: 420px; + max-width: 420px; + padding: 40px; + background-color: #ffffff; + margin-left: auto; + margin-right: auto; + border-radius: 4px; + /* overflow-x: hidden; */ + box-sizing: border-box; +} +.login a.logo{ + display: block; + height: 58px; + width: 167px; + margin: 0 auto 30px auto; + background-size: 167px 42px; +} +.login .message { + margin: 10px 0 0 -58px; + padding: 18px 10px 18px 60px; + background: #189F92; + position: relative; + color: #fff; + font-size: 16px; +} +.login #darkbannerwrap { + background: url(../images/aiwrap.png); + width: 18px; + height: 10px; + margin: 0 0 20px -58px; + position: relative; +} + +.login input[type=text], +.login input[type=file], +.login input[type=password], +.login input[type=email], select { + border: 1px solid #DCDEE0; + vertical-align: middle; + border-radius: 3px; + height: 50px; + padding: 0px 16px; + font-size: 14px; + color: #555555; + outline:none; + width:100%; + box-sizing: border-box; +} +.login input[type=text]:focus, +.login input[type=file]:focus, +.login input[type=password]:focus, +.login input[type=email]:focus, select:focus { + border: 1px solid #27A9E3; +} +.login input[type=submit], +.login input[type=button]{ + display: inline-block; + vertical-align: middle; + padding: 12px 24px; + margin: 0px; + font-size: 18px; + line-height: 24px; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + color: #ffffff; + background-color: #189F92; + border-radius: 3px; + border: none; + -webkit-appearance: none; + outline:none; + width:100%; +} +.login hr { + background: #fff url() 0 0 no-repeat; +} +.login hr.hr15 { + height: 15px; + border: none; + margin: 0px; + padding: 0px; + width: 100%; +} +.login hr.hr20 { + height: 20px; + border: none; + margin: 0px; + padding: 0px; + width: 100%; +} \ No newline at end of file diff --git a/src/main/resources/static/css/theme1.css b/src/main/resources/static/css/theme1.css new file mode 100644 index 0000000..79b2dc8 --- /dev/null +++ b/src/main/resources/static/css/theme1.css @@ -0,0 +1,21 @@ +body{ + background:#F2F1F2; +} +.container{ + background:#1A1B20; +} +.left-nav{ + background:#1A1B20; +} + +.left-nav a{ + color:rgba(255,255,255,.7); +} +..left-nav a.active{ + background: #009688 !important; + color: #fff; +} +.left-nav a:hover{ + background: #009688 !important; + color: #fff; +} \ No newline at end of file diff --git a/src/main/resources/static/css/theme2.css b/src/main/resources/static/css/theme2.css new file mode 100644 index 0000000..04e9171 --- /dev/null +++ b/src/main/resources/static/css/theme2.css @@ -0,0 +1,21 @@ +body{ + background:#EEF5F9; +} +.container{ + background:#323640; +} +.left-nav{ + background:#fff; +} + +.left-nav a{ + color:#686a76; +} +.left-nav a.active{ + background: #786AED !important; + color: #fff; +} +.left-nav a:hover{ + background: #786AED !important; + color: #fff; +} diff --git a/src/main/resources/static/css/theme3.css b/src/main/resources/static/css/theme3.css new file mode 100644 index 0000000..d5919c5 --- /dev/null +++ b/src/main/resources/static/css/theme3.css @@ -0,0 +1,22 @@ +body{ + background:#E8E8E8; +} +.container{ + background:#F34743; +} + +.left-nav{ + background:#F4F4F4; +} + +.left-nav a{ + color:#686a76; +} +.left-nav a.active{ + background: #FEFEFE !important; + color: #F34743; +} +.left-nav a:hover{ + background: #FEFEFE !important; + color: #F34743; +} \ No newline at end of file diff --git a/src/main/resources/static/css/theme4.css b/src/main/resources/static/css/theme4.css new file mode 100644 index 0000000..0a0ff61 --- /dev/null +++ b/src/main/resources/static/css/theme4.css @@ -0,0 +1,21 @@ +body{ + background:#E4E4E4; +} +.container{ + background:#019587; +} +.left-nav{ + background:#263035; +} + +.left-nav a{ + color:#fff; +} +.left-nav a.active{ + background: #212525 !important; + color: #fff !important; +} +.left-nav a:hover{ + background: #212525 !important; + color: #fff !important; +} \ No newline at end of file diff --git a/src/main/resources/static/css/theme5.css b/src/main/resources/static/css/theme5.css new file mode 100644 index 0000000..92c9a06 --- /dev/null +++ b/src/main/resources/static/css/theme5.css @@ -0,0 +1,27 @@ +body{ + background:#EEF5F9 !important; +} +.container{ + background:linear-gradient(to left, #7b4397, #2196f3); +} + +.left-nav{ + background:#fff !important; +} + +.left-nav a{ + color:#686a76 !important; +} +.left-nav a.active{ + background: linear-gradient(to left, #7c8ce4, #2196f3) !important; + color: #fff !important; + border-color: #7b4397 !important; +} +.left-nav a:hover{ + background: linear-gradient(to left, #7c8ce4, #2196f3) !important; + color: #fff !important; + border-color: #7b4397 !important; +} +.container .logo a{ + background: rgba(0,0,0,0) !important; +} \ No newline at end of file diff --git a/src/main/resources/static/css/xadmin.css b/src/main/resources/static/css/xadmin.css new file mode 100644 index 0000000..ab7030a --- /dev/null +++ b/src/main/resources/static/css/xadmin.css @@ -0,0 +1,534 @@ +@charset "utf-8"; +@import url(../lib/layui/css/layui.css); +*{ + margin: 0px; + padding: 0px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +a{ + text-decoration: none; +} +html{ + width: 100%; + height: 100%; + overflow-x:hidden; + overflow-y:auto; +} +body{ + width: 100%; + min-height: 100%; + background: #f1f1f1; + /*background: #fff;*/ +} +.x-red{ + color: red; +} + +.layui-form-switch{ + margin-top: 0px; +} +.layui-input:focus, .layui-textarea:focus { + border-color: #189f92!important; +} + +.layui-fluid{ + padding:15px; +} +.x-nav{ + padding: 0 20px; + position: relative; + z-index: 99; + border-bottom: 1px solid #e5e5e5; + line-height: 39px; + height: 39px; + overflow: hidden; + background: #fff; +} +.page{ + text-align: center; + +} +.page a{ + display: inline-block; + background: #fff; + color: #888; + padding: 5px; + min-width: 15px; + border: 1px solid #E2E2E2; + +} +.page span{ + display: inline-block; + padding: 5px; + min-width: 15px; + border: 1px solid #E2E2E2; +} +.page span.current{ + display: inline-block; + background: #009688; + color: #fff; + padding: 5px; + min-width: 15px; + border: 1px solid #009688; +} +.page .pagination li{ + display: inline-block; + margin-right: 5px; + text-align: center; +} +.page .pagination li.active span{ + background: #009688; + color: #fff; + border: 1px solid #009688; + +} + +/*登录样式*/ +/*头部*/ +.container{ + width: 100%; + height: 45px; + background-color: #222; +} +.container a,.layui-nav .layui-nav-item a{ + color: #fff; +} +.container .logo a{ + background-color: rgba(0,0,0,0); +} +.container .logo a{ + float: left; + font-size: 18px; + padding-left: 20px; + line-height: 45px; + width: 200px; +} +.container .right{ + background-color:rgba(0,0,0,0); + float: right; + +} +.container .left_open{ + height: 45px; + float: left; + margin-left: 10px; +} +.container .left_open i{ + display: block; + background: rgba(255,255,255,0.1); + width: 32px; + height: 32px; + line-height: 32px; + border-radius: 3px; + text-align: center; + margin-top: 7px; + cursor: pointer; +} +.container .left_open i:hover{ + background: rgba(255,255,255,0.3); +} + +.container .left{ + background-color:rgba(0,0,0,0); + float: left; + +} +.container .layui-nav-item{ + line-height: 45px; +} +.container .layui-nav-more{ + top: 20px; +} +.container .layui-nav-child{ + top: 50px; +} +.container .layui-nav-child i{ + margin-right: 10px; +} +.layui-nav .layui-nav-item a{ + cursor: pointer; +} +.layui-nav .layui-nav-child a{ + color: #333; + cursor: pointer; +} +.left-nav{ + position: absolute; + top: 45px; + bottom: 0px; + /*bottom: 42px;*/ + left: 0; + z-index: 2; + padding-top: 10px; + background-color: #EEEEEE; + width: 220px; + max-width: 220px; + overflow: auto; + overflow-x:hidden; + overflow: hidden; + + /*width: 0px;*/ +} +#side-nav{ + width: 220px; +} + +.left-nav #nav li:hover > a{ + /*color: blue;*/ +} +.left-nav #nav .current{ + background-color: rgba(0, 0, 0, 0.3); +} +.left-nav #nav li a{ + font-size: 14px; + padding: 10px 15px 10px 15px; + display: block; + cursor: pointer; + border-left: 4px solid transparent; + transition: all 0.3s; +} +.left-nav a:hover{ + background: #009688 !important; + color: #fff; + border-color: #04564e !important; +} +.left-nav a.active{ + background: #009688 !important; + color: #fff; + border-color: #04564e !important; +} +.left-nav #nav li a cite{ + font-size: 14px; +} + +.left-nav #nav li .sub-menu{ + display: none; +} +.left-nav #nav li .opened{ + display: block; +} +.left-nav #nav li .opened:hover{ + /*background: #fff ;*/ +} +.left-nav #nav li .opened .current{ + +} +.left-nav #nav li .sub-menu li:hover{ + /*color: blue;*/ + /*background: #fff ;*/ +} +.left-nav #nav li .sub-menu li a{ + padding: 12px 15px 12px 30px; + font-size: 14px; + cursor: pointer; +} +.left-nav #nav li .sub-menu li .sub-menu li a{ + padding-left: 45px; +} +/*.left-nav #nav li .sub-menu li a:hover{ + color: #148cf1; +}*/ +.left-nav #nav li .sub-menu li a i{ + font-size: 12px; +} +.left-nav #nav li a i{ + padding-right: 10px; + line-height: 14px; +} +.left-nav #nav li .nav_right{ + float: right; + font-size: 16px; +} +.x-slide_left { + width: 17px; + height: 61px; + background: url(../images/icon.png) 0 0 no-repeat; + position: absolute; + top: 200px; + left: 220px; + cursor: pointer; + z-index: 3; +} +.page-content{ + position: absolute; + top: 45px; + right: 0; + /*bottom: 42px;*/ + bottom: 0px; + left: 220px; + overflow: hidden; + z-index: 1; +} +.page-content-bg{ + position: absolute; + top: 45px; + right: 0; + /*bottom: 42px;*/ + bottom: 0px; + left: 220px; + background: rgba(0,0,0,0.5); + overflow: hidden; + z-index: 100; + display: none; +} + +.page-content .tab{ + height: 100%; + width: 100%; + /*background: #EFEEF0;*/ + margin: 0px; +} +.page-content .layui-tab-title{ + /*padding-top: 5px;*/ + height: 35px; + background: #EFEEF0 ; + position: relative; + z-index: 100; +} +.page-content .layui-tab-title li.home i{ + padding-right: 5px; +} +.page-content .layui-tab-title li.home .layui-tab-close{ + display: none; +} +.page-content .layui-tab-title li{ + line-height: 35px; +} +.page-content .layui-tab-title .layui-this:after{ + height: 36px; +} +.page-content .layui-tab-title li .layui-tab-close{ + border-radius: 50%; +} +.page-content .layui-tab-title .layui-this{ + background: #fff ; +} +.page-content .layui-tab-bar{ + height:34px; + line-height: 35px; +} +.page-content .layui-tab-content{ + position: absolute; + top: 36px; + bottom: 0px; + width: 100%; + padding: 0px; + overflow: hidden; +} +.page-content .layui-tab-content .layui-tab-item{ + width: 100%; + height: 100%; + +} +.page-content .layui-tab-content .layui-tab-item iframe{ + width: 100%; + height: 100%; + +} +.x-admin-carousel,.layui-carousel,.x-admin-carousel>[carousel-item]>* { + background-color:#fff +} + +.x-admin-backlog .x-admin-backlog-body { + display:block; + padding:10px 15px; + background-color:#f8f8f8; + color:#999; + border-radius:2px; + transition:all .3s; + -webkit-transition:all .3s +} +.x-admin-backlog-body h3 { + padding-bottom:10px; + font-size:12px +} +.x-admin-backlog-body p cite { + font-style:normal; + font-size:30px; + font-weight:300; + color:#009688 +} +.x-admin-backlog-body:hover { + background-color:#CFCFCF; + color:#888 +} + +.layui-table td, .layui-table th{ + min-width: 80px; +} + +table th, table td { + word-break: break-all; +} + +/*404页面样式*/ +.fly-panel { + margin-bottom: 15px; + border-radius: 2px; + /*background-color: #fff;*/ + box-shadow: 0 1px 2px 0 rgba(0,0,0,.05); +} +.fly-none { + min-height: 600px; + text-align: center; + padding-top: 50px; + color: #999; +} +.fly-none .layui-icon { + line-height: 300px; + font-size: 300px; + color: #393D49; +} +.fly-none p { + margin-top: 50px; + padding: 0 15px; + font-size: 20px; + color: #999; + font-weight: 300; +} +#tab_right{ + display: none; + width: 80px; + position: absolute; + top: 35px; + left: 0px; +} +#tab_right dl{ + top: 0px; +} +#tab_show{ + position: absolute; + top: 36px; + bottom: 0px; + width: 100%; + background:rgb(255, 255, 255,0); + padding: 0px; + overflow: hidden; + display: none; +} + + +@media screen and (max-width: 768px){ + .fast-add{ + display: none; + } + .layui-nav .to-index{ + display: none; + } + .container .logo a{ + width: 140px; + } + .container .left_open { + /*float: right;*/ + } + .left-nav{ + width: 60px; + } + .left-nav #nav li a i{ + font-size: 18px; + } + .left-nav cite,.left-nav .nav_right{ + display: none; + } + .page-content{ + left: 60px; + } + .page-content .layui-tab-content .layui-tab-item{ + -webkit-overflow-scrolling: touch; + overflow-y: scroll; + } + .x-so input.layui-input{ + width: 100%; + margin: 10px; + } +} + +/*精细版样式*/ + +.x-admin-sm{ + font-size: 12px; +} +.x-admin-sm body{ + font-size: 12px; +} +/*登录页面样式*/ +.x-admin-sm .login input[type=submit],.x-admin-sm .login input[type=button]{ + font-size: 14px; +} +.x-admin-sm .login input[type=text], +.x-admin-sm .login input[type=file], +.x-admin-sm .login input[type=password], +.x-admin-sm .login input[type=email], .x-admin-sm select { + font-size: 12px; +} +.x-admin-sm .login .message{ + font-size: 14px; +} + +.x-admin-sm .layui-table td, .x-admin-sm .layui-table th{ + font-size: 12px; +} +.x-admin-sm .layui-elem-field legend{ + font-size: 18px; +} + +.x-admin-sm .x-admin-backlog-body p cite{ + font-size: 24px; +} +.x-admin-sm .left-nav #nav li a cite{ + font-size: 12px; +} +.x-admin-sm .iconfont{ + font-size: 14px; +} +.x-admin-sm .layui-tab-title li{ + font-size: 12px; +} +.x-admin-sm .layui-icon{ + font-size: 14px; +} +.x-admin-sm .layui-nav *{ + font-size: 12px; +} +.x-admin-sm .layui-breadcrumb>*{ + font-size: 12px; +} +.x-admin-sm .layui-btn,.x-admin-sm .layui-btn-xs,.x-admin-sm .layui-btn-sm{ + font-size: 12px; +} + +.x-admin-sm .layui-laydate{ + font-size: 12px; +} +.x-admin-sm .layui-btn{ + height: 30px; + line-height: 30px; + padding: 0 10px; +} + +.x-admin-sm .layui-btn-lg{ + height: 38px; + line-height: 38px; + padding: 0 18px; + font-size: 14px; +} +.x-admin-sm .layui-layer-title,.x-admin-sm .layui-layer-dialog .layui-layer-content{ + font-size: 12px; +} +.x-admin-sm .layui-input,.x-admin-sm .layui-select,.x-admin-sm .layui-textarea{ + height: 30px; +} + +.x-admin-sm .layui-form-pane .layui-form-label{ + height: 30px; + line-height: 14px; +} +.x-admin-sm .layui-form-checkbox span{ + font-size: 12px; +} +.x-admin-sm .fly-none .layui-icon { + line-height: 300px; + font-size: 300px; + color: #393D49; +} + diff --git a/src/main/resources/static/demo.html b/src/main/resources/static/demo.html new file mode 100644 index 0000000..ebf8f46 --- /dev/null +++ b/src/main/resources/static/demo.html @@ -0,0 +1,40 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/fonts/iconfont.eot b/src/main/resources/static/fonts/iconfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..df5334af5f88dbaafc510fc0b94ecd79baab2ee6 GIT binary patch literal 49600 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 CY%vA^ literal 0 HcmV?d00001 diff --git a/src/main/resources/static/fonts/iconfont.svg b/src/main/resources/static/fonts/iconfont.svg new file mode 100644 index 0000000..f6f082e --- /dev/null +++ b/src/main/resources/static/fonts/iconfont.svg @@ -0,0 +1,477 @@ + + + + + +Created by iconfont + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/static/fonts/iconfont.ttf b/src/main/resources/static/fonts/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccf533ec5e6b778fe8ffe17753dbafde5ad3ab90 GIT binary patch literal 49432 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 Wq_gOFI@Jmyj-<^eJwU6rJp6x-RUf?o literal 0 HcmV?d00001 diff --git a/src/main/resources/static/fonts/iconfont.woff b/src/main/resources/static/fonts/iconfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..d06756cabafdf52e80d4b9e3119ba1ee45a2ebe7 GIT binary patch literal 30200 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
|q2hSViV%dX`aB1@ z^7Dwylbb3@N#hj9PwZaSI6H?iA<>3zb&k_1J|wPeO{2x!8YO*Fsv`JQtFq#cZ>$SG z4z}|#N7`(gW~5!W&WYr-DLm&TjHGnp?95ZbWbD?Xer$yaDs&km7c+6<1|XnPgiPWQMjOH&;rwD9P5ElGfyQX0#P~REs9!;JCClkNu8n#{F_( zO=z^}4zDd|oOH9G!+RExY*~_B;wxq+=?S4xEet1QT~2Q7XnU@(`7CJ|5v@&H?-{iB zypaPf`B7~rEWX9^T8Qzz=#*+Q z&&pt5EN#=pUQB6SncY^oE>O)W23lVlITeBlPPCdhku5r5EA|z0at1s1Zyr@P#JLC} znX7Ba=o`-b$kCx!rI}dXvf-j%n75S52tC)*K--dqrR3@{p;;<|%aTl0PB!7b57l}QerI!0roIsw we(S@aujq^ml`?>~HkoL8$@lkF>C^s7A(t(dw&MOqSvw2B*2>C%`%d}-0Li%S{{R30 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/aiwrap.png b/src/main/resources/static/images/aiwrap.png new file mode 100644 index 0000000000000000000000000000000000000000..36fd481b048959bb4d6fbbbc932384e0a4b424e9 GIT binary patch literal 3032 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ρFwWt@M8jm) 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/bimg10.jpg b/src/main/resources/static/images/bimg10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1d52155cc39a74f68bf4f0c184bd8e08656fcf3c GIT binary patch literal 36639 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 z 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 P?NOQlOq%LS>Hz=Q-;lsW literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/bimg2.jpg b/src/main/resources/static/images/bimg2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..59e805ba9c863e6e2a4770c8e82c7bc20530ddfc GIT binary patch literal 30119 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 m`t8db#qqHcGG!4W&h(x{RO806NQIj>i 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
xMmxTSc)R?Gwps8~n@erAld8uQXbZtOp9$y%s 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

uLD9+IlZ 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 e%H%9~GWA~z=ukCszJv1eOFQG4&A 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

1K!h^WF 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

p=r?O#% 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/bimg8.jpg b/src/main/resources/static/images/bimg8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d918568af6268cbf103985aae5829f0a9cd9f2a1 GIT binary patch literal 101468 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

4;NS% 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

MRI?g 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≫T3NvCO7I+IOxq+7I1*)ghM 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/cimg10.jpg b/src/main/resources/static/images/cimg10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5fe49607c0f213e62c19d642c605e911f940c997 GIT binary patch literal 14122 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/cimg2.jpg b/src/main/resources/static/images/cimg2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9f155ae97113e769de86fec57503337e402b4701 GIT binary patch literal 31189 zcmb4qXH*kWw{~dK1Ox-piv%GQl`6frgdUoNA{|1LE?q#d&6FQ-W4hl#|dJlqh zq>FSBy}s{V>s$Bl_sqZ9Gw1A?^~|2b;{zZA12Y>B2Qv#dD+2?kASd@DUNAqH zi9_hA5Z_ZCJ}}>Z1|c9NC8Z#vxKBZGpO2Y=neYD_f4cy*WdEG%AtHDPAfzQAq9yp- z3t$5P2#ARY2mt>NcZi5dNC5!#;ch9M`(L{)6PBY%JlQwrSo_M5LQ4sIQQ9U_>DDPpQB`P`zPqw@l-^a27S6%^_Tz! zm7RVn4ce6*RjcMW4(%^srQx3h)~Wf_*F{yTqrvA`VyE5^S4Pc5_|Do{DOd73Om4PO zEbm*D3v>3>BV@w9H*gh!FmN|#Aow0qS>C|iwbaqlSR(^_J3RFJ-2hMq!}EeUP3G*2 zJUQZSTrtqAnTvnoMq`vwjis~oc z7WlMdG~sk~kS_Ls;$&I}#L8&}6Dz%!d6Bt&8JsYXlUdC>UC)$GUYtGF7DyBWozooW z7yndSuHcpYvq*D1sVWxb2se*?wV*hRo*{rd3x1D_3}62X=y~(IJpMNN;RqMM`qUbf zw0Gvq^S-7ma?LgFo(2rbP#aTw0E@;e`s2VZ-~l~WN}p(7ry6V!CQYA+Pz<=9iPQkv z=~<&oxN83b)^X-L$NbqQb$ZTP_l^cKuIJh@JIQ&Wf*Rr#zFj=E1bxn!Kp4hU%spKb zV-z~*;H=SKOjb6;{Slxblf%eUyBAEGIUW&KN{Sf?z z;uG3UhV{?Lw;#s8E2Ty17EtrYp#u3gPDzlz0C35!7XSCOFrnmY!&GxEM32v#aj`av zhGcNcq}e5r`Hf1L)0K|5Z4+dF)b+qUXl}B}UBp~!^DltB`s2jJZB4P)h5D_lvOpj= z9$VyQB)`Z+v9bJ|-R(@j3V~@tCL?Kbye=Gn$Gel-=Ikj1m^?7J>1m;zklhdMk#l8n z67ZAiKMO&$*MJ0G2CeA5-SbVohbAO_*b<0ILw*z?AlgXWGSg?a0}8F2E9sID4f|i+ zrO}gy+8yBtC}pp#4S#0)V&?G1@k69+qB@1{!lj-Zw|1Ysr#w@pfvepPy}>R%^6ZQ2 zXguMaJ5t3+zGfSB9sodrc|ntn#Lo;WF{X*NZO7WarzXRi+MB$uvSqd!x3&sc7TSS^-sJ-q9p%${LgByTB{BVMl< z1G-C%rhUbBxIXs{IXvEFG|Rw$nEZgDr&`@?YGz5B zIjM)1#Imk8(6y;&8~4-V4RIOmtQnjgvRdRE^C^)hGs&sG1>EmB`! zUl;ekw?ZYE&N<>eT7usW{p7rLWjy+?4NIH3>|jSGB;E~NvrTyzV~cxKa6l7EwLcP9 zX`HHE_W0GyBF9;4RtIZ#8a65*@P_D{vRp}#w1?AQz`$Ps+$HI2vfyw&{tj-gqWw#| zlC4o8Msg2U%d9xaTMBKgGpa@^-pak~W;&h-W2$UQuuqwMLJdQiyJ=(Qtf$au0qO5r z^y$T}WLU>SPKjbjLOxPIzBhT*E8;5C8>aO^hK5uQJmEloQ^dYuew4C*DxTX_q(TWZ znaX>NDFxZhcO3)#yzreV!qn9=);Y09j#X%PJhAVx=u~U8d}ed*$5uJEvGPQPE{IE z)ZB+!Pjy$ZZfSfoUs5%ByJ_;iltjERMuLLnaMW5o1l&Ik#T!JJCzrX`n&G&ygE#AQ5Qb=pzf46V-1v!R-x-TLf)qgQRxhB|OgA?mN@sJv#K(6xzT zh#T)(Bj>GiVSYv!D6PFDE5Q034AU52Gjz|+zrO`{jFtXJ7|efY_S}_mc&dLBm>Xr= zZ1%jzYqm9tgZ1tdYK7^7RpUsq;C%2Gt?qxQHmT3134DSj+4?qFIh|rx-}H?lM7H)G z#%sPeL7Fornb6f8`lCsQu{73wc%vc{3$?VybUo_@CeL&&mk^D5sl-M!SkD)DW z+Q*y4#9Xu{GOW~>})=FO}@I2r>&`|3= zIHopvXw~S0j%P{F#~-9Cd?nPJKVeZA0DafMvN&2{nfvno&#EHZAZ1#JBf{+rRC>y> zKZn_4U++xhn(;wx1`j+ep2)|MfHrB9m0e3%pXe&6yt+dVeOd*I(S=RLq02ylDKTrM z1hV&(ev0LwnD*qUY8rS;V4LDi`)7i&8%B8XLz8KYCdYu8`PfsvHtl89 zzCUhw_@X$fG=Gpq&%!>Yp}4zcuxZ3aXLgrIhYrPnOw!z>mU9Vw+Anh8l&J$#+{kH= zu2psAgLR0UC`3AsEA8!w0}<3?3F&GSif*jo9SNR#Flr6%2<&`W9u!3*a zPI6M*^fP9MPg{nJTE44Lr+umdo#~C2PF4JNp0{7iHLd@CC;~f3E%LEBuaE4I`_+TG zoqiK{z8bt&+Ty}%(r^)*01N~h70OC(yka%jE}zSMWrVoC$K==dB>4Htcsj`}McjoP8NH^v85N%~_=9PbW=WwgEh(!)P95;Gs%jjoF`h<6OzI)j z|D59(mX|L6#kVQ&jj8#LxgThICFWE|M!dhM9D!%!aUzh~(@UyMt8I4}9xr{=+t!cl z`8d5I!J$5-q{$jm_6is5So&$jwvZ>|fuyIU_WKl~LmU#SH2AeJK-QjMs?Fe#%3Y{A zqghS)-Ad@~cXrltq3n=-5L9^mAb$4A$K_w%!2PJ=b4<K@{`R@Y0ewW5uk}Z>rCB^pD*fcuzg0^}l_pPVDW(c}L_p=jq5vd;z84;;R zPzzpA)AeI69wkiEosC4+9o~^*-U?*uT895@Wrq*}k1LlJyhW0q>4fEkc;1>rzd1Gu=2Mn|E?SGqkQ*4aP|kj z;q@jQZ^zNx#gu*_P;@{E7qn3W=a_EdXjC_P21oO|iRF}8L`%>u8sLi>75xluGs9;X zt_?g!Y+M~`oH>Q&r*e8dy;8xnvI_%&*RliYcnjbkRxu%;hNBSMI=P{!*eaXHiOun~|4v zOTXgq0Za||@EiO0{ik?0ktHxx85aKZ{&b0~z|%g1@3AZ8t!i~TsEjAa2(+Zc-P}6? zgzw!hXP0l}6Mfw;z4voR-bB-Wb7wz@Ggez%sX&+UT;8WM4?KH-<{B-tA>aaYvYtzk z0s=BW97@65AH3rfRX7LV+9nOppdvAtJY78n=`rw`NQ$}OvSDb7hYNRl7Prq01tW!* zHL4QPwZqahTb4o9K+wD?C=p*ijP57z;xM!VHSN*5e_F!mp+QgIA&bGpg%eIa6O{veBcr4|az=&*G zfh`D7E+UJXxodiG`AI*r+>%}!^&n8K%OCR#QKjJ`kgmN@7x=Pp>j~YB6d4a>r&@{g z553_Y*_fr+sw3!ZsaS~2uk_cYy^Z3AoMa!PbL+{WG+f}BK&;*n1pd_veA8Q2wtDw^ z4h4e~JH51tci^E@@!k;UiuORvL}NCX?i8HMmo+2mIL?w^J&6Y1nQWKw%KH`l&~(yd z%0ze0*j1o$1kOelPiVfv&kt57ozE2QT#lm@;eEPbb;+y?Z(6clON6GF-^Uo2)|ll4n|lG()DLXVemla-@PJR5#Mo0)=9_@}yxS^xKU z-4gt(!E)+lE}$w7fm#zQ5xDm>*}SmJIc78FsCMFMu7L64KjAK67iVJnysF5N^Int= zg5Th|&}Oj=D&++5N1Vs*b!Rgdzm$2PyVXe_Vkax$ntplm7qD-fJ9*bNn(}LXu}_|3(GK_=zI7WvD|Ur2XUNTu$Q#Byei8Wm zwj#PkJBYs8;(eJ`!hpLjaalI&-E~a*^e*alWhbabBo(vF9zujn3)BrcSw&P*rsGlT zC2b}cR3#}O@~K8UtG>f$^F!2Wq_CGO4E3t5P(&9Id44b*)yTk4ep|(tS3WS+`NEXd zRD&WaJtU)G1Q%Rb+_d!LD}~H5aduqr7*ywhIF>C4n4zuKI(QdL&X+JvK$RvU{k<^VX?)CEX30!sdL;)}nw z2UuP-Bo%gU)M#I4?tGcK@U?vbIO|X5dB*f|sXG2uuTCv~s7lGM@vh`Gy&C<+_OAuyH>36NElh>5ko0=w zvvNt^045S%al=;`FNu9tea_0;Wm7+2;5zm)?IjCVo<(EHO_M-(-?VJZrNVX=CXMsk zCSRi6Tfgcb#0FUB7w{!aB^8I~t9#2y6S`=FWe7hQj1v<~#XS7(uiRXH8=P(~38Ta| z#cdSm_Q<+CFPP4B9=K9j&0_sG1mXp+F$kQF}gQ0lC z<#!iF$#42)HQ3brih0CsRgUoscP%nswHc)`SQ;o#COxeR5Bm$?X0?lPSsIg}e=Jmw zPYBJ$+@1K4!}Wk(ddVZzX#JIRLqtS3BgcNREc!5#>WooNLNqw_ApJWL+QX0g<)_S~ zdb4ls>Os3siQgI`qemQ=SlQK&S&eS@u01~b`&TL-{$w;P!@~&gErLxH`QdMasNWWy z8F!C7LZ>)r+u{TQ$UWe|D31XdgO-%spc#ivEsTL}qLXV57y`9K-ejpi6S7ZHnaWeu zQT!Y(;GOQJg)d3~CORj6*v81u^!UHSJe@RHI&90O4)N3xX<4#f1|^(34A=_ksvmdeISt33fiRH9d(o1e??_zT zie6Py5q@VW*Uhs~%`fL-eC!F!21C1dZf2!u3>s~wp0PB0mkad*P@ISS7Z<-au$~Zk zcedoz6z+DNsnn79!)KJy+dAcMH-642M}em(P{pi~x&WYvSQskxv*5GGC&GHNZ|RzI zWM1*DdMx2qCmz)u!XDRkk|;Pp&1|K#+_CEr*%YL3H>({xJ8o_nzdSsHH*jcHi2(r6 z^itC$A^}Bxr4v$>j~&Its1&HpN&p1t!PsYs#-=VYa$pU9(OuBrkzE;NSR#E%8N zK+KdkZRm{kD{-^v*M+MKXYbVHXkNU;SC@R+UoxV^^vChe={F?}-_OQuWII*My1*^d z8XP?gv(@ule7m_quf6&N&Z9MC>AVKzfm1klx%gwt5=0Z@k)1`>+gcpbjw?+$`nVPDTGqiK&kzEij<=WhRtCcVJR7ES0U{}0FGy>)%f?IrEcB0P<%PuaeB{Ag@` zxza-|+MWiq+)lvSJfvzFXsRt4|9IBPL64 z$QWM)az*p-vJQ!?T>t@((@9nC0b2#<+0mO8 zoqP7JQN2E{EH;DP3qjC#hAdCGtYXL93MW)YwZc&-eI_zWMEO^1>LAA+F#q&hh$Rd z@D@_9;S-8i8Xsxt-+o_GF((M*eH(_SC+CUM{@*^t`&5ln@z5Q;& zY)xHjwIKs90>zpdX1&fP7j8)0E*>EaBGIqRFG zv$^o-PJjDnCb0oKvlFBoJIKo+UFp^)`Sq}BC|Q_RW;43Diu6H3%j$;0eYMcCJ(gIw z+=bA#$P}&^J50bsd{5~Dok*Q`RT8#cW)alRvUe*oS7d{#uqaCu!5+4T-S==)?ezgUQRF6q&z40V-a|$PvRqxPqFfvKq8cpu!Bd2c!?>C8$C5)`wi@lQq_{zgbxi3&%@bmu zA<3Pd@}+lY2_M^&8J0<+atSVCK4PZ4LebkFX^desU*b9b0+P8>KlRrtFrOwm$W`o7 zUbHkX9pCSc6`CScrhBRkAs1rm&KQ9(uxL-0?k}zs0`Ep#l{jo#L*=9Xwo#NdA`xB~m@=Ydf1v6*3)xOfR4U z6Ii$Ga7%V^Qg>X>pd$}{&tgSoqLA3Kqi)s>khgBYZ~l%Meavv33jph z0qurR=B7#=7cS_t|Xl1b1(oz<9tRGE=Qu=Z|GhV zT$LvK_JF1*zR|s>+p}FxQl+K&Q=!c5^(EHMs}wH1Ywxm|9y!eVK@N>u4gHD3+VE%+ z-?cu5hWUM6omw1W2seg8LUkqj>C`1&r30={=W51!&TX0z?>L8Swj^dE8GMc9aTiy?k`*>iFN~F=A^Sbbt zWogrFIm#(ru$Dj%QWre-ATvy;4XWf%C;_EC%OxM8zP-w2{xJ~ynZPCgzT z^dWcn49?m6b}NUb|9vqQ)v-4NGf^^4l)_6Y_k`m4ClhoZz0LSNPk#U*w_IYU{yMOc zTHExC%O(6gC=Nr_MdvfKvtcZfK=n-g$3qjVW~+&_ef^{vh|lJiBUtoDe6~Bk{s4%o zm2nVoJ>xrS=#*Tv(eY3-<)LbEf1pP>XLEz?RK8boQla#pp$fOhC95Aub)kwvw>dA1 zXLeX3lh8y*jHdl)nIJ0X264jdX%jx5W3orG*<8h3&hWJ4Tt!~i!1*9^-BJtlh13ta zN^gt#B#_-!P+i%l@+2zP@)rFyc#%a`TseUdkCvjlZny?(I5o9^*zLt)$p-O|;*+NB zGw_g51J2s3(S`j*yN)0dPAB|AEwIYt(%c`@qH;eM3ir&nTa+y5Tiy{A@Eszijgv-}wOl_TG(tE;i>lI#f?`=R<$WxS7c!yCCm z2$QqRHY2v?QV+!#J|=3r=qOimS5+~r*eF4)UML55+{FNqBIM)TrODOecPggmsd&A^ z`+B(ijcjF_G=eadOn}3UnreP*#3HFPvbJ>7TB-;GnoS7bylBLA64$$)lV&}>n$6G9?zwK zrvC^r`9Q_Z8^Vd|S9R>>}iEZ(!<5lhpG$lLfV2nkK0h2hmx$B`N1PW4i6lygg&!R zs@PW%9J3l^Urm+%1*ivq-@Yzw=bXg$S&s4aAYOa9^7Or2iu?2ZghTpKy$coRc8W+9 zv(2a4%QC20P9vB%`#!Q(IMRjP6ai;?Yx_)MBC9vm2!{Wf5KT-JhdLVi!Ojk}v!A6s zx?GZL&0-BW0m8G``j<&~NCPPFsJMITPZ8x4sTo2JZ59qW?!B~C8ssrEFjdO7t}MNlcrDUo<3be=v02WC&gV#Pf&?{?0ggB=u*9{5K;&aY^KAsX;?{`GI7)g z%?K=GmkKNIEg6omf(j^nIU?H|&Wpf?yn5d=4k;GhJIhVV=qBCL=s!NEotXgd`DYX7 z%662!Yq+X``=0SpY1tiM3DFo%WW6p#c7u1rc<_+w^HOS~ro2u*H`XjM{ZKwuIj$tE}ZJ`%u z7~;v?#Dk`h;%chL>P1E$loT)d`E)n7A|d&hkIzRH!fkH7#R3xP{HkR{wUi)uWGSmU z)Y}tD3YMi0FtWUSVR5e3>ZMa{DDgY`f$@WOWzAjmOH;$6O8MjR1OKdzI+liqA^plQ zkmUVKO$s7^^4p>{{o4YUk*TwNNHl#3w|v7lhAcR0>i(OYji{e6DR$oeCh!fKsSgzB zwRJ!$PtRSl`D&go&q<$}XEQnboY=@W3e$!w^JJRpS3M=tKpJ9TQ&9Xm(oOwyxu}w*J6PCB^OQA;-oYgQ9Td_0LWfU|@{27kW=U_FkTrk2}PVlO?5?2r%%0~Z0zoSEy1x6MUTp9ey zOt3Zg7t%qOJ2=@k+sQX-BFeqZn|fW;`eqLR#2}D8bvTmz+P3su)#0mKAI8ESKBsB= zn(b&;Wm?_}RlO<5qc)N`Ss^`CrJf#RH}C!~I ze71L-8S77NmYr)r>gB$kho&N!m`|)M!=gG5$bfe;87hiPJ z9SVq?@b9we`cdVJ+)u|ZU4^6xEzA)7`hY8X+C&c8eZ>=VywR@NF)83`W;9bFSYFiS zD^BRS7r+iI%PucIN)k2|KR2${yd<6~AiP2N?i+y+x?McE(^4e3Q7|quYSyw@_+`sr z^g~g>;h6Oducn*%_xh6Ds3scjuBnq7$phrrh{t%VI_x6a=6aWc>Cc|0bIfY)m&}x3 z&@FaghA5$Z@zm7U$B~kz+5w>g33|aow+&;_t-5;fU}N8S zuOaj7*ri@DC`%(NEVT~e&?}op9Hn%$G{8-wl8Xs2Hl(SyRO0H~ixqXUXr$_+xsG(k z7MNsM5V~UiDNO=Z&^b`eJHoa>FO0tL`Usk^hM3_Zs7Dh;N|6rCVW|`rft1)(sxR`> z!VY5ZCUh@Z@%c1h;=75ghQ?HmH=+{~2@^Osr=KqLNAB>3+~D(2EW!}rwj-wJ<+#d7`hm%8 z6VcC*L{X8#J^t&-Q?x0rQJa!949TB5%sh`*sxt-vUNHiy>l@`NFL{Vha$3a{&PX4z zs-=0gefG+@Y~3|%A#kf{g$1%nM9i1=XU3D;1Sxv^z)BTn_>BfE6dqQE^7)PIVIRwV zYa7N3dLUe2gh}7eWUXht@Va#!w{>@TCa38)kH}Rp`JR$QrFp~k?}l1s3O~;VL1*2X zhqX;EzIgKCn(d>AD?f84_n8JgnmA0o7+o^5u$3ZDs+qa$8y)6mCBEThI<459Ju2c*ZRp5c9TA+Zw)!ZPyx)&6&&eu*s20v-ja&!;6%e0GnnE*Y9Yt=$vnyrd$s#4pjBE)Bl{j9p+9gsH%5c9BQ~K3hrBk}^vHSlRRbL2hKSk{uHKU|5KqCyQrG zcGbL6e)6OQlQOigWg(YQLvzgh(j*kA!kfM1X#?`~8MS;pdGfOpL4|~Vf~}t73BJm$ zC`cF82+tk+VtCZRrj5Dwd!5Mo)`*>NYjROaS; z(st{>_P8vMw8^ngUu8?k-OWIls%d(ZL~LcYv;fSs8N6?g%6`f5dN4L7?C9-e z;g=bcjJOxa-UT8zYW1fH?qp-6fFu#0#CRw|hoIyvg=EC-Lj#Yy3|pvmxLyK)=%jp! z1#9(a_{}3?6>M5)5Ir>M zn5TPwbvUr(>ut&4@^6)&l@k5huv(cZ)5u1wgWB^`-fu>;Dc(fwT8&zt3bH~AUFBxn zUKt=)p%L6nOGxASM5q3S28Bla0f)6Q7Ttj^lip9b3`XZxtRfXRh++7qrP9rB^um9( zM2Ch9wYaAHrFm2O#G`$bEd;x%W!Do;O%rpyYtoDScbPhg+pycqjS^p?aJ!Nt0V}Ay zf29>JWeFy4+m3yOB8!Ac;u2NzQqC(6_i?99K68E7OIm5wM|R~q&%Jai+X1|uk|4ev z?!;waG&bI=oFT;xSEgZlSYB^%B5F zR9FS))v&4-^`lz8d~s}L0uP-jsLc-mSknn7GEX62#MY{XqBlJzia&8t!G)$Cj1h(p zUElp9=Ibj_HXGNQdONglquI43iI5ZI+*8nS#etSskA4-*9m3FVUvU1+FM14Ec zGo^k0rCvihW_3pRwVHa}_56&}zJ060Y?c)Luh zjMf}sc{emN?RsPy+Il?Y1o%H54!}mHrD+!#=G#BiTd6u`1L(3hD*=B2e*C3TfzoQ! z7KgFw66;BoDHu$W7n^+;J$e(iI?kIpe6E0abIrY9Q}oT5k-iF0abSWH7%1FV)I5j{OAFIJ$=yk2$0`+?0hk77C^E2p7xwfz_yrAs+rhRvoYa#=ADx6YnclW={ zphW2}?*)vwVMBtu$~q0K{{p5@7K09Y`}G@9JWyv0--f*S9^#T1x8_ivaLP11zDmk_ z>tn3vJlEQm#1Be^7D;Sh%rxKB>S@P!0X#LUuXRR^Sy6?>w~ll) zfWX{bOT@U7^xL_ON4vhQ1I;BOT6b$V*2sh^DV7hBkU@Fz@f2WD$VZBPM4MVee9^M@ zk%)?LHq27lMkaF_UOo#3O!vm@I&&vU?tZBnDhHgpT95z8ddxIKS zBaSFwpSH^Qn)*>6BXTE~CiMNPmZGo!v<^%6R88)ecj6GG|8X zKRc`FXOIXL^a)Lo%JZm<4@b#pw)A$oWsuBeYq^k_x%WvD>{Otlc0T9#5e67%8eGwu zn+q|?HGDH!70z-%5#^LaVe$yTtqb7^o}sY4Dnr!hew;gT@?U_k7^6UK1#5Z$*Vz(g z2mc~aXk#FD6;-#T7vy0+F&jyIX>uuU-Tk}YY%bra&t!pUK?R_v!A8EonIXwNzRoa_F|m^NC*=Uw=B}AV;vllBg`ppK{1+-j1i_DCUTo5wFkha&JW2 zQ!9b4ZZx*kA0IOP7HKZl_jFZbormaX=NEtq6#e>ioGatZ?L^>VlHS@4%kPY{MY1`Z zL-v@!yab%tC#ra+7G7gKzO_E%-pmamX>k)s4=^~if+O1SQU8)A4wIlSUfjrMrP?WeWU70qQqDejCtmZ=vlSw z{=oQX&ROP1ib!FZiQahS0jUxsYlAR{;NQ}r&Y3)0X#v4xrrK}*vCc*HpdRU9z9cZ{ z{WJ9ycgF%=kvF%sG<7@IC{{%m+y@v@Gc(|p(^0!fWL**0err=85ZEXY!0nxaV@;IK zrFk@=+B!w|zK)x-%$-NYfC7zqP)b4-~U&aivgS@Vdr9bbX@v^lr|BL`q zrm+>NYgk(YE*9r{)v!>A!&DWhO+^a@Jf|2V=vuRqD!=h7*0G@HDjoS?Ug61Ofug4i z0C~+9Lxvv7#JVauzH@bJPTg>z2vmX$c5~YAu>UrgB|*rrR9Py}DT!1>=~K zoUn1-EZBg`ynq@A2)4JL;AJ=1t6MooGN6CVamF{~pO z109@@uLL5-lS?uyajrj~7#s$<4B891N4M-HmCDpY0AAtL0NIqeqO*jocBwjVo8r28 z&>v%W#Taf4_xkXhe8P~cYUgW7?l4cyvvelIoNxa&V@2Ji zmOm$U4wf6X8(bz>Imk6#J1;z%ELmq6QhxtLKDA#KDH7IF?W;5V9dEik?Ae5;sIB62 z%HQ8pbIYx~v_-tO?bnal5Vx@$qc}{JN>q8b+*$|4Pf791^Rfks31j?#KW=D8Xji`G zCqX5Wf0kQKzMQs(8#HOXH&YUzx{>;xd~Om36kR+>y^9$NRpWcv6^AUEAehOF^O73) zJtSNzFTUIMm{MTsk(I-<1G1A$4RT$P^@feDaCtvzjF3DBKjUx@VxoiXORRYf;3@f#!{i#wMw0cESk zRJR~;5vO*C#`^DGR1ZL{5eWg%*SBSj`;ps~!QxhSODC_11@PAd<|&bm z8)ta9==?ZnyFDbtg5y!|c_3Wz%{&RI3BfAgoDswXBJYQOy{suqdp3qEf`1L8ACjGC z<}>N6-FHn*^Z>sdp@`?9Akl)rnh6PrlB8*kPIL0Vfk1+vzBW}W(?x-P|InMO&RxQC z6pO`JsHhFt$)W*wAkccG@GEYRj&C8pzY$`Ym* zIaeI^D1)+UhA(xqWs#dnX=$LRXvNCJYYjqg7xNv0(~Oy=@K>H{X4p%M^AH%6{|jJd zBf|%B=1W6daZ`de=hQhzM#jjT_)fn zd;{2LS>+Pk5Wx^@t}UT=9#Q;+~!Fkmhl!QB_>kd6(2cTc+4Zq97MW$kkL8W1kl-?J_E* z8^tf3X`0ge>@UCsJcCIC3TQR4c2C_u!iqnZ&V`#s=9H~kUr+wYsUL~@BU`_uOE7sLu8faRv->h;4{q!y~g-0G)Yukf)p?8B&AUvooLyI9+rB$+e8_@}%c?D7j2_a&c`hbnP1ucX0EktTWa zL3yFZi0NcI9mD`g{=holLQ9b((Q7kQ071p%eIVJmdsE4fhCO)irW&fGOD~p|BPU70 z9nm#N>_jhMJyll(by&<U8V~x&YO$e)eqU*XrqM)lz}wg7?zf?4~3B))~{0#xk|!yCquYe*sp}oOcuCciCiJ zyw!{2&WDmoV3c|y46r@n+6~@pYW}dCO2sx&9G{n?IqKKX3@`zKU8K4X?m98l&|uLa ztI|UxstHqduU-VEv~ThV^NDL4dS_#lpapeV>=co`lV1efd-uV<+XcUuh4#sLY*(Pv zi*ECeejVkd&hTvA^2IAx3n!^9na&%{3YfsSP)9vSAkL4ExLE#lB4iIP(e`imgv7|j zh3QVq;EOJ9@O35?VV1*1te{>k)F$F9_N#o%NkLn4iOmi+x2cId`v zkiK%yYXm>>5$84QFMX0}TxHaRKIkjv&02^0%XO4}-a4><h<5!X)8!3CjsztrG5?imP&?8e38Y zQL+Y%#);rf6e+;Eq7e~i>$!z1Jw`OXNTorLZ)tCY#Zk3-LQIjSq6WaWZCrd%O1y3N z-MWB;tAKH24%q}7K6Z=Y&LW#tAotcNz>MoMp)`@*xw0{k`%?rfdxVyJE>O;?RVA89 zZ#WcFOiICHZGFuiP!j)>E7_cq_U%OzDM0_3%LCK3#+NSK74BPYCQ#|syLNwEhJIZ~ zV-bz@2aRVV&KDZj38Wj!4-SpRsV^@9GuCv4Nh_?cWWA72Mf3Q_s5+yijUt!S%TgFt zhO6uEb(=?U{VO}Ngk0JIZg%(ag&^~onZ3;d8BIfsL<0i8=Rn&EL?v)5z*?RD+7uN~Y1MgaGzZdd967->kzPoi4^?Wx_1O zvXyrd;Q+|Vm@L%;=c^wqNq0+A$F_T(7A&74y=Jbjr=*G*9vF@G*^X3D{B;t>-y#mNt&dwMe_8+RHG zA^M{a-n!9Rd@=}bH@6*<>_5-L5 zR>zo+KU5%qTYjsT_V3>o%V3Th4*B<(;O*P5qy7Yzf$JK#qVCI2GoLfbSw(hM+kGh= z_)22_hAy2P|2+G1`Ulp5goW{7Hc5WT9T00`_|>e9y|r#?iKC>MTP2SQ-hhL>1e>E& znLn(Y;g@l5iy&H9s4$YhIhjuO-|~(-iZJXaeV^m9{(gRA=d+S_+?FAE*N!LCFBAQR zCNaRpw?Cq0Dle3e4=xwPG84%Eb$QQ8hPdVm?%m79=e^%YcrpLaLcL-P)2J7Ka^jnw5n?rjbt&8?tL9?H8C*GL2-QI>b(AwVVa2X z*i&nZ=?7E;dT=N{xYXje5vk)__ok~Fb&w<%bXVvng@sB{`~su+y`~;L;@prr)#-w! zT>&#Nr{6gJonPiE7#%+Qqcb#JMjL50dxw4lXc5nd{XQUzI78 z^}W{SOR?&zzGB}wYn-L@8JT`f%Auo%k3p!8$Vg-yFX!s%xNcAg!fRm0g=&`>wqAAS z@$O(i7op{w=C*E8)BKcf9nQ$YM_b1QTB|Q89qJ*zfNF30@ zqlq*L+?}2}Ye6{FC#Agt^89vN?^fcO5t5Yo_?YIk>_l1%_ z<*#FEYlAlFK{JW_EQRe-6q2lxj0_BOo|qm(&b-HX?DpRZ{{SIsa!1%hrD$PI6su-) zw30?Vvt1FL^ogdfq{8mZEb;Yzm|WK`3x=dTrj-^r2~Gw&fyM|v0DI`3ErP>pQ;Blg z)9xb$E;m`B6-(xQ@2_*W7mm z{<&jrK|L|l`e0CQUm{MgMEpk-Qk2F+MWBA`ZTDyc^Z8TKg%PaJ+$~b zpA@V4_*SjASob)6^CW@}*Be&~ZC)uNyRylVCfwVS5T@MZVO$b3!TC`A{@na2rs-z` zzs4VroF(-6d;E`wx`*}=JxrC9l_6>)%gU>%Np&&`ihOvV>NlKSIEK0Wi`t3If2a)-whp^c6s$Wl@{#}wi{!KPL1s3jTdcoZ8e zQo=?_o#wce( zkf-4x^^)Iw;aOV81z976j+m=sOLiLu-oQ=n=($94l*UHVgXR`_A1bmOO{&Do7V6N_ zTWKgSKA=`W^EegJH;dCrEs|Wh-@)ZeXJ&fWQY{Wii!7(X$*vTDJp#G;3a~6c(eRC{ zyxmZb65M9;e~DkpkMEtWY5Q`EaTK|(jz3qzKa2j=4HvXKt?9rb1|qVf#=*H?5`UFX z9b|lA*z;~Gw=5f$LFvQ~EwiOU=pDH-sRAlFU?Y zKgO@+S=yHw8BKsV)uuiYtxB9@h6%HynBo=T;>IXq`6;PN@vQ?^G~yrxlWT zqhy-q^Eh+=03Stga^vnW^sQpHr38XhKm)|o9p_Y9?QE%U$wt)mJAeb?c&=p@`YPI8 zlRfGZt)$@oHMd`Floh(Pp##N70;(&oY9>)rb~tWH@b3~Zf$v(l`2$1Jre7|Hbou3k zAME32IR5|{=i~);;>9Z23FeGT@;s&_XSjK{G1qE=#Vu8LWKBnhF6fjEs#06rwGv8> zRn;CB{@0E=tOew3$8js8RvQX|$*F{OY8Fgiq8mOQ=fQNn4mu$otqIjU8%~ zTqNpSq}EX3WH_Uh45w;%{HnUJEopW_@7Li3>bm> zBhS{YlU$mjc56KNuElj2Q3$_6DF=dCAd&K{tN4z3)=}5dwh;=)6qF#TY6(c>l5hoW zJt_}bzuf8h7&t2_K>3Q}#~w{2bj|TrEhA7`;}RDw3O-HcUxiW~xyg%hof3RBIG@$` zODX_lgOT(ny#~oK^q4x+v6BrbX zC&2r<^q_cJL2@82Q}Y;!jD#}&?(xDg;fy37Q{i0svq~>fEs6?C>^sw%X;+9)<}~wd zH2W)f_bh@?l%7JANWsDAH&v%&?8?mB&57mAsDK^zUZKVJ$B)7NBKEO4#y zVMvyw93&KhxF}%t@Z|g``V@IGmccXMX|#Xz$XeVU<*1*+x#v8eItt@@4(+k6+I9<3 zZS1!ZjGc@jM=K|;2U32tOvfB%tH)5dT5jbs5=v%9ZAvL+9nfCUyUTIN^FJCNpRL1o z2x~*dcLYd7tZYv%AdZCi^Ts`DD+H$(Kcb$Zi>6&9R9(vA%s=bg2>fbErT2^>VI@0~ z4iqp(Xg9P7t~&^=l0wtZ70i~(Nzx+q9;S$8KX8Y-dG1>nBc>05B`KtoEkEvouY0t2IqIpl=FT__B$GZFhLbe)O!XMjD_(Z=6Kq`PH>KU}z6 zOJ8cX!Q5~FaLQl*0N3mfim1NDq|teRCfsh<86$QBV1^KX%8q`tEu^~&x+$~zZbWuk zS347xtbSE;TI@*EI&{NCmt>`&gWfxh-ErYpmOOF7@A4$uySq=kKeJ$$Rqo>;d`PHVc&5ukmq@7e{{ZxIU$DFN<+l9WjE(2#!1~pX zV(g1XS+5Qk8>edRBt=ln=l`p5e4AWNqtDGLVIzQg43Hc5v z$__GU5u94G4%^#p<564-7VB#eSkGQwbLW6Ql+(3`rA@rUM2FVtOh(m$cm(Gs9S4P7 z_NxW5(#USz20UaAfwTcbdY;Jv%Y$>@U^wy+kS9O@mm5OLLcni4|o)hq=Aw;P8S7|=RC@pj& zlYNQ-&za77t*uz`q=K+Ac&(BLjWQO3e$S`13T?-}$x_gbsROPF{&Z0N-Q|KBSY@-u z5`RAmrSEet(A6F7Jhb(HpjGOvzttIc#(4snm5Vgl|XLvyBesw3WB+q9|$uei5 zL3>**p^%WQsCeX_ln?^a|d^U!mF1)uC;?UD1`zhM20)Kmv!0;nH@rw2o>d=5`ghWc}Z7Mk3tX5jNFuJ!v}KMP?Vo4?2HQU6~mbr6&z~hkm;eGmpxr<3{F(&guY`b6o?DrkknIo|KBDfu3vDl5Lze zJ}XEaYA)y%B0H_L>X=f71BvP?KH+my3F9Z!(DbY0s>s|$FQ)ruZpgdEtdWJj`_890 zaJh~>MGk$54Lg?xNIgpPQ!^&I>WSUfm^p8d;(NzOcGvsIR2xstSgGYnl!Is_gL7gm zbQX}6uLCMqS|fp}WxS;AQd&Xs=BvnPjJ0=cy&`jo>WC~U+ zq2n$=l;`|5xChZy$toz5_&p1vCbDFhcj2^l|1 z^7YrWHy=T0&AU!P{>&{fnEwEV-b#nWQ1e=n;-|u3vl;?P#$z+>{{X~RSN{MtM}uyY zDwQi|t{?4cJf)?bGhw;iR=>F8i4mDsxl82ys;br9wcLyEFznb+RD~2Nm=R2uQbz<8 zyM%l|H3`{;lKjT6fq8j}Z?lq_4!TJp1ae7NS|GaiBO>{#uF~9=)L3rITZ!5?D1{xw zW5capejlcn+a|Ln%Ch;|1k0-b09w?U#B^20O5OwfEvIS+y9T10ovANB?9o>ww!RAx z+wRbP=|BMdYttHku{|$r+Nmu$IlQvmj#7^}e*hc+o$EFjUd~sfS?fz}v9=elke(`dXZd*;f(=I#g`$^~7 zND2GE_*5R1?C)0J0A06FIvHLz$(TE&0p<#b-S7sa@;2yoja8Peq5hEUq%9hD#^bo? z^wsPiz?|p!g%@Z&Q#V*>>DLMBZ@ev%5ZZR77(C<0!^F^DpZ<={x}>|Q?}<)%Qx^8~ z{{T9G1Nds&wCM{@lG9Qx_Eua&N@>l?b;7kM?I$NZe1M}Ft};?xpiOl^R<{OEW%oRC zTXmHW;{)@mL5M4PUv$@_^t1*q)~S}+M24Q*k~|1GA5bb*4`()(oh}IJDhJvM=LWn_ zHgbYeO3u#~N~xZ9x9PbOhz!SZXZxwE6HI6+@#8Z3q_E4&aHSDSk9a^C-H!oRR9id< z4T2EUV0qwFT*>S}y}u|#ap>YZXiKOA*!GlH$5ZhJ*nQVfPeCjh&UZX{{J#>;%BC_7)7RKVFoOH)tqN_){O1Ru#YCfN{ zyM?GFFU?zdHAz@?=)l&poKeqTnX0eRX?%iR*_J65Ub|l3Y>RfsyCW@roCgP=#l}f`D^T%-WAZTO+i2mTy-j z%yfG&99TnKBztK2*E&jKB({}>WS+F1kd}vTSEmpNLM^TzLG7pcRA!!Ftxd>+yeU}R z0LWLuyF3bOWHYKR7zhDSc<6)m!J-tb0mTL2W)hiXW9Z z2OxP=EtNWG#%eV8rAE5LQ4!qRlsuA2+IsW2tDZWFlWo#K&syrp?lJy}zS|rF?D$tf zUIR4Wc^IyO`S+TUsBn@qpM@sk_Jfgxj)t|G(ue~!f+rZI*QB8ITUf0)`XnP`jU{fU zhZ`fQ{o(xS7ThVGy!fN@q~@hBVOc40KXqx~kM-qH$@vc+fgaH=8)3BxrM_EI!pT|4 z7|6iSwe#YjwB7K;vb@uYQi7CAURlYm^*jZjyS3s8S#d}_q?6S{%h&UvDGx}E4H4SG zK*=Zex$>*VQR0yNY@2G`aKFn^l9jwi1cS8+^vRNw-lfFa$ZDGfS_g%?yHC2u7d zE|5QM1E@Z|JP4x}r2VQ3FFwi=@JLqDGlFrHpGt%NK!dv;t&paWWwsnnN=eTkfrbtSlNrVC2rWER6Y9z{v^ zkHngFXVDsp`sh?^e5XpzOO6Z!>yuG=a^%zzPfig0nKLI+!j4XEjykX0wno@L;<@b) zf=xll)Zt4igKJdCR_Z9QZO`vtN(RzGb?+^?Ccn)m%6U2}SL z-H4QqJNe7N9`vWD@l{``J5JTtr7aULPcq5lxrReX$Cgvc9`b2kWV#B)DSk(+uiB4K z*qKvzi=-%d8+)a=0?vGrIX@~{`}MX224+i^%WX+*E~KdPzhrU~)cAN;m9*xCi+$0O zuTdtuI_BC!-GtD}+fi|8PDdoO-Z@EjimYi#MTD2$*X@yVi*palU+*8)qw_yORsHX@d;Qp{EVzh`AK7GJ{{Rum z`4K~Q+bqk2p)5yn%$}hTATw=U;5@ju^+_u8^4zNG~|Gt;6?< zj!E~LG|^L3%;Ylee()UqD#^6=c>*y?oNT(G;;xl9KTJiA$J*J7*m1G#VLl#p(cpfl zp*{@|^1OE?$q(Vcg7w9_gOH;taE^qgLYhf%09C+NG6hT$N#xXBqrG{i7Ftjn3P~dw zvKE4`bOOF`www4Fn9QvU!%TVp_MoOjZk?^b<4 z9DXzbtLEKhy#=e)@>GP$cp*)NcWvXx*&KM$50SxeCn1vwFVFl!nj>iNbTh=D2ZbLQfouh`qU+L3ud^J5(w3H&ZGjPj%ja ztb8iYdbO)0XvqVnJ!ryw#~qUE+%~5Yl&fcuNJ#n$;L8@}qUov% zP{yCOvnp#662P3nX>n8SDLEjLpGt;rP%~{{v8S!f!*9ja4a--lG&{z42D5ijMQH(# zWXyhI`^j&u)qi;YRoiJ&r9yFuLONM1F0@Au;S5r zd7IoOr6~nycqeLbcBg(o$l%}}yiwY&EH|n?FMXx zB`*N-PYtVrf1O)2p9s)6-ouo+xhYmLU4>+iI%w0WDZ&&AM;uate3MF@pf^L3Mon_J zI5_gA60UKgAQ>+JqxVprRlUCmlR0DURYc?(BO?`^!-!N`8gDdr9@7vbw!=&10eJ6pb2>@ zI~CW$jjqxX<4Q@#K6D!LLR=#NiXYKbBNZ+O5>?LA#%O>`X_O^TJG3Z-lkcde5|T%S zIiGHFTq0UYQqj&l>8_0SSz1O!a^rF1#%&wE?(8Hgj$*5M9q$-8+vQa5kiNEboSS6E z+b=S{@s|$^Nbv*AdU{b-g1Wf+q%gIY0K$e(PXqZ=Wy4VQ5i8vmbZ5XmwI;-bB?WG+ zDMCh6qHqB7G!b&Y!?Us8PIC)T_8LbkU$}mKC^lUC*0GY9%^__=QTAiE&V5vTe*sa9 z9ER&`ux9HCx2u7)XoiyW-`dYu{aZuCr_bN=28*;#ih*Kq+#h`0Z!ToHG1HO>>Jkr6 ze_z6*`!CY}0H7ktTZ;}ny{R}HC&wA1HK1p3B`f{p@Mum-E|)_^IjbL&Tonpq-?)ML z#P^B)8kBc665*b8Aa+NR>)zFY3PuMNu1J;TDeL?y3+2?SR(yoT9dMJ~%uGwPG9qBVAXb7MH7 zj_KtRfKN|nr(AedGp~C!xI?}MbmR%Mi_#=Ew%TZ~yD3;H=r|h|j=mt#!ez=!(A+6m zl-Nn=a#RloC5~KMXPNZpU^=GbwReZ& zT3J0(wRg^s@~4lQg<4v3uw5r?*t?mRcYJbt<@asp(Fno$sMW2%0Br<==)Wp8{Fao5V#7gHhfvrY`$wOZ z4_q~b7S_1Y5MOs`$j22?YO6)fHi;AFTwj+lyeTOs2n3K19Xx!6FQ;ZEP3jbp_hg`@ zX+N^8e=+!1b{_)_8kc7_Pa<+v&^xPjj-@kRfX(6fmiDk4ZZHU0NdWS{z2oOWDoR%J zo^x}rDCD^Eiqub@O%iK{3pck0FbXm8N{IecHD0b?XG9?FY}qA89G^i;L}5kjsj`%h zKN`qm+fniYwO zp0wSJOto@apWVC>;*rvayG?nuCIUen;M}kBoPV!{JcOUtsE&e!b-#KqN)D5b?HhCD zkLQ|4&|h%|(PyH>{r(%Ohld{TJ_@v4sBZhiE3 z;|W52q2_VvMp`lU!|tWUZN?US&OAP~PO;lSoE7M{boG)Bp^0#chs-2=k27dClnN;p3pRJA7TOQJb#;aqX)NtEM?VQadr*(!l^NM_>SheWzRc|Xhl00L1$ zk*2iFBY-P;Cm5|L(rQ*H1Qpl0350XvvG`C5(&>`E=pEV59u;P4xGK0pPjr7;(cA&? z^AsL!&!HK322!scy!jt5jbD;*NO(FQST#)BQUiAdmzeMb`$OD(YF2KvdQR4@iSAIo zH>(AB^c@GsGyyU(??`cHcs)%$vdfDF(CpUx#PP;?>)46cq2})XzClwe}N$P3jk(C@$32!vR zp;+0-$241H!N(lXvkl;io`We75Ekh^i5*q$qbS=%~m3i`f&2&SH zP0OSt(~o_!{IN8)tug!X1ItKS@zW-pIGS;Q00W?;*W+GPowKScl?_$JAnQp{-O5%v zC>$Dcu}G_-p%93N-D`&v-lzAI!oFP(`r?JVOT2eFVaV|nx%o=&a5{wk*B%^k@uHvsszmtt)QIvn=iQ=~@C-6wMB~Lo7gEeJkf$YZDFeIPO{o%Ht~|m z@$D(45K438GL!N2t6mME`B2+=DFL+s?GuWlwQQLdUev9(2;(kEjFRBT3gDq>KLJEq z<62)WifYvcNn#qB3kpEOj!Dlo46uA`Tylva+9bANM4ts}PkKHvR0r!%mMt31LR_^F4rusxup|wODju^I)b3CyAK@v>X%P=ms?A% ztsBTG+%dRksPh#`wK%B;3baW@Z(>PT-d9>mdjUx#4t(kGMis#or<)}vvS`4{w;^Z1 z((&C3SV8;M-NB-T6OJk^F6?{|Ygp(aj^YqPQUL>!Jn2nGWRIvJqC;x#RW%uj1VvgwNQUjFA3FT9k~d%V;0#@yQO6vJ{skOGAh% z8&D4f=c)WC!3jWfyeUa@7~O%8JhM@nisB$eDo-xElpt=$IP0HEwrtrvgrdb%x+L`K z5Y5}VM;n+~>(2^L^P)nd@~X?Td5e*$Tn_!^GPM0te=4%1I@>t!6ce5XYnoAUbil|h zPiAi9&i+vIe$pII-a+#ol@VyYtUvlX^M>aqhTZ*_hx7b>^kd#3Ln%^ExaNj+EtQ$g z6omNXZTrYRW7E>97t2h^(EZGTnr@;8AXE*m^5iE4zVhl+=vKy_9zWte0s8sW+V}3j z+5q#({#1@Fb`dE{9oeBPteu5HD)@L&Jk^4vr)W;$jE;oRrRLsUB~6}us8I2sapi@+ zkT3ztdGN@`=SW446s)*1uU`suxJya)sbnL6QWEEyjsm_u2Ai_BFt{>Q<7*tCr)bBR zCnA@%+aH$bOJyiP`^#5BO19&XRHVAniVxmN2j@i=iI&yc)WlVWr!8m=7cdYqc`8vn zW5er;tTFQ170R^Eq-lrk@WPpv<8P@UUDJ*2Pa`1Uo`=BHJO|vkEyhbpM3fz*B=D~f zg&67!K!n4Q?(!cKz!}Q&G3GIlN4l%H`>k_cT3y_dHiaIi_JRKZm+Mr|hES(2nK(&G z$C4XUZmA1NO44va9D_+ECp-$0nQ%qH<(0MxD9RQOBOH)N&b0#C{K30!#=Or{T>hM! z;)dl)*~PLe^QE;G6MgK54%Cki_4K0+E1{;{Uk=FjSqBPQxgYoU3P(mD*zc`5a7k1} zWg*lj?iCDsUYzx#t!b>6VvdORsHJW!VJ{T^sUGh$PdIu?7#dybt$qmibZY%!cV;UQIFUJ-Ci?}w8753 zb57nPXbGl^x4|k8+#)hZ>^1t;{WJJb9qYEZ$8d)pWW(m_ z`?P$y`~^@dkfYE6NvXxFsWt69*rWKOUYwt7vabEDY6(E5GUGu(>D@QEUo~g&psTK< zxZKoC`SPWDIN>SzbQKC~RVjH=eGIXrEU60c08(mkYU-n0*Ep!Wl6|q%Qa7AdiOpf+ zwMY|2v}XDr7IQQ43 z=KlcW;eW&b0O=fGoP`jsMm#Fe?1xyhq^?&tr6uLZemM3S0H~-aZR^15YO6eabuMxR!Yl*Q(sZ2thPNx7CB)}N_CYsSG@Je$-wFc zel=&nx3zO(9Q4}JCEo0JN|C^9b>}~jH1|tsJ4T*>n0DydZ7z4ao;~7<@r~T{I35_H zhLfJW=8{>jNROwoB{p~D1e=7#ZT|psAJ|Cr-Ph%|r6F6QK}iu`z&Qc`&%G!zoE{bKMufvIa< zu6@f0gu||+@x4a~`JO&iYx@I1In-@Nh=jHa?*Y>|NcW%RL)Qt@Zt~koTkqW=ohS*k8orlc_6w+E;WreG7DHsIf1Z08X@2Lemms?7bK}v>lDXf(Ojfaq;K8HV* z1k4NGEzL@0Krpt^j}8hwL7~`EoVLtNOVjcd8GJJ#E~o+MtRMV)s>NDU@u&;kt*6;= z7Q)z9-be1AF;$CG)9fkGoTmGjt`^j#r64UklvU10LVYvysJSc2$TM1ED3(+XKH zTii;!r%&u)XK&M|%AfaXafa4~1C)c1aynAUIO&dv_mUT%I*xg+xv6JUjI!OB7)f&Pl&1KTLU;0(dDHLsVe~Fbf%1&c80qVw_lu0$jg%Aidj-f z1oQ)-rezLKb++2&S?lLoYAAk6TWuTNQNRL^tk!m5#0YgMTZ$gpBO~2ixYkc2+b5z^ zlyU8LHPiMqv;&exTmeIGfZ&gf5irp!4YGo_4@8RQEJvS=r&~&cNCid1)Q=%nWrIyM z5umq|jPg=?tKNSq>!^6><&>p1LFw%@3C3d46P` z2jH)rPU{V5&7DhuZ9-g{kOGMw!&w>lnyaL~{P`=9E!Dd6&PtSWO?aQEd7P7h==gp$ zKT(M^!bs`yqJ1AJm>0I>&fcc|kVqLLXghuxIjBYuQ&SeW;m1>6RzD_qzZQ1n!x^t~ zF1W9?Ig}WVCB(WyQc`^A<+LTXl7xNKfRXMMRO!NtYe|w$!j47;Nj?J}HD^I_=dJ8J zA+XcSKvK{=4R^+GBvg(*99;@IgH2pP86uZby5^8sDjt=Z2-(GFfyFm)qz^1prxFx7 zrg9PN;EakC1|YY2=95x^=~`c>G?C77njA$H+C1wi9m?{orZM8|@mkGkCn@Hz*HBC~ zs={kotP^L7=QW~hpN#_@)`_k`=dEa(#-n74(KW2sB<8V+?KyCEEO|{d+X~)6%ZS`Z z1aVN3T5!6xgea#yK;oa;_MxS(oy6neQgGjn)w)A&C^q)}$a4pA2dK_?9|K*v<0pn3 zh{dHQ&@P`^dj<8!dAFN5TT2T`^#?zdb2Ox^o(jCjjUv(ZvFTiK(=Fc5c-iJ6b*>!7 zxkQFg==UfCQUSq=u6q}|8;56BoU1EgDvqyBq=EFs9HriBGE~HUkNeD~xKg)L30_B9 z%=mSs0HTkx&TGg0t;Ad{Z+T#ous&Qud;nLpKN|JnIj=TXq8&G+uX=@GS#6I#jNrUR*2lePkIt-Ab~fd<*k|8v z30j*WPDhM53H`5Z@^CrecvUVdwihCu*n|wM=jbUl%LyA$IQa_n9s5UGW9g;BiwTyy z#Am!n%9MP{k0!kDIx6Bzb%#f^+K8d*{3AuFc5~mjr237);r2eh1e|mBM08LjZW!D`No|5Cz2OyJ68LqDhUQfoJzR2+k zCi$lkoU?*fUf5=&T5fuh!c z)dnF++kim8z!aLuR|gp!kAMC%Owiy^2gaR3OAk$DiBATDr)m^<8@xI2q)OcgB(+m# z93#eyW$D=s6}R?vI21C{+D3POu4p;*t*2JY>DuBCBD0MJs`(@4L}o*7A#J5?FYh4! zR3_t3>DRELx9v_I6ge#u{=PJ3yd>mOAhh}x(}+rtuVqP4;X}w>G%Dic^Ly{aGKR_t^Mrqd;67X*;@KT2f^*+9p zOc-8SSHLn&V@CANtU=yfM(H^T2?Hc#1M}zUMzJ*fiA?3tLflYo2ptksaguy-*B+HQ zWzp^-LQj3&I7SItH*X&7jC>6h#fX@yLf&*b;xn-cPQ)W4k_RU^@g)6g(3WW8Trr$` zo3>QdsMM+zwDWaT`2c2{9hHq{}bg9c5xGS zZY8&p0a6mQs4J2Wi5?ylrNVNfA;usd)&fxL{s{0WPnx{Xhf3p@>5el_?kws3>T&C3 z!P$ceyImwW;14$eAY}58;qV@04;r$ha4HM2J41G@2@pQs*%L{SN%04#(0ypOR8?;! zX&LjXN+~*zM6vC1eDIBQ+%RJ9>&@_ZiJ43^rd%Z0Y9|yNdFrtLx2RF|&>C zB#K0ga7HQ7Ad`d0;<-{m>sV2?Ybjptvayd6ENyi|&yiXtm6|Z(2=x?+uDPm}1}@Qr z*Cf^&<20c*O>$LQHKSN2^Tl#cHHNfkQH|EKTCD?E!|Qv&E~T|+3OM=GtHL{ngIkhD z0)mpDatO%j@99xZ@JaFpluC$cPJYlh9+ld%xnkhSxKyl7c?W6hT0*d}Ym#}T6ah|r ztB?68dJpBfIX%xU-DNB;mAAaJ(-0B0xD?)mYb8l`Wtow!Y0w<88Zj|uV>Vrt2cJs}&^ zGLS%4IRN#c$tv-&zH{%{PDH)V!r5+=>4I(8; zZ)&r}W36spK=;(rSZ`=J@UBA$C#4z^#<1h4jPrAfixfbOyrcTs8!dzJX@W{{7hF_BEnNTXoInT6$Np*GZc`bO7oDEo@t%Ze1>AMme-Bw1fLp~?EcFR;)iC5^76F!eMb6b!ptZ?F93*anif+!Wm-uc0ySmJ+F{MM)rL3t7+?k zNE|3II-l`*4@$W$c6iq2LYxT727Ho%QW2PLJ9}DA2Z`}DQ}&yEoaNo?Sa-XIfC)l4 z-;w)A$K6oPnPP)c=zLgSSzMTGjbRdf@AP%8LC}CpuXtb&+4JYdr5Ti$x8os6I3V@+ z)g5VZapWb|7N*=!MI_*gv~)1)x|FC%2aZY*6ezfD4ML*MU%$8z?*7vGKN7@UY$is zMvR$720D|KoMiO)*DWC`I3tRYw#99i`^NH;K?DQA@aa;<_?42e{+B`u)h*oRSXzp_ zLPsCUq@u%B()n(-w4AC#qd4_H`J`ermm$7|4`oFNKH_uv3bA_>io?3*H+b4rwGNc$ z!)O40HQAdyo!|iyAh>IA3+^5~1a}V(!68WS!<_)Z9rF0s zt9svGZ`FR7o}J#Eo$2ZBU-!R-f9n82P=&|kQU5C9Sg2^j8e3|Yr~#HXO53vC{OTZGT?*%|K`c|sr{485x5cw=WJ$nMYdNsL6)bFQhucx= zSy;~;TUfqza7?}TPQtRz@{I|ijU~!u3QE69 zdhXu&pnPEwr$ds^Pql}6{LrQoe$uf~M}p?$%jgN(7CF^74Jlt~G(Ja9@pc3Gnzk6*}-sY#ba=+O9#)Ne$m6M zC_76JK*mzwM7F^?KQzA7=ST&GHdr*iK;+eKJZ;9#qP%<*nO6uv`a7_|4-Lt5;V2z{ zWz=RC=(2Q2FLjdBgMhwPTpIrZx`yU)LK1p07=pxG9|C)Yk|n9f61P@B_B0X_*|I5L zOJ#4Zc^MQ7?^Nk+F)4@LD2HgR)&WG*oUC?jumnqEX>p$Y1S*Sv0M31K5qumpyT7x5 zgliSl;UPHypAfDV*hmwSJ+fRJw6zb(pK8hCXW!tI#;S zwHFyyk#^o$L~%6Sgy%9m2Bp+Cwg>zJyeR_Lwk+3~lUg@rQY1+N>%?8<$iz6SEyNdU zN3YcQa0?7YBg&EjN+4@+afkf`M{C3r>cNs??0B^+{LD85Z`?Rab7*jbb6b>=d*Qp@ z1M787?%3a^9)<3?%K}|_r!*<5SRP!M%&i%||87=wU1d_m-bep|VSkKgB1)o)8e3g> zMcj}T%OaQQ5K1N@&*!fjZq}NEYgD!CY`pYyBp*aVE@_M!*tuh_11P5Hfp1QF&^%2N zUt9AQ%2bY*toDrIJ@K0F@3ViQn)Rqh=W)Yl%jb_>`8o0=x0Mc}Q@((J2uVI_ZED_bUv?7AQ^wwxm|hpi$yAO+52o&F)_0@{ zC^yn!o~gj3xTia<`N6p24)E@aSb<~rN_QSaXDiK-gdAyaR&MUh*2uD%Sre(tA_~|V zs}N`-^(g>T!b%EDW?;}Pg5Oz)866)F*aodh@G%(sd&7K42bz2MW_d{Xeme^MaFp#N zlvTcnL@@h1@E2Pbhs$!hYOj#PVTAX&1Rzsa@GFUB=?aP6g_CHZg@u!?7xf11c?w}L zU|ZmdNo_lxX8-sJPj?Y8g_=k$KwG-V<-rUp!Go&rzWfQ_!93teHs{yTFQQqnm~P6C zaSJ6AiiLDUt>e$8uX0(zhrd=J4*C*U#(NErNu(2X#|{KSG*BQq*mijZ;vrS5h91*l zo2w-eoT9-g6eOZKxg8ms6p%exHLTZB@dV+bXf1YZI>GZDjL$#J=1lUCqhTB&+B(na zNC>Zq!m*|d70R>e;@qT=5T~{mNnbusvTTulwYWfVscJ6*xPjx6)Yy8{A)}AV3ms(z zI9`cqGeMW|h0ZA;vb}RLL2$fQ4M;#dipdJ9+Ma#gXKyB8w~&JZ#5<`D=5cA{mfW)% zO5)Tx0#SC!|E!J{?{gnQ5FS!N8HxY*dp?{J3AsmtTC_x-PuohV63yH=PrS9sIEaSa$)(K5v&i6ZRt zaBzmTU1jIX%+`NnE89x@6d9ta|FwSSNch@2pOb4~sD1_c$2J>m=J!(qDp5>C{$!Cu zxit`Vp6*icO4amSE+`MVXU4&z#Spb0?=a#U{O=eH>tq_A&ImR<5{wsmF)|mx;b+6b z*v}aRSGPsmbN`(l6VKZzAGNf!`s;n$Zbs$EB9haV{a)Hg_10||zLe#c$uws+1Yw{4 z+S^tD(ng za*3V~bs@}Fzk*AMmVOmi7rKYpn`m7MzW$YA(q?!6!=i7jI(z;WqU64Cd=kP>pj`JE zbvTpE8~L+By!&>5BIU*q(w{cm-lmfk-@DT0D)(#`&^aa&(l{X*`UyeM>gJO=jyzFt zEAk{ex`WTqZrVZCtmUG01u{?qe;Yf0FDH|I7r|D0=QC-He2bBMV!;?!HQ{~G~sq&>y-wd zQUF?>LZ{KdYKcwQ{-PQLdXx?RjWg=tDY)I+)Mb#uWYzb58R~{ zs;&19`}c%uB<=%b<`Vy&;ow2cS{=0Bx3a;n10*(rBHLEe6wBW|sd zd`zBaRVBeJ#XZ#*e`|c5Hei*SWqtj+<<8c>pikQP3z88*4()KBPjcz(IB?nwO(fJq zwa0f@uD0-7L7xAxeKfw0hsvVoKLD%!^4Ftcz@_9hlpQJn`Mos}ei%CLaq+oH2Hh#o zDkRQ88m=c8b+f{UP978=kGg{k0k*NAaCvmnhT;3 z;D!lU_uAevN(h6nH^E=qM}4Qm%M|`exxr3RJTpDBT>NT7;4k-`$}WT5 zJZD@BcIx(VZ_s+0pP6i)3Q%G(4;FHlb`C)EV0}zI{4lUIOuM!d^INADKxM%&$ZlL( zm^_T%nx7Pg z7y0Fdca|1qqr7_fNS5PA&XKSPewtc8U$sp-9yc5~{bA)t%ODAiYB3`hs#LOL!6i&0 z2X8TqB3M({B1=OnMpI8If|>06`;h}5Dv1;}}@aIl4 z+5p|bMUTjT)9Soo7d3$qs}J8_&AW1Ve%yu#728&L-Ki4iNt1$wyOp)vohT39Ic<}P zconQ~?m8@g0NJP4do&HYpJ-TY-1N@-k1@&3HGcmXqBZXVc*vvr+Kn%M&~(s;rlH#A zI3k3Pwjbp*JxMJUUl2hiQVBoUv?-kci$prHcm)_81?gKui#Mudo-pxmGV`YH3y=n# z{f0;&j}>U zLoX|un#5sec?!ACiwB0Wka>ymjzTma0z2mo3A`Z+jGHI9LTJK1L+50Es`@Cv3AeM zJz!r6RztPlh(~FRz@t>D>RnxS&th<>rP75^%Qu%I#`2YZwM4;bLkX4HQe<;$2VC@O z3z$GqYus{%TS6Y{iF11CHP=v?IXaefK`grJ@M1vq~)P+o_f&(gJK&)0&EHB>4-&rL^SuOlnh5#fwXORRY zabTj^Yj4-1SxPlUJ{&xuMAw;LQDd8Ftx3eEu#WOL5<{|MG4Sgx#QUf{Prb8>>yodlMxTL?$4 zZ2arfjAPWo=Xg$Yq_%p*NtCHOl~%bA2Jz|hr+XM2*r9%c4~SKH$S0^B2&8+U1?4CM zyh~o)P^q`QXCbj_0WOz$cUn9V+?fr7K{tnGkfaD4qC{NHI;k%R1mF@5ZC2A%N6V*( z9YN)4x_NPbib$3_AxXJ?W4cZI@MDI+`lZrWFqHPVHP_%cb-&Vz%sjMNe&X@|2ipj9 zTBHJT(I2$9AicFkT%i18-a{08&X(oV@i6dlFdn!fhF&@RI)L%Fvyz-O0`IaB;K+TX zkK4K5LMA{alDOr72UvvKCO8R)`sC?&M_nt%6lMk7EHX1zFLHf}0|-0eYN?~eh7jy$ z3*Lc{d7ICVBG!za;`uj4gRkHQW?$&s_X9@eCS8IZI)@+U&VO95KsFib-EpAD!w@>~ z&j)JU+Iqi(L1Im5Ldojf6#>dT>hqYL|=O`ZT9U(WCarBsw`T9%gqK4LSbFQ0HFVhCIP3;Y7S_22qe!7hhRGbhkLNe6Bs z3Th@Fcf_?(^a-U;Q?E4+G>lUo%V<~MRJhI=TPXbpSp2G0)0*Dcc$yZV)0R1Y+{zS( z$lr2IIP0V(jON}Ip2E24_%+GepgWx?+Er%uSxzpteM<5K|8>b%jx^E7?A6#VOgv5#C3cXx_9UWo4hF zjufmLqIZ$kkAGC0q8#=04tx8@J(XADrbc5z-6Il_Lo^0{La2I*_2V37w=sMafc3q8 z<;-%dDdV-yhV~^>wT~Fr%B1TFKqueLisW zdo^_#>2jg^SI^do%o;26%Vx8V`6ymIR>}FwCqsoR^hOFnlH2z=3_OMLiyuGb@XuVH zDdB#7%Bp#&f}Zs(V|mn}{TR0s3W*(b^I=rC>B4I?oF{RjwHHD!m|SJKPYEV(Yglh_ ztnFV(5Pu@733|O^YyaZ28!=zs=rw9@*uVRr%&Pk|HyzKJ^Ks;j^gloW{yI3O@`D^E z6jQOl(DVvzlHQ{cMsUx-Gj^151Y0Ae91fP?RnFDIF=+()1yJMo%OD*pB$lTR$Ca)C zk@sAjuD9cDym^1Qw82!Jj7y__;9agj*0mXtI#Bm9c$!uZ0=@F&XlE?&V-h(wh@{sn zU=AHm>VeJG1=L>O3vE`ogbl}Y;acJ~A@QiYkxZxo0`~F5)4j-BlLSu$Xreb8_pqc8 z<7F!NP2ck4WU#rn+nB3-y zTf?968EMgSv_N_Ap_F7U$6hG0v6id4@^;!t|IM8BZ4H0c1=+IGeT9zAE{*V>%yp6h zlvy8Fti)c zQew}lS-oNZq{hvhS{lWu-}~d)|fkBp@o_Pn)Byvl768x#}kePsQUhmGa~( z!M4w8sY&B~`|&DM;tJwPEmUq)B#dT}KXKgiRBRA_vZ$0-?hV{`mqVMCDgy8rB0AibmA?j| zlH;}nz5_Q@Y84c`l+AfO0ew*f#>y}8v~-QHt8co4-aP6pkf4n#@3s^MLO)&@*tu_p z)6?ml_D|382JWl!bPmVnIFQRt&e!`nE{UlM1a3opjo!1>TODiN# zxfH{U{tGdcK$XQ}yr8l6v2W4GJ=FdOza2t9Rbfo!Xiu^g%4F-lm`IwU6DZ zZ`>x(AsuDa<}G%mVFM1)R-gr?`}R*SgHCdb(O|-J>!cbYG~$|t?N)>c{zoZx!#CqG zbQ+G0=q@)t*Ai{ikyo=_K!X;n8#rx!XdlS79yWFVkf|O7&yvthW3gfL%6TbVn+DbAg`m z%&84uu;C23HRGqyWD5FnuC}*Sqc>4X#rwky_QBw|FNIONuWa<-26yt5M}#rQe{KVl)_tUl9Vb!FpTRG zBT7))yR?{|1AK^VPJd36cV5~b+kuZXPL*M#q(rI8B@L;v^wA!Rv%kcApXlB2L?oSQ zcl7#Ov$V+>5%0o%5#>c|V$Xh%rQNvfpl&VW6o!aA3QRFZmq(q}q+bB?S%cwzx+AXG zYl_$_0Ky(SDk`xwpjUPjM0ek_Lp zOcQgZ-v)=~B|8O)`cNc0+9s z2E-RJl7ojH@;K=ZH!jh8s(c?x`U@KqR>bgx&ecem`bwq_3t&RIS8x<P6iowMa(D38($dD=RkS`_;G-74Wg;VSQ{Be>N#m_iWN9J(a?*{$c$o z$5cbTngqJ`ZCG*;^n*{f99Xwuel!STPN4ZOPrFLec9z_z$VF$me)B)O(WBZ|+Znp= zK-?{vg$H$J7RVX0E4VomG?QDVvy2?ul93XBx9_bl5iiEEMPhJt&X64YGmS_jMui(R zA4ci_fu#5!;MKf_hvIm&QKm?|{CRAV51oaJTyYvMoYHC`xXzz<;wLC@`(^FC>kmTKZAyQ0ksaCm5g-?@JO#7x}vH^On+d0lU@eQt+TxB880<)aKrwc*SoWXmx-K33p&KR zb0NBC&RW4KH|TdF;gRL)4Zvb7tEHd{2)&ICo+IXvw=l5fGj=+?JoBvL_2=fmnq5R` z>Rxf$yPApo5;0FVAkvI^7tox(f)tQYv*O~Qg(aBJwV-Q+NB;Bm3O++A(Y*2u(PTkI zDxS}4M4v$jhtuK$SRK;a>hxlflN3hm7&!W}dB+twMe1#+tw^s+P)H{A!ZxAG1#GntJeA>N9n} z$<79w9;rpfXs~c`LXFVUrJ+A=+Z(KHT#&joVXaF$%WE93xX`>zw!6p=9L@MD4_T5j z*LGGr*42T75&Y0&h3I(ovb7cKY?Q!ZntSNGOG)b=IPZZuHfd85EL4^W_l2M&g$j;L z>;Ct(gCB#pKXbEPdpc7?KaQLcUz8e@djBj> zoSA2HC1HbV{$0glAQraCoYTE=Us=D!ruDOzK2l6a26;iMWQ7MBD-HVB!_KZ9oZP+kTZ&P>Alrv}YQ(|z3}@O!AEFNb#(eSTVrN_A93nyAtxKbvyWfGMs&G1k`=I!Zvf39l zyu|s><9ocQk?6KAyj*D0Ay7BQI!AD1=8D|69%{k=E!IY*`*g)$`}e0V;`g(4HAQJy zA$^PlnK;XlY99I+Xd8aT-43H!)LmC8`5S*eR+k669(k^G-6CI%<8FRT3*A`JR35R& zzk935YJo+?)n=ei-2WA0Y0fs$LJ-|@06T8X&L99eg-lTKugP-ge^@^#LAH(!Y#jW+kXk=~ewr$mBUaz6GwXgOZr;Do`G%AI#--7R4@Q-8OxfnSP z6`mX*kBrywOz6prJ#O%qO}jQ95(pI&w!o4_enV72!O=IU8&eB)>!%cxK4uNy+4<$R zv5Fcmy=BMMKReoYgSA>{sj%I8;SdSLb!v;5JaN~JwxYn(v(DM)_&y7Nbn0>|Fz<*L zWLZk?NxT&b1#a-wEZVjKykDC{V{GRQm0OUnth6FmcazJClT96Z9fAA&MTl~c zzKEJ4k<;K)ifrnmibLuV$)8+2LwBrx@7TA9$?K+%{0&hc{o_uS=3pUJ2Nkqez0KP` zay%_8%~a7Q)kTjI1=t9Ij}BF)tiOSs${uqA(97yC9IvQ)?NK2>-~88Tz1=(rZgJI&b$!0PzBT< z{AgSrlPbc;whO1a6ZsdW^UhrJMt&=LM0edR*$$)O0 z+tvj!m^k&b#m<{Oy!V*Fj+wk*(+&OGAaTnk?pBvKi_6cJwTR)-nD1X|c-h)))7vf( z{=~Q6$@oYu0KVA!W{EN6hGiF4-9XfiIx_^Rwd@JG=88!3Iu z1-_>}6PYUh*zjb{clzCTH2LFGD;!jF+`1c<8-t|ucWOsBXhl-R5EGX|6@IPMmH zR-0D1TOeF1o3CeUBfs~=&i1|h$RLkXpZKfMk`!AMMzU1CR>6n_e+bSqGRFGKimD9` z=U|6(w@~py05{a4D)r?XTW=ZPszmou*K*_A%1)^?F^n8ckRMaMMJJyjYAuLZ{>?5) zMGE9}NaNq6uC)5Rbf~zO@8Fi;bD?vus%0L;uwVsT)XCBv3`MZ}d^tjnAB91uz8Nqw z@Fwg^TVxV0vk11lzRI>Xl2j1QH?-JzS(BJi_?gULHQX06k711Q^hGyQZ=wj2Z@SAGm3%XxA-7^s2q{^1Pr+iEb3$8&Ynb;Uk z`||>ud5E*YMuiH1-r^BHtqIK*!l0~8H(YHPdVmB;oO$D#)^P;48m2hGl(Y;j`2mU5 zQ3R-b3g{SDAYITk3_I48z@WQ^ycZ>IX(`&bJ z63mtWKmmWJNIq%HCL&cn%>>qYH(ZvG9i`v9XaGX^GEplNt5ai#x|O6s0Etc=NIYQx zBqZ=fratOcrkQ|=G&M%VL*Ch>#ujhb&BBsy+sWn|+cm8@PmRN{o2swza`Jqg2Rv)9 z(LNoee{I@L2e&#{p$mQiOwyFM#cz+8V_%T#gJ(-*xvSrQo+Pgm)IF2i+yhr+y=EVg zt#)nItplrKjhLSqr*Dl}aB~!xTaL+^b-J9Mi5)Y1{hghPJNuayayL{}PM)=CY!t#C zn-b8QUSBt=u&QAWIjXq(zz%waZN!8WYP|ku79-A20h0l`pF6y0i093C-g=ZCDJs98 z5FO|?Y{)eobF}OjJS57VLtz5$C}g}c#Cy!UC>-|aB0=#CCvgvTG(D0&Url>=7I`n* zvu*B~Jg}iMJYD+@tqaRjVb9ca=*+zaob&oj^&ddQU|RTH!ElLntL?;xdIeX8>y-{7 z#_&dR-#FqA{1))t(U@q5*w8PwaRr4{o@8PE5l-T@?9i`&Rh=(d^S~oh>C&2XUW`Y? z9vg^a#Vz6nk=TpVT|)4R=s&=?Qx1$Od^Ug~j8_C)o*~0A?^I;ku%9X8QdUzB94$|h zqh8w%V{O_oJ#3ZTwK+3-%~&ZM@U71&Y9qGD_z-X4oaOsS-Ra`3KW4{wvtw+b6YUs5 zk^ItH^0g+=3q{) zTWAQUXR&Mxh0Tx1c7!qp*6II3-c4K|{6%+L;l$Glh}%y#|5W3(bQ7Mv8$Z<{i8 zqFt`ry0{|Vvp(fobt$%=5qOf@F_DfMw9(jB?}mNyEN)d=JM4IObob?oW%x|a-WByu zVdlQt@C5_c77l-<+Z1}E?M%A~xI!`UVZ~EuuP6>wOtRANCagrlk~sW^WW{NJs6Z~9 z1kj8L+kgnePO@>VdKP(JsdekagbGZH;IL?rL_|Q*I*gKV-99G)01)qH%*%~m5t7a` z6=K|Y-KSCZIuG1weXBmnkaQZN<(dr=XWS4c#6vP-c}dPGaAp$+xT+dQ1RO?lmjOT} z*BXxBH`L%{Igv@>e)6{%yCo69b&k9msIDrcbwQld>5)Rtny6H5G9oFEc!wz(-tA&m z*w;!94jbxMdNI>%I=a3MM-hFAQTtl+N8cDJdkFA-==^F5 z`IS1L7#0a~)4#A9c(V$zn+%_~J780latGR`;X{AQT9CfFfXdCS4nrjPtX(OGxZC;u z0UGWt&6CGF%MWC5zpnn-?E>T86e=;kB(}W0ul{C6CDbwJ#Y2EpBUeizSJ4n1QbNPj zEY6+6ShNoerNJv^hGA*hTk&G1=hIqHvYds#SPo7<&qE!hGAIP9F1B!w1Z zp+{}1(RAhrz;`^Oq@OJ5n|hlwzCA_QJn&*`#C?joGgy{|V%%2%AHF}l;bH#%j7H=#D zg)%*O*Zu)m;pF~dM#jnXp1EiK#o95q*p~a~uEsg=uAZjO>mh|NsF57F zQEX;u(ZoClW$GwxP_BN9@6w=@9M+l_k8|~jWrpibtx>rZIF5#IkifWi{lp}v`lRi# z6iUPqslP~~@8q<^H1AKn-HtBzPD_q5EV-+}xy5j;e*_qSwzsE%`+4dmVW_}8Z23d< z+ZQkYRPtO55;k5wbUN2CFhfwHJ+GY>x;bvCGEA^#IW~;c$P zSpB17)q1Rud^WwkUqKStw4BMgL_GGbS110}pEj+yQ8^iTZEO^XP(hwLdYpwMqjnzN zL;{Z7G6uaIj9N=VzFRmzGum0*k30ZR`v78B&NkR!4z-Y00k_iFV3c7lJ5@Dlz9nm= zDT(;?^0d2d2xV3&G|oH``wWRTK?TM$Y>jQ#N(VbiFGEH~(dB-Y>~!i@9J-W%OI@i@ zV;%%Gy;jm5mexEk|D?J@IkFJtQ)H}NOp_kfMvczA5H%&1(nY7u1tv7sHLdcZvy(^f zAVA@GeGR8sPHdq*j2luSgzMIEz>tOw@v!m;gTQyT>8~R=T*f*2%AZvpa0{r35b7U|`*D z;BkxQA-JNn2YCQwxxA<8Ih#^c+mDQ7wTxgY9COx(CSU)pi>=;&6h+_5iPD_gIjQ;>%CmSF zZFy#?!-R7YKJr`&*WwY9vUEBb^LK%S=r7d+PTBRu;cO56`mh-Jj_VgF+i(batqVauCuP4#~KL-mHn z_d_{nvwN?!dvS=Y;G?x^^&7so5tFs>62u^%B^sZ1!RxB#ev(Hol9&w`uVu`0MB`Vk z3L6T^;FCXYZscAlUA;0_Ek(TiO=8=+2BHL(c$^LD?Br$t0Ny%#{h!&fKT98nk)+EI zYLRrKiCULk*xbo?9K);xJBYQj3e9D|z2}E_@0oR+@aVW#AGUtknM~-&{IlI&Af6U&K z2O{OOhNc-df3wk;ESkBf;~HH$Ln^p0U;0f-ms=p4*!4g~zfh5mdOBp?F>9D@xus;D zWC_3-f}uG*Q+LgNMj;TZmGFIh3Cmtq=jyYKQLLgJc1GC9ZkSONT3%w2XGY@Je+^ae z9E4EJ6;;+~%bOu=TenOIm4q;%-yu1O*$tBXI)CQaQ4RXCV6uDLB9h*+Qhf`_1L#OFnK@WBs7XW!^8-Nde>lU%NsxBhxJZRcr9}AP&_+lQ7qJE&dJ}>v zSdtxz5!4#(t{7aS1LRxFlVt(C zZb}QQ>*8_1#OlRIhnt{0Y z&#>07WEx|_sYH`5nd?3?y$8O|>yJi;VevS^eviGFdOXjwpV$$r!uD&A%o7E^T?CwJ ztJMCF%uRS(XGEHVjPLvXrP!&xxddSb(_x+bgc!0JSIA{zxqL#q)FgbrbgM| zC_ov}wCLfRl5XEe)C-(M^{(eDdtZ5B{p==m;H%&(y_hvVg@pjiY@g>d2VZ%r*3cTG%d_Ktpg8wls=80N?|9YHXs|6aP{76l2@5o_`U6^cyDU%#J$E=i`&*j{H1(H+X&aPMAw;?B!Q1)2m0py%!4WZB=a8|VjC{({A&M_zwh;pEBWMPf`=5_=qE zmog3yH_oQ~(4V(Uy~Y5M6@WI+eukh(_ACbIPIBaMh3<+AAjYY#IP!;^;@&?IZX+bm zYPDBI?G01DqhJmEVWX`&=+g|qfTND8C)F_N^P-brrsP8;^1!{E%NPKgM9yhsBrud_ zV=WPeUl1Tpk%0RB#SB+Q?=A{hfuO(C5-1^aA~S&`IExO0m*O*3*pnayAt#!6D`Ges zG<@RR_|SaS)gjh=|*- zJj`oWJ!5%|@ZxHVYx};bGpFW0XCAujy7-Ad3VHeafXww?)IUJ>t0~Vq2O%_Vv3~%g z!Yjk)bgTv@i*1@Anx`Ry9BMGXV29wZc-%_~6Gf+|s^j6!?uh3|BX@%{UM}SBn8N48 zGHZ?ClG@o13wTi&jdy|bFc%CED(+<7)ZD7)1p*~Fq~|{W%y!i>bc4>tSIYj2jRU2M zP2kFc-E&#)mpYCObdGpr@V zdF*$bC6f_{`%;IDZn?mAP=&^Qs+}x3p0D+~jQES+FG9pu<$BZ$^O=sh#0MAYBIUvw zLg^$OdDS>9@F_~kVm0e%d!N~%FW`+KR(SklUhI4KH6rEPu9-k5T(Q>_L4QQKjK)x^ zdIkX676Ufbu#(-t=aoYkl--MJ>Rq3hFzd;!(T$aMBbh_L?X`0&i@#}IpMf?xM?d?n zOC2wHf(@u12gf3<*?#$3^>6!r&=jc`+M;w-OS9?#V}>W@8}H}E{Fe;*b4IGipN(g4 zR3B8_b0kqKAd2-3K~{k&oYi-8gZ;AMp9I`dBHn40E7{42A2EbAMD|&A6%zAgvfEDj zr&on@A@{PetVni!EKqii{MNO*vuvW7j()WdAZ)*ilFsyd>xMoTiFL@v*kV zuMAT;w#A6FQ(-u72`{GjxEtyOc-AwTB7TJU|BgI(6u$Ub)L<`T-Yw$)W_r#-fULM; z>qkh6(Hw7#7--4K3K%Z%_z%$E@F96Pt-K}Hc_lXY&Cv8ji?G1=$%6fNmv-troM52=O(=S_!V>Nu68?P2tSipeL zp<8HRix&eQG2g@?lRI|7q~!5HEqoF=o-Yxi6|*bEM%^vLhXJ(8#6t&_6jV;<1(uCC z5(Hku1@cV!io|IECUoK;wSWlFI%pjxP6L($NdRUUXk9HZU+M$ZG_)dF{iBE&DY&=(OGr5o)IL@bxgli8vZ|cgJAeb~O z0Awz;^eRw@$56_imXO#K+`dJKGFxTz4|iWvQrd|1Cz^NEv@t36 z1X0>myEfKfFD-18hsJ)B(zZM~`^D+BU_Xb@7ZmEAY9#6D%HexpGg2{qV$}Juc`m+O zw%5?g?|4NrOdHA2`IOy;9d_3yT5@KvwWy{!okNindusDQfI8&X>gnc50nfCYH%pDj zO^Q4f*o-?2H@b7f_Auf6bsezoyd3vAreOnHk z5C;CNW8dL_)Wo$7uei4jP8}D17e{xY-GgAdP`&=1ny@;i7nH%KfWaFKUXnAkr z(3o-rSSve^3yPs$`f+b)XIudWw60YpZR#Yyhof&tld0zyGgY#z0E-o7^wH$O->fiy zYa|SlGBZUKeQc-NEc`p5N&#eYsxIg`Z2KEYCp3^af9_wljdAx<6%nobzPP>XElIHJ z0?u%6+cZM~X1u{<`NnV>pZRUIWO0@Z+Z>R8BRc(rANR;_Mj9@&x`nGlF*~pp(?uiM$ zd?#%BN$+SWEA`?tAJV(Csh9z`B``2GLzsblRs(ag9sshYI{l{8u=kGF85m}^E1^bO&WWKK=PIQC4>ujSsPi+;= zWl_m8TD-0pHeAOUt2hd9GQCUTwYq<6JwD@{vuP8MC~mMot`fwF4h+E(V*1L)+X~U0 z*s=9y&}I{5wd1bir?F*Ca-L*y>p(*JdhC)>^*jZ>*sELZ7i$H@3>jC0SGh)WX9og` z9OwyD=~-|_>oL$S;k|{ZF|;Uz?i!$ZI^x>>Y$3ZTQ~_E{PIY}|@d%9wN(mAXh}>&> za|_r}N?tq^F5q3#^Ez-5srZk4wZ(h~AxN2ix)Ot)MOuK#rx+BJ$b|O+#w2K?Myow6 zqwf{qHzMv+V7(enr)7q4f6udK;dFGow2m(H^>^jMk!HNA*6)5vhLzkYjEFS7HcgXR zm`xfz+%7_(NU&SDm#SM_IpEKYrapBejKpa(B(X=fV<{V_1PP9byq`IPpPr1P$-sD& za;a{NQZn-9t=k(c>s!+!ucP|&?*!JKAD0ZdmN3Y#S(t6-TNa$|vU*irQ9XFk)4^d2 z1}-*z{I(izx;frEh<%u9e#2;$F~(uVF|bj-tBZ|@`kW)JM^+w8-a9Q}hfGL8`6UsR zL4Y05gaiI{lQ{o|+Rs=3A6fkU@{|kqFLzNPvMGz>Ux~89W1a}nkCD5p@^PVuE%9o&`8l&v%Q$+t{pU8(6N#9Nr8D@CEXrp(^ukT<1O#27$^l0Wm z-^LSpbSBmYT1g0LOkQ;ba}ik!CinaKhBZ9}UDoXE<)SZ`on}vn4JL2?xE5RzV)yvt zvT5q~0me&+H0w6;<-VHLp+6VDk1n7KQ;l*rtc|%$^dPhCs#~LR2W|7D7AX7m`}zo) zxT2j$4*vYwrU_0@$uJP+Tjj{rIEO;`a;#hAH}?Hm!(Yk24Q5dlRQsB~Q+WYur(5V$ zs2AnfaLg5w8+ItCvsNmtmY`?BN}Ljf;KuXHc9@a3~94gc$Jell0*2m>9Uts)}NU<;&X^C z1fKM=qozb0Z*oN=4`uIU530Cg#G1S1#d}F`4rpa`RsR4J`|O8u;$yl6N^9sbi{1GS25u-67C@AS-tjH(d4<4nSuGNn;xpm>BI|Zt+xmaZQ=ZkK9xwT7}CgD z6N8O0{A19mqsWng?KVV%ew}Sn7TCpnpkBbK7+mIytL4vfm?wUu=i!K5{2+l{ZB==Z zzz_x3G-d$f`A*$-+h*!Wq&`W!6|KP=DLXO#4@y*{&pr{l#Ibmk)V&>heZ6X|YiS~H`j ziWa%Q8JhePg;)+8?5s*hlOkK$Pdnl)_*#}mJa}01M-%v4 zAbI(M7JO02ubWAZyNPLV2594v62%R7Wkd3zojH(r0>EP~G(;sECcxHwhq$xHD*Qr{T9iEs9J z#e-eebK1J`@gp3a^vsU`0G+B_FNnBVdZsoI!O4zHr-n3_0tK%g62JcdG5-MkOIyNk zbNpqc65?whb2hFIY}NHhv^^?({Fc4(z%9X>lCWFxH%B|WA331!{{RlvpB|g=KBv%z z1NyHNIWvw@yY8fe*&FdMLjadIGy&cp{Z~PvYgnEj(_5W@USM;JM;mxf%je(4&f&sj zG(z?7g-^c(uyI&!M1d^9*#d14Ce&d607Ok8MMw%D?usyXNE8y@$**)E-spkia2?75 zv1u+Qe~P+f8IwT$KQiHam`E)*N8KUuXG5xXE^AL;m8bmE724kE?)fe{KZ>3ocjj(u zJ>s=E_?_XP2NqQAzVJCPbwMIKb3+`hk~T>jt*;zSJ;6hhA!ZcrW4K%*achS#X+=py zbU$R{W#JI`>%@bewU7uky%l79LGddHBUgF!ECpVvuW@PlsSz|i*NL;@SBaZds7B-K z2rH@hdEH*ZqqQFJsv?*NAZs>r}vsHC)7-T(OjmzNFCFX18njO z%?HL((Q;_J9<7~q-WBmHd{?6WK0Ie*4>ZT+mvM4KTcN;!M)$g6@S_H-RaZ{SpYczP z@jNGyjSgNc)4L&sz{EhRKBziEP?s(r{{YpUB!S0+p5DBgQ4fmx3EA-HGyeedw8}hg zY-TaG_=O&U#42xSX&?$7yQ>q(_g53P3cQAiB&{-@JVrhyzm7(e&udB8Tbh}ad2xKI z&Md%UF{D@m(B#b0z}B{pG!z^h(pqZAZP7ss<-P%6deUctU16?wu(fMXEo)^GG>f9p z;YeZ;jW{IvP9v>uh0J(6#_)N5RiHy|+WG^rr5w`mG*jG3H&%j&QaX=HNE+NL@o2h^ zX%az-_r~&R=U|-pe^n9|3^^V_t(7tA-wMbc4F>o8L)UP}+d|_$9BFxaZ-tv4Y(^)( zXFq_Qz+IGW<+Tq@*DLj?nj>;>SfXD*^Le$HzGkm{{VS?5iV{v8;9aDBaOiF zF97f8yl=*S41SX?MyNF$NwMdckqaGC0(V;CmCfNwM8}QSLdEXAkKtteehG+P&B%~` ztH<=cJ0mgV?lLNz&V`fQ@6vrvgY=4MrjUQsS%iKxz!2Cp> zMtJj44S55I8vg*5bAuv6?c7bSui`$5s=vlrnNVr-&yOi-Y_T(l8ffge<_F!DxBz+9 z!B~~l{62Mf^G&`+M}I}vd}C|BX6bVP4-Btv{I?5=@C3kk^GgGAW+Q)P-h5s^?xYSQ zc4b$!g0p_Cc_ZE(%ni~UFRK6md4&j(j%cTI>Jx|j#B=mpWfn*-$|bFN1Cb52HxLaL zTupRc@59U}^R%4bF`)T#v~Dh}1;lExej8TGglr?3&HYw%KpsU?on4A{&BEf>56rPW zD?TGL4UBgNo@-+>O2~>Pe#+LhXyh-qws+G={{WP8S)WD!Tri;aisTWcp9!Wxtr{&1H_n#B)1TSu)c4RKBU zpc6olHY=w;4<~P#Ha>K2g^~H9+ip8uE$8?XI$N0JXf{RgGB*G#*+ZtkUYj^Y20U{X z0!>8d!EY{ZptH*Izavu~es^&;FSlej^K)G`xu8Rbr#CJ5l0%a@c=Drv6I)!5dMi5{ zN{=EiS&y9e5IDTJ`2PS-YU(fOULSt3qlu%#hIYjvYrlM1AwSZV9#jv+%aR!wV{~pU zEGEcZuY~nXUkzi=kCz5`5=rI`JZAzFGx$0FD$38*blkBNEO~sRA|lQJN3S(y)N!0- zAIwm={MJuSWn70%^YY9w=VLSheq@f}YrU1%cv~VtQ0D2+9Jb16zq;0Ib2j2C`1 zIPXoxbAbCUv%&0&7qbpX@@3+XkmHQzhLhg*U1pHxL#AU!?5No+aJ8=Bm>M80Av~^# zvAJ@(H;Od-1z^`R<6jNUs%g>3iR3im7d}U@gTe^wOU&PaBPS4v@!sMrJU*I!tJ8d0 z0nxlCmo}E~!#U1ikj6J~^ zjhXKy&OG`qcC7yZ999>B^D*+A{Hz>YmVXOO?u-NUTKFCr70Q*O@jS9+;S4XsjI2DSaO6o7?d*4; z>OEHlsrWF!*$yU~n(#%j!bXr!sOG&UEbJL~k2e+f+D4T-8xxJN#Ov%rm`d{vKf%Iw z@Z@Rwz#wypk)8ghl8Z#~hO6PYCBf7Droh>p?ir)EUt3VT8iwU_@}M4z&jHLQg-~Lf10#DD(Y~CoSh>Yk1CLhUUBEh2j(gN023f@ zJNhew(xdpoTV`z=Z|+UH>-;I=c)VAp$(Ig0@x*c%%O36`SAxEGI8gw4uT}Uy@Aqpk z6R^s^(Mt!Q7gI?*nhD#U%Z-cT)_^7<@#e6!kbiZ2ms zW#wXHV+m%az88W;^s890$t&7Oe*T~p(lVcq8N^haG>wwL*AmIdHC7!;vGY0c0)1K& zT!2w*WS{OTt5fGm7y=yJfNP|uWgbMb%MLuVOC+*7GB}>=CW?m11el}Wrvj1F%3)&* zA}x$i92H0_i5}gll6t#0U^Ce{2ugmHA-sN#UQzlG6AbbE)m4xkk<$^=t<&<}T74)^~6 z)SnTsf5*j>-T`Y1#G3wpiRXfCN6HSzVQUOb;Re^W;j%HWk^~WM`6v$iyY^S z^tg1bc*Bg?+Y6&>niy;@dU5j$tSW9KefhnjuZ&{A_k;U`ED?<9Kl(Q2?yJhuJ!|23BksIwZP@m8~xU z+y#|=PRp?IzlL%h;e6dghyvJJ_hXT6Y3+S!W0bqAGaf!SJ970=zWDvoGG@8AL=Whb z$Z-S>tD4&{OZayH&+y4<8$&CH`L2!~IyRE`fY$?7c`j4oZlug?4Co|qX%aQy5oGMQ zwVdIRkOLe`0J`M3c{z3V>%)(4PL=}`BMcI-^fdj|2TPL#&Jg8Hzz-nqAh~lOHD7gW zOwTQRu(-LyVhJ}(9xpd*n7sUXHGeNo$J8>8Mr;sd&f!K$S!AlYz8t~SArVgr^1uUy zl9q!?(9CUftKX6_lGCtovb}p88IgE9LSO=YHc8qJ*EQ14)O-nnE?b|bwYU(F01soH z;CtP!oJa}gH$-1tiB&bqEIJ&+xam%~e=WI{6 zs_u)nqeNd+iz9yKHWTci|+p_-^|{@5P~i%4J<$1btB;*P?}bb+*XFXzs3;hSo)F1(lnVc3}&88ra=Dy z^i=UM@I+2#P9~)*%@F);!1_}4lMyZix;NkR#L}gUBO(o>Zaw!5;r@s?e+qb?NAS#9 zSpHsk^WGlj&d?ky(v~ixr(t-P#4^c&sIwW_4>EsgX9EYJb)xaxq{#7pRFbp@1~3}- zT;Xkk0ITSttw*CzE^N5*&yHOac+1@-G2h`mRdI(SvReQxGC1%6Uv_=eWVmb&!+Jy> z;0Mihw&Lks9;M+(rNHp)7}>@+=8U*km=4yobMkzwQs~^$;y@Jb!tvpgBOPadVnXbG z9^zr@GS88hjU@77y{?Q297ohFa+bew0vL{VokxR0E1fg4E&)p7B0<;MHE-#aYz7Nzo|ZI(2Xb+szvA&w+@ zbwHhsESdaAre!!fEcl2Qu{B89lN6wsvLb!$v%=4l%g$VpcyQxqwf1MV@&-AwFdeUs z!oL&bh}?5X!`v(G4CewWF5HOZXc z3uz2-aMIxi(q{#JFAeC1FeLE)Gl=U~e^oO`a5O<8!KKpRZ;1(@4+_n-WOB{$W{l@t zdIU{8_IrRos@uWBpH0IU*f?-wKn;clTGoz2_LIWq(W*NVi-_@6e7*ar?OacfW1M(b zHJKrX;}7{oSIoR_Q^NCIcV6S;(p{kDurRy(GmhPNULP>B4{#Qu0KBH-Jga2HCLNZP z?sz+mm!SM6m-l*{XP9#xOU~W-yDsD5M5Vf}p&#=?*L{kKUc(crCYrkglHz_a#vkEa zNk5Y+iT7z;n12Q{O*rf}Xx(z36$*`8-Vy7vc~Y$o_&&|?hW+R#qM-b3OIb4mW_=oJ`%@S7sR@3QK=CF6Xb3t`KR zkAW6Ma>>Sg$B;o;8svHymKSJw*_naY=Kdxi&JNz{v{^C6&>Rl^ka|QP7@^>Ea(q7L z5({ma70fR)kVf}C*7k=uxLCTgYRJlj?MLjG99I%aqI>M73S0w~1?n2ejWyv_=R>G+KJ9Gt4fnix0DqycoyKC|6C|{n0zn+hBv#bk7cW zrhPXONHqL8ppquJj%@TpNZP{J&Cny#FrkxH)S|@5lp2IY<79LWOGbg8u&`VkASMP` zYtLnBNSh;R?~s5wJn>iEdGCwIe;p^2l>K?HiFGWULrsaN8dkvBi4qo)!bfA(b4BHY zVnwdU;!LlLKLQ3zFP7Mx;Lpm@Wb_*@S_r0*q_yNw2YuIWGI5z0w|&)NkpA~bhD@Cu zy0menvPfw@tx?GVZtjhq;4LB(koxCo{P#Jud8aICZt=8wgGmMg2kza!XIMd_;h!!3 zCc_gkvPK+9X>EhIWxwM%BYrM1#K4Xs9$fPaEALB`$C0?xGG>SIHs~Hpt?;*sv~410 z_!dueR2Qyme%)pO;?muY2gS(#&wnkks-bW$``*>1>UlYrk&+?PYDO`v6*$#8S? zp>%|pG2Y8>u`8P(fk&p??Q~^l@hv1C8cb)5js4Y26qPCYa=Fxll4!ad|I{0N+5M0*=Ri>BtTg=7a9D zIa%?%N1yQKe7A<_x!9A!8$s`I4aoZG30oI8vmie~oE2!|+tCS;VUT=%x%+lg_4AGbi zgZ}`yZ8^`2DseV;m4TZr0mfUx^`#!IqQ4LDvuRGog!5pG78~|j)W@E9+c!+ryg`kV zrAG`{@(|e=$oN{?cQahs$LB7j9p_RkpcyGko6vHPMPMN{L5a^s72vTM1dgC2=+Ga~g+lb@W z^j?h3c1T(q9A|_Ir#iq){{RqXJWyjO?YOm@c;Blwe0kJ0khQMdkN(P{z?G+w2I!?=pK_~tU=c)t z@{h7`!U*}S0#Dr$=KeP){ie+(_H#zx;au++J;7VvFemojU7I1`ev6%|2+)Zn^ZL>* zLz_tVQQAZxK<{OGhry81g{wHw{p4eQT#EAH%r8;+I^xYURU$I;=CDxfu~V1DdN3e@ zMN#a$!{ZEho2SSI`~|kXI1*z8&EOF@cRGyqr=~xg^ZFx!U&=^Ni|-{tz*AZ z#e6ux&LxTM;)sXUuQt#4KjJq<8?mBe-5W;}TzFR%7F77=;mDdIH~A%Vf1y`k@jkbT zPm!zVFuP+@6MuEA#8%ccY|Rf-n+rHbCWB{)o*o7IsM)4!1+8;%@*dZYCcZe!#dq8M z(Mg{)t#Fmhkht+V&uy04k5SWG!-bIO1yw}y+eKzi5sAb&JQ2^0g|+uxN5d?J zMdFvW(liM%+zq>(D94X=YN;h`qNs@&$KTv3uzYsxNsPlx!E?x>n!@;t7m+pq{46jM*AilH4;Q-Q9bogYx}O}+EYsl$ zUSGn;Rjyg&0xa%FCF9^(m;H$+~ULX^{t>LIWGI*<1!tjwF{N-xJ51 z5!Xy`<1p?ceen*$mqFsq5aD=wS@is-V@T2olO{mcf$!a7$DOReDm_8u4&_IvU0HeazsbD})K9?LUepQ5PH{7x|<#{R8R381A#tU!tu(MpQul9|{>OuN4)KE@pc(Uo@D~MDy4Z z)zVgR&;U5DfHhX6Ee~j;R6(`QV`_QNoR?%Uw2(Mn%B8UU;|#_#9}ueq9m;Aa;E}B* zr>FU%^CWA!k!0Gc?N=Rzf=)Qg%>Y|_tFXg7C*G zj{KGA^c_l4D;2`}ynv^V!r5=#?tzuI&f>4KsgED=e4*ODTg8y+hxAwiRu#B>T~2pHhi&5D@4}TTU*nr;I)5;{{XV3lgQR^a-xZjdz|CI2_L}Tj(4C{T&Qq% z;)qUm=#h!@xz2_!%S48X04FVP%w=SZb$qrcDgyUjrSN!>rRszb-`_KH$ZS`aQ5DGF z>b+m!#uIaNT~s*O84MgGUF=k&x@o9DFXP+ucU%X==0_wFkkDj|MB;jYy({))jb{ve z1)xv^U>61PA5YZ34U}1@IoN_0m*fCQ73{Nv$t52>j-f_I{FJf_0E5gZ)_~eXl)aL! z;Q*7#E9Q|24qm5Z9?hYNXYk$(!-TZswB7HpT?Rq_0I^~xtu9Z&`OTBUIE*w)7+FEy ztEtE*_AEf1w&uD1qcNqPsBaaHP>>Oo+G#f`z959jrtS?e2-+W)iu!k&L2xikzbn6Vks2h zr-&cKMMMV|wvR!&5K+OtOhdcc5PP<>k*R995#ZyDNT73CCVT~?$}4a?1J!x1t>H5S zvKVwM_!_}&dmrWp{{W)u{{Ux3(hPFQ!T{&GHZwX8_!-Xj;vr{IAKhOw)W~LJD1MHC-p^nS_wDa8KBk&&Q8@Iq&{TF9}o8Ub|5+f$C z>`aou<}^5lhjpu7GeqA|Qx;zI3g>)$FWA)O%6`2^#-0_>@^s(YI#-CJ$~euh!vGxT z+38DyJ{_AcCMLrqaR+Qn*4B@$EU-9DfI%INQk9u`EFUgRpnr^&xhENsEw}3aZ-q4s zI9TB9OrJIU4G>NoN%q-hNrxmec`jiySZ@H_-(_K%o@8$h6I+MzIe?=&oTb6?W5D-= zVcZ3-A5d12T;fdwYIrgtfAYQ}2p!PKG1v%>UONJb+jXx8i*q59jCrBtaF+>qi68R< zt)Ca?WH#f&izv7AGE8>9y>FN3mMATZ{_<^XN4X#}iI{V(|OZ-^%RR6yh*Xx(!!A)t1;UZ>+9 zh29|4b+_hX3|XUaYZ}2P3yJ!#J=Od>sA;my%$#R59^Hc8fIyP zOx#JG2^J&_C8z4D0mS38htW{=z4J@iA~--K+K|HF8%_kcSfyY9Xrcv5{0U)un<;A? z05na4q5y=V#-FyOjbt zg6Dl)YB|?C-d(5)icX=izC1-b@&-V=m7d1IhcV`;CVrBpvU2QCPn)H_ z4$45<0M^MC14e}&t0Bd0M(H>dHyqFy$Rv%@10&Kxj*Oq{;X9Ia~L*1 z!$28WYy{ZdoFpy(01SBEUk$|g^ye5GG2(kq%+g1?^?CderQ|e+vBLTqAg*7;KMyob zIv>R3AH!n}oihy* z?i2^6>x{(1@Mbhmo;8y7>>xqh73qp2!-){uD|9kJx5@w zJcGm<9$u9w#mbAy%7E0c@mrgGxh#-e)*d2SeMK&>U(+>QZC@?Sl`ut<~OP}vs z`Yc?G+1*W^3IOqNmTZd6;&^XE?v13mwi-!CBiQMS%RpfumX3--%r{C)Uig}501eUz zrHS#^n9|ZfJE3U#yDOiDV~7JSuN5@&fU|>^VLU*c_xdj;*4XH^?A8-}GdNgY?Ee4>OU68$mL2&$w7f&a&^sT+dYm#> z6nO=vm5~_Fz9JBtPVxhYCv@FFRY-S8l!!lM$fS|yvVND*H(qEQDImYaL+bE=4U@)8 zC1Zy+n-+uFuccnW2?N*#Q02LrOEO3ff0n{;mh`2`%5Ezf_X0zl8@H1F?|}NNpX(05V(BDWW(Kc zU}50$D1kN4?4csZLX`o?SF#Dc(jxgNh4dvZGg}?KkV(tYBj1_;^VlNduz*d`uhn)x z3o@d^@ieA+%nft|adWlDU9Hat2ESfxZzKmW-5M$nY9me0A3V4@Kl|94O4QP{+jk62@fZ_gcigRw`%!a&#`RppWA z>lnZo@?PW zrmLoCdgMidNidv6aYq>4WuF7%j915xt+rC}TsaJ&716?J(_!O3i#rwBF}PI+aFO*| z<3GXgg^|BU)EMAD;xjVI`-)qv@CKm^7%*ki-0&&xE-nx4vE-$T;r6AGAZ~jwL}Y^F z6KIj>nq!xkcy3*zlU0Zf{(cv#c^LQ`{u?pxzCuX2O7xd}FYxQhA=%O2PCKO={u5}< zAjhg@Gtt87Gjuvn*GhhOIvWQ)7W~Bz6+sKqO^l03bft#=7<^tGTPF=&R#?6|Ex> zL>t$GlA6c5Avw<4nhEMjpoyGZ0Jt{NxM z^g$yW);fjkR2kq|?woS$K7?+sYM8Z&;V%Pb(P=Dk{t0ArX>Cj3>?dgt$I}c@G_bXgjPVBjJFZ>$alNFG zUdfph@H+9b9~ty@Elz3Ge-q)xBOwvwWJ(?n=3%Q`?z`dbLrBY+n3{e>xQ^MgM0lKi zN$2!i(QDeaD5D^iqxsuv^d2=WKics~zv7M6`W1U7Jek@?Q)dpB6Edt4-@~2Nx9QQ& z?iT48oJW;LTm4tBWB8{|oQ^5vh25lY`K@SjVa#YTNgTlTAgydijNtq`$lXmazuU{c#=5_G2)9UyL`~h2lZae?KUZQFou)VY*8~s#SR3Q0yo&wYCNtF zh8`ixo&lWfd{)SKKqraAZhJ2C!5#@`gf$7z;-sDVObu<07H!XN>r*x%q~na^mRSxd zFL0FDAno^AZSnS(sxk1j(!%g+Ig5T!`Zc)Qe^pRfe-kwLHOFb#Sg*@`PN%<&HKw`n z_g+)1;OZLYy{c+>ns!8(@?^Qi%x@59xmUE$25MTaWUR)|#bmKP#mtjw04LFU7l(A_ z_$Nr72}F~>EZhG8cne>(A7Na|s_<;M9~{8Fv<~2n?Fl?Bux!^w-Rph`IeCtoML5{_ z#L$7I&j5~Ri$b?dGmll!3Ru0sKk9!;*!T}qCM#_0IB*<|x z2A4SQM%Ji=az_BXsDa!Uv{!USC$L#*0X{Hmb73zw(Ds)B&XHcS_@j~&6Pi4-0HLr7 z9Y!Y0hVCNZBO$`Q753-&Uo4L!TNv+gpvl`u^;hTczC+?7DPo|8Y{O=2Dk!pe#;K}$$GkF>F0BEl_bY+q~j%fw1BYt}oj}HsOWpwg$ zoU;{PDac6P!jez}s`n~7UW{@v=4d8GM!6&cfOqA{Btm*fQAIT;N|VwC0Ig3A<;R7s zM?A)uz)PrErI-}BzwyWen@BR$Zg4V=_+f} zV%N0Eg|j*%ea$OzWJNHzawB;3e>LRdhcFYd&SQaVoYFe9)g|#mUb*uSENp(L3~@Q% zG)yPetIhFzL#g4P+~!C?o^eL^VRO;yZu3Jo$Rj1#vU5@AOsZWEEj(>R@xNn_W81m)DKP$)|%6h0(gNzvJkT^Tn zb+6&`!=BJN16{{en-;MHnnp`QPkOLcu8tu6p%by((${Wi-5}`+A;;MXrveBB9^%16 zERnSz#S7F;6Naq zm1p>^&c7};wEFId={G$S7d3KjqT)$0 zW{!(wuzRA5%nc$&eMaibGg#sYX$RWEvL$1MSU$=shy?6^RHb1Mzj0Jmz#97|iBV+2 zMmxw914@Gc0mMp)@R1%s1QRK+J1IxzDa{~(?LUggHTgrV^yGz)a2ZYp_#8;Sn=3xZ z3mWFUPyyF<)dYTj3=lcO%%lyu3sM)i%rS%W0mM)~0Omr#Xhh&e^`wMkXP5Av0~iNOqJM62#NP{GehGtmElgjCGqu2GVX@=8 z4+&W}N1Y}uYsTTG`->{hRwg=3{{Rr^ek9VR)AMJW5tE7}j$c*Hx8YU}L}Xz2mG6k2 zE)SIN-A4R4j^U&p!9s8gO~)m5{#CB&)zx@g!BBWcS*L<&vgVb%CGXf*vJV)xe61`T zOj7)kOB&!W%LkeI@>p23F8g4!e&m3-hzjz<(#mt{lwjl9FnKOr*9I!Z! zU|9VW*;v{qh#(Qp_;Ok{0q&;{^IGi_9$(_^XEVej8Si{jh^+jL4XaS-jK>%bk2ez@ zM;G0_qQLiE3wxgecFbB+!9d^GR6Xyl;NbU6c`njH%Z z&hW`x4fZRepWxw|7R#qOqMs~<%D7Jfg3wbtcuze=1tkR*Jo+!*}WwlX$QIu@y;&Um3T z1fT9Ek2BIf6=&vCwMpZ~jE&=syiZ=Kg^Juf7%`b;kuWe5xuBCX@vr7CVfAXAvqb&d zD^I1WhhZ&vE+&Bmc&5AH4SOF}%bA*cr^k|KJ&%RK+Y@}3w9Z`~ERse8oYvSJ!pE0C zDVat%b3C^)iF~nJ4e#=fqtyq``mP2>ESEGdVPWBQjz`r~XxnqJUahJ8H=9@2Cz>5t z0hsdn0~knY^#^KJus#pz_~ac%SLKj*uaec(c>Bwnus=?T7m#-VuA{_$43`sK&BxK> zntXg-9xg6zBwr7%%bc4X&^SjlZ;jwtYuio=2!p|JyGL7D*mFSUaPMNfUg*oqh$nId zD}hkvH%-4zYTNR0mkz2KPaDY@335UJ~Q(&V#bGe%HYxI-Fg)8vlBy>7=<<{9MN9OkCytzxW({#6J-$Qs^SuG zASUn2ZpW_3F)}26rJWPavLevI+QRd?E}nrfKQ(ksc9VZGL1F+n4*gW2%=0)nhaF!J zq6~3uceh^wvFHGvUaq5MwR5E=~y21D8>G1v|O8tSc6{Lx%I6iMz%%FoNk z!qrTfP;tjATG2CIyFQA-r#E(&F~0ulDRZz%1}Ufkd+v%kqmYj-W;*&^6|ENTHh@4S zNX)|BgE&XBkISZw?35*rY2MHlOU^?JUdGY%Sec$4Zb2@Mz!U1W+gI}+p;89M`U3CK z2L+dMBDNMRdv-E)#@ZpthYw!=+;O6*|psKslz9`~0UCGRdL?xkjt8$}VzxT2<`my1ew z2n6yRfVFBZD(ad~sa-TUtYx1ohK+8eF|=}Mpqj37Eh)}*GCDo#m8i6d2>F29vfKj2 ziljgR&?%!gA4_W;b-3sPzaAuEzm(sqoq%%$ZPiK*je#fGK?jjQkwAMP5tf=e`)sWi z5;+hP2srk2*KSIpv2kOpi*Ig3A(JnU8dipocuvJ!7>okAY#sOAN0A2(EVV!e9!d^y z0mM{7Qr6Dr3lS0k3Sd5Bh43-)%F%7}F38;!jDfFXNvB8&2&fyQWExSvC!B~JDwrGz zDmIee#kg49kWaD+`E%r(`Y43XW;QW9nG0G^xGGLCX7cRu2Jw9mF#*jW@*sm-U8v;8 zY?#6!@-!Ba*O5~K4 zup|I_Y@ZTWPZ=)&7QM~e(MrZPH@(diTtPL}1~da5rKQ|Jz0cd#0)}?vLL_bQn;ZHf z1UaCz*gZmr1~)~5#z@{54kJi(@BaX8fDTkg>QGtgnyuR;mr^<)YU$M?(bRpDkPh{- zTi>Dv0FF+tbi|R+6X=N~0v-oD9^oPy;m8sCBCWfjENSQg^w^+@_>nw*Qaz0*j-COw zKF4A?D?9{pJ9ayzZWc>!x`a$a7DlCoycrUJKb7_s=sa7W2?BWIm=2}9C-hbL+x$d} z9d=Lhxx3SW`m40a+Q#vg8^IY6OA)?pJV9yWYg&F;0xYQP?ZWfIR~+nETt6)zO_VOc z4mQ{Q2(_unI=vx-hyvPh^fs(O+BQc1tIT3{b`!X_5Ib3ykDgYl1y4wJ1rOTovEDOy@Q`AxKw>C@b;9AAhy?;*K(axnh@G;ZQm zb)7T9UN4`|$ehEJMRAvKIQ{lpmNSeg{v%{Vr?PBlA}(voCjIenaQ^@gOYXWq3V6Y~ z)|x~+J_1-;@nm+Tj{g9JT4xD#I+jc0JJVbUKV_$+csEYbU~?g3qM-#&e= zq?q0s%+a`cn54Ir#BDtOE7I{XpEg8}W20erl;KWwbPEm9;0F+2Bu)mnWqX>rt#3@r z$km?AJb2%YAOuO~*}v{< z6JL%D*UZx^Wpw~!*nkw#Yct_qxrzye&}1}kK=74~KZiAaHpX6+F>U^4Z(n8Y9u)Bm zTBd^o^&%k1vIu^~z;ZuTydcM&pSyD&Jql{RX_taG5a{KI_Iqd`V}*wYT@ZF(M`h?3 znGHU6JZ}eW*bT0KQ21w}W`chP*xYxxj|oj4Ld`|AINH|$C=%4>OjooQHI>7{I9 zE4|J5Jpgfb9#ri9S!H8{wSuygyTs&0}{U9v1%q>bm%|bngw}{u4}$Na56eP*eI? zW61Tt3Tr+bYh9`07@~RMY|VEQN%vWdKQILEYq9a~idm`Rehv8sSwxL-V?QG+{MQs6 zZ8T|iBQ4xfO>lGZ(r+i>lcHia*f1o-41 z-AY2!69dbdwhdn_i{8QL5)qTjWod%90AHdoZ+)-XL0!1Okz<*?(Y6@)sB;_DD*%e- z5(lWE*#tJw>HzQ51v400&`3f?;PbA?f#PYQe(DG3vFd=d5^MrFDVrH^2KMX%a{(r~ zgX)5zV>)eJ2IzdE@5=UgY|kT48`*$%xvA zG!+?+7}@|5J91Jrjd0(mWNzKNiYdC#Km~&AbM;6HzQGY;;^neHSguHbB%2+S8B{Q( z@4!`p#|y4XzFTV!YZQ18a^hBrOG|(~l$U(AJ(gCgYG;sWhV$e?%)r$0U~q4l<}`GE zyq$F-!7t4 z`SLb7bF`^d((mxnf=MGHLC^cjNTz%9@}YHbL>gIMp#;S(`yhPmW<*e%6&*S^Wf1a1Kz zaGbO_?g95gVrV-8JprTXY z-aL{tjqQ)6b}tiZc)&ICi2&ZEW&Wr`$1rzD+l4!Sb#|E1gT^g*th_N_%)@H_KDVXh zP-M-C$D`T8xwm4({%xb&Y@&VuC*^$)UDfQJUBq=LxTIu*yIpF&MxBk5e~HA3Ps{cRxa&(ZRl*6|X}fEG%t;i-Jx0~GZDx9qh+UTWMsIWT&4=Bnw^zDYAgk1i497Pk5d z3f12}X`+TWc+6}KFL85->Qq#RZIWo-`6PcSOb>KbtYPvRJj#?FB1Yg3)kly201W%7 z78K{bQ7b1=E&N-FZJoCpEkFkucJ_AXvd_)Ne3KUjk_hN6SXLA-YEl0yMfcXlx}&bA`tfk z`UFwM(2E|bTKT!`rC?|^bWe2yM9by3sYVzYYz@0293d;c$0Q1`kgsINW6qOMaP|Uv8-ff@=2lKu2IlRKV@aW3oZOo%wP`0jjNn2%O$0YP}=kBx(O0(%YBdGkzP@Y#EH<8Ue&kYze z@jGzK+^qbaRzlE2_(k;DQOM47;~3T-U4
yuNG!uWS5825dk{6lAryb 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 + + + + 后台登录-X-admin2.2 + + + + + + + + + + + + + + + + + + + + + + + +
+
+
    +
  • + 我的桌面
+
+
+
关闭当前
+
关闭其它
+
关闭全部
+
+
+
+ +
+
+
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/js/echarts.js b/src/main/resources/static/js/echarts.js new file mode 100644 index 0000000..eab6a06 --- /dev/null +++ b/src/main/resources/static/js/echarts.js @@ -0,0 +1,90902 @@ +(function(global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + // window.layui && layui.define ? layui.define(function(exports){exports('echarts',factory(exports))}) : + (factory((global.echarts = {}))); +}(this, (function(exports) { + 'use strict'; + + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // (1) The code `if (__DEV__) ...` can be removed by build tool. + // (2) If intend to use `__DEV__`, this module should be imported. Use a global + // variable `__DEV__` may cause that miss the declaration (see #6535), or the + // declaration is behind of the using position (for example in `Model.extent`, + // And tools like rollup can not analysis the dependency if not import). + + var dev; + + // In browser + if (typeof window !== 'undefined') { + dev = window.__DEV__; + } + // In node + else if (typeof global !== 'undefined') { + dev = global.__DEV__; + } + + if (typeof dev === 'undefined') { + dev = true; + } + + var __DEV__ = dev; + + /** + * zrender: 生成唯一id + * + * @author errorrik (errorrik@gmail.com) + */ + + var idStart = 0x0907; + + var guid = function() { + return idStart++; + }; + + /** + * echarts设备环境识别 + * + * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 + * @author firede[firede@firede.us] + * @desc thanks zepto. + */ + + var env = {}; + + if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') { + // In Weixin Application + env = { + browser: {}, + os: {}, + node: false, + wxa: true, // Weixin Application + canvasSupported: true, + svgSupported: false, + touchEventsSupported: true + }; + } else if (typeof document === 'undefined' && typeof self !== 'undefined') { + // In worker + env = { + browser: {}, + os: {}, + node: false, + worker: true, + canvasSupported: true + }; + } else if (typeof navigator === 'undefined') { + // In node + env = { + browser: {}, + os: {}, + node: true, + worker: false, + // Assume canvas is supported + canvasSupported: true, + svgSupported: true + }; + } else { + env = detect(navigator.userAgent); + } + + var env$1 = env; + + // Zepto.js + // (c) 2010-2013 Thomas Fuchs + // Zepto.js may be freely distributed under the MIT license. + + function detect(ua) { + var os = {}; + var browser = {}; + // var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/); + // var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); + // var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + // var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); + // var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/); + // var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/); + // var touchpad = webos && ua.match(/TouchPad/); + // var kindle = ua.match(/Kindle\/([\d.]+)/); + // var silk = ua.match(/Silk\/([\d._]+)/); + // var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/); + // var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/); + // var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/); + // var playbook = ua.match(/PlayBook/); + // var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/); + var firefox = ua.match(/Firefox\/([\d.]+)/); + // var safari = webkit && ua.match(/Mobile\//) && !chrome; + // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome; + var ie = ua.match(/MSIE\s([\d.]+)/) + // IE 11 Trident/7.0; rv:11.0 + || + ua.match(/Trident\/.+?rv:(([\d.]+))/); + var edge = ua.match(/Edge\/([\d.]+)/); // IE 12 and 12+ + + var weChat = (/micromessenger/i).test(ua); + + // Todo: clean this up with a better OS/browser seperation: + // - discern (more) between multiple browsers on android + // - decide if kindle fire in silk mode is android or not + // - Firefox on Android doesn't specify the Android version + // - possibly devide in os, device and browser hashes + + // if (browser.webkit = !!webkit) browser.version = webkit[1]; + + // if (android) os.android = true, os.version = android[2]; + // if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.'); + // if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.'); + // if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null; + // if (webos) os.webos = true, os.version = webos[2]; + // if (touchpad) os.touchpad = true; + // if (blackberry) os.blackberry = true, os.version = blackberry[2]; + // if (bb10) os.bb10 = true, os.version = bb10[2]; + // if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2]; + // if (playbook) browser.playbook = true; + // if (kindle) os.kindle = true, os.version = kindle[1]; + // if (silk) browser.silk = true, browser.version = silk[1]; + // if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true; + // if (chrome) browser.chrome = true, browser.version = chrome[1]; + if (firefox) { + browser.firefox = true; + browser.version = firefox[1]; + } + // if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true; + // if (webview) browser.webview = true; + + if (ie) { + browser.ie = true; + browser.version = ie[1]; + } + + if (edge) { + browser.edge = true; + browser.version = edge[1]; + } + + // It is difficult to detect WeChat in Win Phone precisely, because ua can + // not be set on win phone. So we do not consider Win Phone. + if (weChat) { + browser.weChat = true; + } + + // os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) || + // (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/))); + // os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos || + // (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) || + // (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/)))); + + return { + browser: browser, + os: os, + node: false, + // 原生canvas支持,改极端点了 + // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9) + canvasSupported: !!document.createElement('canvas').getContext, + svgSupported: typeof SVGRect !== 'undefined', + // works on most browsers + // IE10/11 does not support touch event, and MS Edge supports them but not by + // default, so we dont check navigator.maxTouchPoints for them here. + touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge, + // . + pointerEventsSupported: 'onpointerdown' in window + // Firefox supports pointer but not by default, only MS browsers are reliable on pointer + // events currently. So we dont use that on other browsers unless tested sufficiently. + // Although IE 10 supports pointer event, it use old style and is different from the + // standard. So we exclude that. (IE 10 is hardly used on touch device) + && + (browser.edge || (browser.ie && browser.version >= 11)) + // passiveSupported: detectPassiveSupport() + }; + } + + // See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection + // function detectPassiveSupport() { + // // Test via a getter in the options object to see if the passive property is accessed + // var supportsPassive = false; + // try { + // var opts = Object.defineProperty({}, 'passive', { + // get: function() { + // supportsPassive = true; + // } + // }); + // window.addEventListener('testPassive', function() {}, opts); + // } catch (e) { + // } + // return supportsPassive; + // } + + /** + * @module zrender/core/util + */ + + // 用于处理merge时无法遍历Date等对象的问题 + var BUILTIN_OBJECT = { + '[object Function]': 1, + '[object RegExp]': 1, + '[object Date]': 1, + '[object Error]': 1, + '[object CanvasGradient]': 1, + '[object CanvasPattern]': 1, + // For node-canvas + '[object Image]': 1, + '[object Canvas]': 1 + }; + + var TYPED_ARRAY = { + '[object Int8Array]': 1, + '[object Uint8Array]': 1, + '[object Uint8ClampedArray]': 1, + '[object Int16Array]': 1, + '[object Uint16Array]': 1, + '[object Int32Array]': 1, + '[object Uint32Array]': 1, + '[object Float32Array]': 1, + '[object Float64Array]': 1 + }; + + var objToString = Object.prototype.toString; + + var arrayProto = Array.prototype; + var nativeForEach = arrayProto.forEach; + var nativeFilter = arrayProto.filter; + var nativeSlice = arrayProto.slice; + var nativeMap = arrayProto.map; + var nativeReduce = arrayProto.reduce; + + // Avoid assign to an exported variable, for transforming to cjs. + var methods = {}; + + function $override(name, fn) { + // Clear ctx instance for different environment + if (name === 'createCanvas') { + _ctx = null; + } + + methods[name] = fn; + } + + /** + * Those data types can be cloned: + * Plain object, Array, TypedArray, number, string, null, undefined. + * Those data types will be assgined using the orginal data: + * BUILTIN_OBJECT + * Instance of user defined class will be cloned to a plain object, without + * properties in prototype. + * Other data types is not supported (not sure what will happen). + * + * Caution: do not support clone Date, for performance consideration. + * (There might be a large number of date in `series.data`). + * So date should not be modified in and out of echarts. + * + * @param {*} source + * @return {*} new + */ + function clone(source) { + if (source == null || typeof source != 'object') { + return source; + } + + var result = source; + var typeStr = objToString.call(source); + + if (typeStr === '[object Array]') { + if (!isPrimitive(source)) { + result = []; + for (var i = 0, len = source.length; i < len; i++) { + result[i] = clone(source[i]); + } + } + } else if (TYPED_ARRAY[typeStr]) { + if (!isPrimitive(source)) { + var Ctor = source.constructor; + if (source.constructor.from) { + result = Ctor.from(source); + } else { + result = new Ctor(source.length); + for (var i = 0, len = source.length; i < len; i++) { + result[i] = clone(source[i]); + } + } + } + } else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) { + result = {}; + for (var key in source) { + if (source.hasOwnProperty(key)) { + result[key] = clone(source[key]); + } + } + } + + return result; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} target + * @param {*} source + * @param {boolean} [overwrite=false] + */ + function merge(target, source, overwrite) { + // We should escapse that source is string + // and enter for ... in ... + if (!isObject$1(source) || !isObject$1(target)) { + return overwrite ? clone(source) : target; + } + + for (var key in source) { + if (source.hasOwnProperty(key)) { + var targetProp = target[key]; + var sourceProp = source[key]; + + if (isObject$1(sourceProp) && + isObject$1(targetProp) && + !isArray(sourceProp) && + !isArray(targetProp) && + !isDom(sourceProp) && + !isDom(targetProp) && + !isBuiltInObject(sourceProp) && + !isBuiltInObject(targetProp) && + !isPrimitive(sourceProp) && + !isPrimitive(targetProp) + ) { + // 如果需要递归覆盖,就递归调用merge + merge(targetProp, sourceProp, overwrite); + } else if (overwrite || !(key in target)) { + // 否则只处理overwrite为true,或者在目标对象中没有此属性的情况 + // NOTE,在 target[key] 不存在的时候也是直接覆盖 + target[key] = clone(source[key], true); + } + } + } + + return target; + } + + /** + * @param {Array} targetAndSources The first item is target, and the rests are source. + * @param {boolean} [overwrite=false] + * @return {*} target + */ + function mergeAll(targetAndSources, overwrite) { + var result = targetAndSources[0]; + for (var i = 1, len = targetAndSources.length; i < len; i++) { + result = merge(result, targetAndSources[i], overwrite); + } + return result; + } + + /** + * @param {*} target + * @param {*} source + * @memberOf module:zrender/core/util + */ + function extend(target, source) { + for (var key in source) { + if (source.hasOwnProperty(key)) { + target[key] = source[key]; + } + } + return target; + } + + /** + * @param {*} target + * @param {*} source + * @param {boolean} [overlay=false] + * @memberOf module:zrender/core/util + */ + function defaults(target, source, overlay) { + for (var key in source) { + if (source.hasOwnProperty(key) && + (overlay ? source[key] != null : target[key] == null) + ) { + target[key] = source[key]; + } + } + return target; + } + + var createCanvas = function() { + return methods.createCanvas(); + }; + + methods.createCanvas = function() { + return document.createElement('canvas'); + }; + + // FIXME + var _ctx; + + function getContext() { + if (!_ctx) { + // Use util.createCanvas instead of createCanvas + // because createCanvas may be overwritten in different environment + _ctx = createCanvas().getContext('2d'); + } + return _ctx; + } + + /** + * 查询数组中元素的index + * @memberOf module:zrender/core/util + */ + function indexOf(array, value) { + if (array) { + if (array.indexOf) { + return array.indexOf(value); + } + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === value) { + return i; + } + } + } + return -1; + } + + /** + * 构造类继承关系 + * + * @memberOf module:zrender/core/util + * @param {Function} clazz 源类 + * @param {Function} baseClazz 基类 + */ + function inherits(clazz, baseClazz) { + var clazzPrototype = clazz.prototype; + + function F() {} + F.prototype = baseClazz.prototype; + clazz.prototype = new F(); + + for (var prop in clazzPrototype) { + clazz.prototype[prop] = clazzPrototype[prop]; + } + clazz.prototype.constructor = clazz; + clazz.superClass = baseClazz; + } + + /** + * @memberOf module:zrender/core/util + * @param {Object|Function} target + * @param {Object|Function} sorce + * @param {boolean} overlay + */ + function mixin(target, source, overlay) { + target = 'prototype' in target ? target.prototype : target; + source = 'prototype' in source ? source.prototype : source; + + defaults(target, source, overlay); + } + + /** + * Consider typed array. + * @param {Array|TypedArray} data + */ + function isArrayLike(data) { + if (!data) { + return; + } + if (typeof data == 'string') { + return false; + } + return typeof data.length == 'number'; + } + + /** + * 数组或对象遍历 + * @memberOf module:zrender/core/util + * @param {Object|Array} obj + * @param {Function} cb + * @param {*} [context] + */ + function each$1(obj, cb, context) { + if (!(obj && cb)) { + return; + } + if (obj.forEach && obj.forEach === nativeForEach) { + obj.forEach(cb, context); + } else if (obj.length === +obj.length) { + for (var i = 0, len = obj.length; i < len; i++) { + cb.call(context, obj[i], i, obj); + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + cb.call(context, obj[key], key, obj); + } + } + } + } + + /** + * 数组映射 + * @memberOf module:zrender/core/util + * @param {Array} obj + * @param {Function} cb + * @param {*} [context] + * @return {Array} + */ + function map(obj, cb, context) { + if (!(obj && cb)) { + return; + } + if (obj.map && obj.map === nativeMap) { + return obj.map(cb, context); + } else { + var result = []; + for (var i = 0, len = obj.length; i < len; i++) { + result.push(cb.call(context, obj[i], i, obj)); + } + return result; + } + } + + /** + * @memberOf module:zrender/core/util + * @param {Array} obj + * @param {Function} cb + * @param {Object} [memo] + * @param {*} [context] + * @return {Array} + */ + function reduce(obj, cb, memo, context) { + if (!(obj && cb)) { + return; + } + if (obj.reduce && obj.reduce === nativeReduce) { + return obj.reduce(cb, memo, context); + } else { + for (var i = 0, len = obj.length; i < len; i++) { + memo = cb.call(context, memo, obj[i], i, obj); + } + return memo; + } + } + + /** + * 数组过滤 + * @memberOf module:zrender/core/util + * @param {Array} obj + * @param {Function} cb + * @param {*} [context] + * @return {Array} + */ + function filter(obj, cb, context) { + if (!(obj && cb)) { + return; + } + if (obj.filter && obj.filter === nativeFilter) { + return obj.filter(cb, context); + } else { + var result = []; + for (var i = 0, len = obj.length; i < len; i++) { + if (cb.call(context, obj[i], i, obj)) { + result.push(obj[i]); + } + } + return result; + } + } + + /** + * 数组项查找 + * @memberOf module:zrender/core/util + * @param {Array} obj + * @param {Function} cb + * @param {*} [context] + * @return {*} + */ + function find(obj, cb, context) { + if (!(obj && cb)) { + return; + } + for (var i = 0, len = obj.length; i < len; i++) { + if (cb.call(context, obj[i], i, obj)) { + return obj[i]; + } + } + } + + /** + * @memberOf module:zrender/core/util + * @param {Function} func + * @param {*} context + * @return {Function} + */ + function bind(func, context) { + var args = nativeSlice.call(arguments, 2); + return function() { + return func.apply(context, args.concat(nativeSlice.call(arguments))); + }; + } + + /** + * @memberOf module:zrender/core/util + * @param {Function} func + * @return {Function} + */ + function curry(func) { + var args = nativeSlice.call(arguments, 1); + return function() { + return func.apply(this, args.concat(nativeSlice.call(arguments))); + }; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isArray(value) { + return objToString.call(value) === '[object Array]'; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isFunction$1(value) { + return typeof value === 'function'; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isString(value) { + return objToString.call(value) === '[object String]'; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isObject$1(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type === 'function' || (!!value && type == 'object'); + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isBuiltInObject(value) { + return !!BUILTIN_OBJECT[objToString.call(value)]; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isTypedArray(value) { + return !!TYPED_ARRAY[objToString.call(value)]; + } + + /** + * @memberOf module:zrender/core/util + * @param {*} value + * @return {boolean} + */ + function isDom(value) { + return typeof value === 'object' && + typeof value.nodeType === 'number' && + typeof value.ownerDocument === 'object'; + } + + /** + * Whether is exactly NaN. Notice isNaN('a') returns true. + * @param {*} value + * @return {boolean} + */ + function eqNaN(value) { + return value !== value; + } + + /** + * If value1 is not null, then return value1, otherwise judget rest of values. + * Low performance. + * @memberOf module:zrender/core/util + * @return {*} Final value + */ + function retrieve(values) { + for (var i = 0, len = arguments.length; i < len; i++) { + if (arguments[i] != null) { + return arguments[i]; + } + } + } + + function retrieve2(value0, value1) { + return value0 != null ? + value0 : + value1; + } + + function retrieve3(value0, value1, value2) { + return value0 != null ? + value0 : + value1 != null ? + value1 : + value2; + } + + /** + * @memberOf module:zrender/core/util + * @param {Array} arr + * @param {number} startIndex + * @param {number} endIndex + * @return {Array} + */ + function slice() { + return Function.call.apply(nativeSlice, arguments); + } + + /** + * Normalize css liked array configuration + * e.g. + * 3 => [3, 3, 3, 3] + * [4, 2] => [4, 2, 4, 2] + * [4, 3, 2] => [4, 3, 2, 3] + * @param {number|Array.} val + * @return {Array.} + */ + function normalizeCssArray(val) { + if (typeof(val) === 'number') { + return [val, val, val, val]; + } + var len = val.length; + if (len === 2) { + // vertical | horizontal + return [val[0], val[1], val[0], val[1]]; + } else if (len === 3) { + // top | horizontal | bottom + return [val[0], val[1], val[2], val[1]]; + } + return val; + } + + /** + * @memberOf module:zrender/core/util + * @param {boolean} condition + * @param {string} message + */ + function assert$1(condition, message) { + if (!condition) { + throw new Error(message); + } + } + + /** + * @memberOf module:zrender/core/util + * @param {string} str string to be trimed + * @return {string} trimed string + */ + function trim(str) { + if (str == null) { + return null; + } else if (typeof str.trim === 'function') { + return str.trim(); + } else { + return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + } + + var primitiveKey = '__ec_primitive__'; + /** + * Set an object as primitive to be ignored traversing children in clone or merge + */ + function setAsPrimitive(obj) { + obj[primitiveKey] = true; + } + + function isPrimitive(obj) { + return obj[primitiveKey]; + } + + /** + * @constructor + * @param {Object} obj Only apply `ownProperty`. + */ + function HashMap(obj) { + var isArr = isArray(obj); + var thisMap = this; + + (obj instanceof HashMap) ? + obj.each(visit): (obj && each$1(obj, visit)); + + function visit(value, key) { + isArr ? thisMap.set(value, key) : thisMap.set(key, value); + } + } + + // Add prefix to avoid conflict with Object.prototype. + + HashMap.prototype = { + constructor: HashMap, + // Do not provide `has` method to avoid defining what is `has`. + // (We usually treat `null` and `undefined` as the same, different + // from ES6 Map). + get: function(key) { + return this.hasOwnProperty(key) ? this[key] : null; + }, + set: function(key, value) { + // Comparing with invocation chaining, `return value` is more commonly + // used in this case: `var someVal = map.set('a', genVal());` + return (this[key] = value); + }, + // Although util.each can be performed on this hashMap directly, user + // should not use the exposed keys, who are prefixed. + each: function(cb, context) { + context !== void 0 && (cb = bind(cb, context)); + for (var key in this) { + this.hasOwnProperty(key) && cb(this[key], key); + } + }, + // Do not use this method if performance sensitive. + removeKey: function(key) { + delete this[key]; + } + }; + + function createHashMap(obj) { + return new HashMap(obj); + } + + function concatArray(a, b) { + var newArray = new a.constructor(a.length + b.length); + for (var i = 0; i < a.length; i++) { + newArray[i] = a[i]; + } + var offset = a.length; + for (i = 0; i < b.length; i++) { + newArray[i + offset] = b[i]; + } + return newArray; + } + + + function noop() {} + + + var zrUtil = (Object.freeze || Object)({ + $override: $override, + clone: clone, + merge: merge, + mergeAll: mergeAll, + extend: extend, + defaults: defaults, + createCanvas: createCanvas, + getContext: getContext, + indexOf: indexOf, + inherits: inherits, + mixin: mixin, + isArrayLike: isArrayLike, + each: each$1, + map: map, + reduce: reduce, + filter: filter, + find: find, + bind: bind, + curry: curry, + isArray: isArray, + isFunction: isFunction$1, + isString: isString, + isObject: isObject$1, + isBuiltInObject: isBuiltInObject, + isTypedArray: isTypedArray, + isDom: isDom, + eqNaN: eqNaN, + retrieve: retrieve, + retrieve2: retrieve2, + retrieve3: retrieve3, + slice: slice, + normalizeCssArray: normalizeCssArray, + assert: assert$1, + trim: trim, + setAsPrimitive: setAsPrimitive, + isPrimitive: isPrimitive, + createHashMap: createHashMap, + concatArray: concatArray, + noop: noop + }); + + var ArrayCtor = typeof Float32Array === 'undefined' ? + Array : + Float32Array; + + /** + * 创建一个向量 + * @param {number} [x=0] + * @param {number} [y=0] + * @return {Vector2} + */ + function create(x, y) { + var out = new ArrayCtor(2); + if (x == null) { + x = 0; + } + if (y == null) { + y = 0; + } + out[0] = x; + out[1] = y; + return out; + } + + /** + * 复制向量数据 + * @param {Vector2} out + * @param {Vector2} v + * @return {Vector2} + */ + function copy(out, v) { + out[0] = v[0]; + out[1] = v[1]; + return out; + } + + /** + * 克隆一个向量 + * @param {Vector2} v + * @return {Vector2} + */ + function clone$1(v) { + var out = new ArrayCtor(2); + out[0] = v[0]; + out[1] = v[1]; + return out; + } + + /** + * 设置向量的两个项 + * @param {Vector2} out + * @param {number} a + * @param {number} b + * @return {Vector2} 结果 + */ + function set(out, a, b) { + out[0] = a; + out[1] = b; + return out; + } + + /** + * 向量相加 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function add(out, v1, v2) { + out[0] = v1[0] + v2[0]; + out[1] = v1[1] + v2[1]; + return out; + } + + /** + * 向量缩放后相加 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + * @param {number} a + */ + function scaleAndAdd(out, v1, v2, a) { + out[0] = v1[0] + v2[0] * a; + out[1] = v1[1] + v2[1] * a; + return out; + } + + /** + * 向量相减 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function sub(out, v1, v2) { + out[0] = v1[0] - v2[0]; + out[1] = v1[1] - v2[1]; + return out; + } + + /** + * 向量长度 + * @param {Vector2} v + * @return {number} + */ + function len(v) { + return Math.sqrt(lenSquare(v)); + } + var length = len; // jshint ignore:line + + /** + * 向量长度平方 + * @param {Vector2} v + * @return {number} + */ + function lenSquare(v) { + return v[0] * v[0] + v[1] * v[1]; + } + var lengthSquare = lenSquare; + + /** + * 向量乘法 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function mul(out, v1, v2) { + out[0] = v1[0] * v2[0]; + out[1] = v1[1] * v2[1]; + return out; + } + + /** + * 向量除法 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function div(out, v1, v2) { + out[0] = v1[0] / v2[0]; + out[1] = v1[1] / v2[1]; + return out; + } + + /** + * 向量点乘 + * @param {Vector2} v1 + * @param {Vector2} v2 + * @return {number} + */ + function dot(v1, v2) { + return v1[0] * v2[0] + v1[1] * v2[1]; + } + + /** + * 向量缩放 + * @param {Vector2} out + * @param {Vector2} v + * @param {number} s + */ + function scale(out, v, s) { + out[0] = v[0] * s; + out[1] = v[1] * s; + return out; + } + + /** + * 向量归一化 + * @param {Vector2} out + * @param {Vector2} v + */ + function normalize(out, v) { + var d = len(v); + if (d === 0) { + out[0] = 0; + out[1] = 0; + } else { + out[0] = v[0] / d; + out[1] = v[1] / d; + } + return out; + } + + /** + * 计算向量间距离 + * @param {Vector2} v1 + * @param {Vector2} v2 + * @return {number} + */ + function distance(v1, v2) { + return Math.sqrt( + (v1[0] - v2[0]) * (v1[0] - v2[0]) + + (v1[1] - v2[1]) * (v1[1] - v2[1]) + ); + } + var dist = distance; + + /** + * 向量距离平方 + * @param {Vector2} v1 + * @param {Vector2} v2 + * @return {number} + */ + function distanceSquare(v1, v2) { + return (v1[0] - v2[0]) * (v1[0] - v2[0]) + + (v1[1] - v2[1]) * (v1[1] - v2[1]); + } + var distSquare = distanceSquare; + + /** + * 求负向量 + * @param {Vector2} out + * @param {Vector2} v + */ + function negate(out, v) { + out[0] = -v[0]; + out[1] = -v[1]; + return out; + } + + /** + * 插值两个点 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + * @param {number} t + */ + function lerp(out, v1, v2, t) { + out[0] = v1[0] + t * (v2[0] - v1[0]); + out[1] = v1[1] + t * (v2[1] - v1[1]); + return out; + } + + /** + * 矩阵左乘向量 + * @param {Vector2} out + * @param {Vector2} v + * @param {Vector2} m + */ + function applyTransform(out, v, m) { + var x = v[0]; + var y = v[1]; + out[0] = m[0] * x + m[2] * y + m[4]; + out[1] = m[1] * x + m[3] * y + m[5]; + return out; + } + + /** + * 求两个向量最小值 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function min(out, v1, v2) { + out[0] = Math.min(v1[0], v2[0]); + out[1] = Math.min(v1[1], v2[1]); + return out; + } + + /** + * 求两个向量最大值 + * @param {Vector2} out + * @param {Vector2} v1 + * @param {Vector2} v2 + */ + function max(out, v1, v2) { + out[0] = Math.max(v1[0], v2[0]); + out[1] = Math.max(v1[1], v2[1]); + return out; + } + + + var vector = (Object.freeze || Object)({ + create: create, + copy: copy, + clone: clone$1, + set: set, + add: add, + scaleAndAdd: scaleAndAdd, + sub: sub, + len: len, + length: length, + lenSquare: lenSquare, + lengthSquare: lengthSquare, + mul: mul, + div: div, + dot: dot, + scale: scale, + normalize: normalize, + distance: distance, + dist: dist, + distanceSquare: distanceSquare, + distSquare: distSquare, + negate: negate, + lerp: lerp, + applyTransform: applyTransform, + min: min, + max: max + }); + + // TODO Draggable for group + // FIXME Draggable on element which has parent rotation or scale + function Draggable() { + + this.on('mousedown', this._dragStart, this); + this.on('mousemove', this._drag, this); + this.on('mouseup', this._dragEnd, this); + this.on('globalout', this._dragEnd, this); + // this._dropTarget = null; + // this._draggingTarget = null; + + // this._x = 0; + // this._y = 0; + } + + Draggable.prototype = { + + constructor: Draggable, + + _dragStart: function(e) { + var draggingTarget = e.target; + if (draggingTarget && draggingTarget.draggable) { + this._draggingTarget = draggingTarget; + draggingTarget.dragging = true; + this._x = e.offsetX; + this._y = e.offsetY; + + this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event); + } + }, + + _drag: function(e) { + var draggingTarget = this._draggingTarget; + if (draggingTarget) { + + var x = e.offsetX; + var y = e.offsetY; + + var dx = x - this._x; + var dy = y - this._y; + this._x = x; + this._y = y; + + draggingTarget.drift(dx, dy, e); + this.dispatchToElement(param(draggingTarget, e), 'drag', e.event); + + var dropTarget = this.findHover(x, y, draggingTarget).target; + var lastDropTarget = this._dropTarget; + this._dropTarget = dropTarget; + + if (draggingTarget !== dropTarget) { + if (lastDropTarget && dropTarget !== lastDropTarget) { + this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event); + } + if (dropTarget && dropTarget !== lastDropTarget) { + this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event); + } + } + } + }, + + _dragEnd: function(e) { + var draggingTarget = this._draggingTarget; + + if (draggingTarget) { + draggingTarget.dragging = false; + } + + this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event); + + if (this._dropTarget) { + this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event); + } + + this._draggingTarget = null; + this._dropTarget = null; + } + + }; + + function param(target, e) { + return { + target: target, + topTarget: e && e.topTarget + }; + } + + /** + * 事件扩展 + * @module zrender/mixin/Eventful + * @author Kener (@Kener-林峰, kener.linfeng@gmail.com) + * pissang (https://www.github.com/pissang) + */ + + var arrySlice = Array.prototype.slice; + + /** + * 事件分发器 + * @alias module:zrender/mixin/Eventful + * @constructor + */ + var Eventful = function() { + this._$handlers = {}; + }; + + Eventful.prototype = { + + constructor: Eventful, + + /** + * 单次触发绑定,trigger后销毁 + * + * @param {string} event 事件名 + * @param {Function} handler 响应函数 + * @param {Object} context + */ + one: function(event, handler, context) { + var _h = this._$handlers; + + if (!handler || !event) { + return this; + } + + if (!_h[event]) { + _h[event] = []; + } + + for (var i = 0; i < _h[event].length; i++) { + if (_h[event][i].h === handler) { + return this; + } + } + + _h[event].push({ + h: handler, + one: true, + ctx: context || this + }); + + return this; + }, + + /** + * 绑定事件 + * @param {string} event 事件名 + * @param {Function} handler 事件处理函数 + * @param {Object} [context] + */ + on: function(event, handler, context) { + var _h = this._$handlers; + + if (!handler || !event) { + return this; + } + + if (!_h[event]) { + _h[event] = []; + } + + for (var i = 0; i < _h[event].length; i++) { + if (_h[event][i].h === handler) { + return this; + } + } + + _h[event].push({ + h: handler, + one: false, + ctx: context || this + }); + + return this; + }, + + /** + * 是否绑定了事件 + * @param {string} event + * @return {boolean} + */ + isSilent: function(event) { + var _h = this._$handlers; + return _h[event] && _h[event].length; + }, + + /** + * 解绑事件 + * @param {string} event 事件名 + * @param {Function} [handler] 事件处理函数 + */ + off: function(event, handler) { + var _h = this._$handlers; + + if (!event) { + this._$handlers = {}; + return this; + } + + if (handler) { + if (_h[event]) { + var newList = []; + for (var i = 0, l = _h[event].length; i < l; i++) { + if (_h[event][i]['h'] != handler) { + newList.push(_h[event][i]); + } + } + _h[event] = newList; + } + + if (_h[event] && _h[event].length === 0) { + delete _h[event]; + } + } else { + delete _h[event]; + } + + return this; + }, + + /** + * 事件分发 + * + * @param {string} type 事件类型 + */ + trigger: function(type) { + if (this._$handlers[type]) { + var args = arguments; + var argLen = args.length; + + if (argLen > 3) { + args = arrySlice.call(args, 1); + } + + var _h = this._$handlers[type]; + var len = _h.length; + for (var i = 0; i < len;) { + // Optimize advise from backbone + switch (argLen) { + case 1: + _h[i]['h'].call(_h[i]['ctx']); + break; + case 2: + _h[i]['h'].call(_h[i]['ctx'], args[1]); + break; + case 3: + _h[i]['h'].call(_h[i]['ctx'], args[1], args[2]); + break; + default: + // have more than 2 given arguments + _h[i]['h'].apply(_h[i]['ctx'], args); + break; + } + + if (_h[i]['one']) { + _h.splice(i, 1); + len--; + } else { + i++; + } + } + } + + return this; + }, + + /** + * 带有context的事件分发, 最后一个参数是事件回调的context + * @param {string} type 事件类型 + */ + triggerWithContext: function(type) { + if (this._$handlers[type]) { + var args = arguments; + var argLen = args.length; + + if (argLen > 4) { + args = arrySlice.call(args, 1, args.length - 1); + } + var ctx = args[args.length - 1]; + + var _h = this._$handlers[type]; + var len = _h.length; + for (var i = 0; i < len;) { + // Optimize advise from backbone + switch (argLen) { + case 1: + _h[i]['h'].call(ctx); + break; + case 2: + _h[i]['h'].call(ctx, args[1]); + break; + case 3: + _h[i]['h'].call(ctx, args[1], args[2]); + break; + default: + // have more than 2 given arguments + _h[i]['h'].apply(ctx, args); + break; + } + + if (_h[i]['one']) { + _h.splice(i, 1); + len--; + } else { + i++; + } + } + } + + return this; + } + }; + + var SILENT = 'silent'; + + function makeEventPacket(eveType, targetInfo, event) { + return { + type: eveType, + event: event, + // target can only be an element that is not silent. + target: targetInfo.target, + // topTarget can be a silent element. + topTarget: targetInfo.topTarget, + cancelBubble: false, + offsetX: event.zrX, + offsetY: event.zrY, + gestureEvent: event.gestureEvent, + pinchX: event.pinchX, + pinchY: event.pinchY, + pinchScale: event.pinchScale, + wheelDelta: event.zrDelta, + zrByTouch: event.zrByTouch, + which: event.which + }; + } + + function EmptyProxy() {} + EmptyProxy.prototype.dispose = function() {}; + + var handlerNames = [ + 'click', 'dblclick', 'mousewheel', 'mouseout', + 'mouseup', 'mousedown', 'mousemove', 'contextmenu' + ]; + /** + * @alias module:zrender/Handler + * @constructor + * @extends module:zrender/mixin/Eventful + * @param {module:zrender/Storage} storage Storage instance. + * @param {module:zrender/Painter} painter Painter instance. + * @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance. + * @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()). + */ + var Handler = function(storage, painter, proxy, painterRoot) { + Eventful.call(this); + + this.storage = storage; + + this.painter = painter; + + this.painterRoot = painterRoot; + + proxy = proxy || new EmptyProxy(); + + /** + * Proxy of event. can be Dom, WebGLSurface, etc. + */ + this.proxy = null; + + /** + * {target, topTarget, x, y} + * @private + * @type {Object} + */ + this._hovered = {}; + + /** + * @private + * @type {Date} + */ + this._lastTouchMoment; + + /** + * @private + * @type {number} + */ + this._lastX; + + /** + * @private + * @type {number} + */ + this._lastY; + + + Draggable.call(this); + + this.setHandlerProxy(proxy); + }; + + Handler.prototype = { + + constructor: Handler, + + setHandlerProxy: function(proxy) { + if (this.proxy) { + this.proxy.dispose(); + } + + if (proxy) { + each$1(handlerNames, function(name) { + proxy.on && proxy.on(name, this[name], this); + }, this); + // Attach handler + proxy.handler = this; + } + this.proxy = proxy; + }, + + mousemove: function(event) { + var x = event.zrX; + var y = event.zrY; + + var lastHovered = this._hovered; + var lastHoveredTarget = lastHovered.target; + + // If lastHoveredTarget is removed from zr (detected by '__zr') by some API call + // (like 'setOption' or 'dispatchAction') in event handlers, we should find + // lastHovered again here. Otherwise 'mouseout' can not be triggered normally. + // See #6198. + if (lastHoveredTarget && !lastHoveredTarget.__zr) { + lastHovered = this.findHover(lastHovered.x, lastHovered.y); + lastHoveredTarget = lastHovered.target; + } + + var hovered = this._hovered = this.findHover(x, y); + var hoveredTarget = hovered.target; + + var proxy = this.proxy; + proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default'); + + // Mouse out on previous hovered element + if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) { + this.dispatchToElement(lastHovered, 'mouseout', event); + } + + // Mouse moving on one element + this.dispatchToElement(hovered, 'mousemove', event); + + // Mouse over on a new element + if (hoveredTarget && hoveredTarget !== lastHoveredTarget) { + this.dispatchToElement(hovered, 'mouseover', event); + } + }, + + mouseout: function(event) { + this.dispatchToElement(this._hovered, 'mouseout', event); + + // There might be some doms created by upper layer application + // at the same level of painter.getViewportRoot() (e.g., tooltip + // dom created by echarts), where 'globalout' event should not + // be triggered when mouse enters these doms. (But 'mouseout' + // should be triggered at the original hovered element as usual). + var element = event.toElement || event.relatedTarget; + var innerDom; + do { + element = element && element.parentNode; + } + while (element && element.nodeType != 9 && !( + innerDom = element === this.painterRoot + )); + + !innerDom && this.trigger('globalout', { + event: event + }); + }, + + /** + * Resize + */ + resize: function(event) { + this._hovered = {}; + }, + + /** + * Dispatch event + * @param {string} eventName + * @param {event=} eventArgs + */ + dispatch: function(eventName, eventArgs) { + var handler = this[eventName]; + handler && handler.call(this, eventArgs); + }, + + /** + * Dispose + */ + dispose: function() { + + this.proxy.dispose(); + + this.storage = + this.proxy = + this.painter = null; + }, + + /** + * 设置默认的cursor style + * @param {string} [cursorStyle='default'] 例如 crosshair + */ + setCursorStyle: function(cursorStyle) { + var proxy = this.proxy; + proxy.setCursor && proxy.setCursor(cursorStyle); + }, + + /** + * 事件分发代理 + * + * @private + * @param {Object} targetInfo {target, topTarget} 目标图形元素 + * @param {string} eventName 事件名称 + * @param {Object} event 事件对象 + */ + dispatchToElement: function(targetInfo, eventName, event) { + targetInfo = targetInfo || {}; + var el = targetInfo.target; + if (el && el.silent) { + return; + } + var eventHandler = 'on' + eventName; + var eventPacket = makeEventPacket(eventName, targetInfo, event); + + while (el) { + el[eventHandler] && + (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket)); + + el.trigger(eventName, eventPacket); + + el = el.parent; + + if (eventPacket.cancelBubble) { + break; + } + } + + if (!eventPacket.cancelBubble) { + // 冒泡到顶级 zrender 对象 + this.trigger(eventName, eventPacket); + // 分发事件到用户自定义层 + // 用户有可能在全局 click 事件中 dispose,所以需要判断下 painter 是否存在 + this.painter && this.painter.eachOtherLayer(function(layer) { + if (typeof(layer[eventHandler]) == 'function') { + layer[eventHandler].call(layer, eventPacket); + } + if (layer.trigger) { + layer.trigger(eventName, eventPacket); + } + }); + } + }, + + /** + * @private + * @param {number} x + * @param {number} y + * @param {module:zrender/graphic/Displayable} exclude + * @return {model:zrender/Element} + * @method + */ + findHover: function(x, y, exclude) { + var list = this.storage.getDisplayList(); + var out = { + x: x, + y: y + }; + + for (var i = list.length - 1; i >= 0; i--) { + var hoverCheckResult; + if (list[i] !== exclude + // getDisplayList may include ignored item in VML mode + && + !list[i].ignore && + (hoverCheckResult = isHover(list[i], x, y)) + ) { + !out.topTarget && (out.topTarget = list[i]); + if (hoverCheckResult !== SILENT) { + out.target = list[i]; + break; + } + } + } + + return out; + } + }; + + // Common handlers + each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function(name) { + Handler.prototype[name] = function(event) { + // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover + var hovered = this.findHover(event.zrX, event.zrY); + var hoveredTarget = hovered.target; + + if (name === 'mousedown') { + this._downEl = hoveredTarget; + this._downPoint = [event.zrX, event.zrY]; + // In case click triggered before mouseup + this._upEl = hoveredTarget; + } else if (name === 'mouseup') { + this._upEl = hoveredTarget; + } else if (name === 'click') { + if (this._downEl !== this._upEl + // Original click event is triggered on the whole canvas element, + // including the case that `mousedown` - `mousemove` - `mouseup`, + // which should be filtered, otherwise it will bring trouble to + // pan and zoom. + || + !this._downPoint + // Arbitrary value + || + dist(this._downPoint, [event.zrX, event.zrY]) > 4 + ) { + return; + } + this._downPoint = null; + } + + this.dispatchToElement(hovered, name, event); + }; + }); + + function isHover(displayable, x, y) { + if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) { + var el = displayable; + var isSilent; + while (el) { + // If clipped by ancestor. + // FIXME: If clipPath has neither stroke nor fill, + // el.clipPath.contain(x, y) will always return false. + if (el.clipPath && !el.clipPath.contain(x, y)) { + return false; + } + if (el.silent) { + isSilent = true; + } + el = el.parent; + } + return isSilent ? SILENT : true; + } + + return false; + } + + mixin(Handler, Eventful); + mixin(Handler, Draggable); + + /** + * 3x2矩阵操作类 + * @exports zrender/tool/matrix + */ + + var ArrayCtor$1 = typeof Float32Array === 'undefined' ? + Array : + Float32Array; + + /** + * Create a identity matrix. + * @return {Float32Array|Array.} + */ + function create$1() { + var out = new ArrayCtor$1(6); + identity(out); + + return out; + } + + /** + * 设置矩阵为单位矩阵 + * @param {Float32Array|Array.} out + */ + function identity(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + return out; + } + + /** + * 复制矩阵 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} m + */ + function copy$1(out, m) { + out[0] = m[0]; + out[1] = m[1]; + out[2] = m[2]; + out[3] = m[3]; + out[4] = m[4]; + out[5] = m[5]; + return out; + } + + /** + * 矩阵相乘 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} m1 + * @param {Float32Array|Array.} m2 + */ + function mul$1(out, m1, m2) { + // Consider matrix.mul(m, m2, m); + // where out is the same as m2. + // So use temp variable to escape error. + var out0 = m1[0] * m2[0] + m1[2] * m2[1]; + var out1 = m1[1] * m2[0] + m1[3] * m2[1]; + var out2 = m1[0] * m2[2] + m1[2] * m2[3]; + var out3 = m1[1] * m2[2] + m1[3] * m2[3]; + var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4]; + var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5]; + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; + out[4] = out4; + out[5] = out5; + return out; + } + + /** + * 平移变换 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} a + * @param {Float32Array|Array.} v + */ + function translate(out, a, v) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4] + v[0]; + out[5] = a[5] + v[1]; + return out; + } + + /** + * 旋转变换 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} a + * @param {number} rad + */ + function rotate(out, a, rad) { + var aa = a[0]; + var ac = a[2]; + var atx = a[4]; + var ab = a[1]; + var ad = a[3]; + var aty = a[5]; + var st = Math.sin(rad); + var ct = Math.cos(rad); + + out[0] = aa * ct + ab * st; + out[1] = -aa * st + ab * ct; + out[2] = ac * ct + ad * st; + out[3] = -ac * st + ct * ad; + out[4] = ct * atx + st * aty; + out[5] = ct * aty - st * atx; + return out; + } + + /** + * 缩放变换 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} a + * @param {Float32Array|Array.} v + */ + function scale$1(out, a, v) { + var vx = v[0]; + var vy = v[1]; + out[0] = a[0] * vx; + out[1] = a[1] * vy; + out[2] = a[2] * vx; + out[3] = a[3] * vy; + out[4] = a[4] * vx; + out[5] = a[5] * vy; + return out; + } + + /** + * 求逆矩阵 + * @param {Float32Array|Array.} out + * @param {Float32Array|Array.} a + */ + function invert(out, a) { + + var aa = a[0]; + var ac = a[2]; + var atx = a[4]; + var ab = a[1]; + var ad = a[3]; + var aty = a[5]; + + var det = aa * ad - ab * ac; + if (!det) { + return null; + } + det = 1.0 / det; + + out[0] = ad * det; + out[1] = -ab * det; + out[2] = -ac * det; + out[3] = aa * det; + out[4] = (ac * aty - ad * atx) * det; + out[5] = (ab * atx - aa * aty) * det; + return out; + } + + /** + * Clone a new matrix. + * @param {Float32Array|Array.} a + */ + function clone$2(a) { + var b = create$1(); + copy$1(b, a); + return b; + } + + var matrix = (Object.freeze || Object)({ + create: create$1, + identity: identity, + copy: copy$1, + mul: mul$1, + translate: translate, + rotate: rotate, + scale: scale$1, + invert: invert, + clone: clone$2 + }); + + /** + * 提供变换扩展 + * @module zrender/mixin/Transformable + * @author pissang (https://www.github.com/pissang) + */ + + var mIdentity = identity; + + var EPSILON = 5e-5; + + function isNotAroundZero(val) { + return val > EPSILON || val < -EPSILON; + } + + /** + * @alias module:zrender/mixin/Transformable + * @constructor + */ + var Transformable = function(opts) { + opts = opts || {}; + // If there are no given position, rotation, scale + if (!opts.position) { + /** + * 平移 + * @type {Array.} + * @default [0, 0] + */ + this.position = [0, 0]; + } + if (opts.rotation == null) { + /** + * 旋转 + * @type {Array.} + * @default 0 + */ + this.rotation = 0; + } + if (!opts.scale) { + /** + * 缩放 + * @type {Array.} + * @default [1, 1] + */ + this.scale = [1, 1]; + } + /** + * 旋转和缩放的原点 + * @type {Array.} + * @default null + */ + this.origin = this.origin || null; + }; + + var transformableProto = Transformable.prototype; + transformableProto.transform = null; + + /** + * 判断是否需要有坐标变换 + * 如果有坐标变换, 则从position, rotation, scale以及父节点的transform计算出自身的transform矩阵 + */ + transformableProto.needLocalTransform = function() { + return isNotAroundZero(this.rotation) || + isNotAroundZero(this.position[0]) || + isNotAroundZero(this.position[1]) || + isNotAroundZero(this.scale[0] - 1) || + isNotAroundZero(this.scale[1] - 1); + }; + + transformableProto.updateTransform = function() { + var parent = this.parent; + var parentHasTransform = parent && parent.transform; + var needLocalTransform = this.needLocalTransform(); + + var m = this.transform; + if (!(needLocalTransform || parentHasTransform)) { + m && mIdentity(m); + return; + } + + m = m || create$1(); + + if (needLocalTransform) { + this.getLocalTransform(m); + } else { + mIdentity(m); + } + + // 应用父节点变换 + if (parentHasTransform) { + if (needLocalTransform) { + mul$1(m, parent.transform, m); + } else { + copy$1(m, parent.transform); + } + } + // 保存这个变换矩阵 + this.transform = m; + + this.invTransform = this.invTransform || create$1(); + invert(this.invTransform, m); + }; + + transformableProto.getLocalTransform = function(m) { + return Transformable.getLocalTransform(this, m); + }; + + /** + * 将自己的transform应用到context上 + * @param {CanvasRenderingContext2D} ctx + */ + transformableProto.setTransform = function(ctx) { + var m = this.transform; + var dpr = ctx.dpr || 1; + if (m) { + ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]); + } else { + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + } + }; + + transformableProto.restoreTransform = function(ctx) { + var dpr = ctx.dpr || 1; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + }; + + var tmpTransform = []; + + /** + * 分解`transform`矩阵到`position`, `rotation`, `scale` + */ + transformableProto.decomposeTransform = function() { + if (!this.transform) { + return; + } + var parent = this.parent; + var m = this.transform; + if (parent && parent.transform) { + // Get local transform and decompose them to position, scale, rotation + mul$1(tmpTransform, parent.invTransform, m); + m = tmpTransform; + } + var sx = m[0] * m[0] + m[1] * m[1]; + var sy = m[2] * m[2] + m[3] * m[3]; + var position = this.position; + var scale$$1 = this.scale; + if (isNotAroundZero(sx - 1)) { + sx = Math.sqrt(sx); + } + if (isNotAroundZero(sy - 1)) { + sy = Math.sqrt(sy); + } + if (m[0] < 0) { + sx = -sx; + } + if (m[3] < 0) { + sy = -sy; + } + position[0] = m[4]; + position[1] = m[5]; + scale$$1[0] = sx; + scale$$1[1] = sy; + this.rotation = Math.atan2(-m[1] / sy, m[0] / sx); + }; + + /** + * Get global scale + * @return {Array.} + */ + transformableProto.getGlobalScale = function() { + var m = this.transform; + if (!m) { + return [1, 1]; + } + var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]); + var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]); + if (m[0] < 0) { + sx = -sx; + } + if (m[3] < 0) { + sy = -sy; + } + return [sx, sy]; + }; + /** + * 变换坐标位置到 shape 的局部坐标空间 + * @method + * @param {number} x + * @param {number} y + * @return {Array.} + */ + transformableProto.transformCoordToLocal = function(x, y) { + var v2 = [x, y]; + var invTransform = this.invTransform; + if (invTransform) { + applyTransform(v2, v2, invTransform); + } + return v2; + }; + + /** + * 变换局部坐标位置到全局坐标空间 + * @method + * @param {number} x + * @param {number} y + * @return {Array.} + */ + transformableProto.transformCoordToGlobal = function(x, y) { + var v2 = [x, y]; + var transform = this.transform; + if (transform) { + applyTransform(v2, v2, transform); + } + return v2; + }; + + /** + * @static + * @param {Object} target + * @param {Array.} target.origin + * @param {number} target.rotation + * @param {Array.} target.position + * @param {Array.} [m] + */ + Transformable.getLocalTransform = function(target, m) { + m = m || []; + mIdentity(m); + + var origin = target.origin; + var scale$$1 = target.scale || [1, 1]; + var rotation = target.rotation || 0; + var position = target.position || [0, 0]; + + if (origin) { + // Translate to origin + m[4] -= origin[0]; + m[5] -= origin[1]; + } + scale$1(m, m, scale$$1); + if (rotation) { + rotate(m, m, rotation); + } + if (origin) { + // Translate back from origin + m[4] += origin[0]; + m[5] += origin[1]; + } + + m[4] += position[0]; + m[5] += position[1]; + + return m; + }; + + /** + * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js + * @see http://sole.github.io/tween.js/examples/03_graphs.html + * @exports zrender/animation/easing + */ + var easing = { + /** + * @param {number} k + * @return {number} + */ + linear: function(k) { + return k; + }, + + /** + * @param {number} k + * @return {number} + */ + quadraticIn: function(k) { + return k * k; + }, + /** + * @param {number} k + * @return {number} + */ + quadraticOut: function(k) { + return k * (2 - k); + }, + /** + * @param {number} k + * @return {number} + */ + quadraticInOut: function(k) { + if ((k *= 2) < 1) { + return 0.5 * k * k; + } + return -0.5 * (--k * (k - 2) - 1); + }, + + // 三次方的缓动(t^3) + /** + * @param {number} k + * @return {number} + */ + cubicIn: function(k) { + return k * k * k; + }, + /** + * @param {number} k + * @return {number} + */ + cubicOut: function(k) { + return --k * k * k + 1; + }, + /** + * @param {number} k + * @return {number} + */ + cubicInOut: function(k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k; + } + return 0.5 * ((k -= 2) * k * k + 2); + }, + + // 四次方的缓动(t^4) + /** + * @param {number} k + * @return {number} + */ + quarticIn: function(k) { + return k * k * k * k; + }, + /** + * @param {number} k + * @return {number} + */ + quarticOut: function(k) { + return 1 - (--k * k * k * k); + }, + /** + * @param {number} k + * @return {number} + */ + quarticInOut: function(k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k * k; + } + return -0.5 * ((k -= 2) * k * k * k - 2); + }, + + // 五次方的缓动(t^5) + /** + * @param {number} k + * @return {number} + */ + quinticIn: function(k) { + return k * k * k * k * k; + }, + /** + * @param {number} k + * @return {number} + */ + quinticOut: function(k) { + return --k * k * k * k * k + 1; + }, + /** + * @param {number} k + * @return {number} + */ + quinticInOut: function(k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k * k * k; + } + return 0.5 * ((k -= 2) * k * k * k * k + 2); + }, + + // 正弦曲线的缓动(sin(t)) + /** + * @param {number} k + * @return {number} + */ + sinusoidalIn: function(k) { + return 1 - Math.cos(k * Math.PI / 2); + }, + /** + * @param {number} k + * @return {number} + */ + sinusoidalOut: function(k) { + return Math.sin(k * Math.PI / 2); + }, + /** + * @param {number} k + * @return {number} + */ + sinusoidalInOut: function(k) { + return 0.5 * (1 - Math.cos(Math.PI * k)); + }, + + // 指数曲线的缓动(2^t) + /** + * @param {number} k + * @return {number} + */ + exponentialIn: function(k) { + return k === 0 ? 0 : Math.pow(1024, k - 1); + }, + /** + * @param {number} k + * @return {number} + */ + exponentialOut: function(k) { + return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); + }, + /** + * @param {number} k + * @return {number} + */ + exponentialInOut: function(k) { + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if ((k *= 2) < 1) { + return 0.5 * Math.pow(1024, k - 1); + } + return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2); + }, + + // 圆形曲线的缓动(sqrt(1-t^2)) + /** + * @param {number} k + * @return {number} + */ + circularIn: function(k) { + return 1 - Math.sqrt(1 - k * k); + }, + /** + * @param {number} k + * @return {number} + */ + circularOut: function(k) { + return Math.sqrt(1 - (--k * k)); + }, + /** + * @param {number} k + * @return {number} + */ + circularInOut: function(k) { + if ((k *= 2) < 1) { + return -0.5 * (Math.sqrt(1 - k * k) - 1); + } + return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); + }, + + // 创建类似于弹簧在停止前来回振荡的动画 + /** + * @param {number} k + * @return {number} + */ + elasticIn: function(k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + return -(a * Math.pow(2, 10 * (k -= 1)) * + Math.sin((k - s) * (2 * Math.PI) / p)); + }, + /** + * @param {number} k + * @return {number} + */ + elasticOut: function(k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + return (a * Math.pow(2, -10 * k) * + Math.sin((k - s) * (2 * Math.PI) / p) + 1); + }, + /** + * @param {number} k + * @return {number} + */ + elasticInOut: function(k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + if ((k *= 2) < 1) { + return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * + Math.sin((k - s) * (2 * Math.PI) / p)); + } + return a * Math.pow(2, -10 * (k -= 1)) * + Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; + + }, + + // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动 + /** + * @param {number} k + * @return {number} + */ + backIn: function(k) { + var s = 1.70158; + return k * k * ((s + 1) * k - s); + }, + /** + * @param {number} k + * @return {number} + */ + backOut: function(k) { + var s = 1.70158; + return --k * k * ((s + 1) * k + s) + 1; + }, + /** + * @param {number} k + * @return {number} + */ + backInOut: function(k) { + var s = 1.70158 * 1.525; + if ((k *= 2) < 1) { + return 0.5 * (k * k * ((s + 1) * k - s)); + } + return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); + }, + + // 创建弹跳效果 + /** + * @param {number} k + * @return {number} + */ + bounceIn: function(k) { + return 1 - easing.bounceOut(1 - k); + }, + /** + * @param {number} k + * @return {number} + */ + bounceOut: function(k) { + if (k < (1 / 2.75)) { + return 7.5625 * k * k; + } else if (k < (2 / 2.75)) { + return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; + } else if (k < (2.5 / 2.75)) { + return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; + } else { + return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; + } + }, + /** + * @param {number} k + * @return {number} + */ + bounceInOut: function(k) { + if (k < 0.5) { + return easing.bounceIn(k * 2) * 0.5; + } + return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5; + } + }; + + /** + * 动画主控制器 + * @config target 动画对象,可以是数组,如果是数组的话会批量分发onframe等事件 + * @config life(1000) 动画时长 + * @config delay(0) 动画延迟时间 + * @config loop(true) + * @config gap(0) 循环的间隔时间 + * @config onframe + * @config easing(optional) + * @config ondestroy(optional) + * @config onrestart(optional) + * + * TODO pause + */ + + function Clip(options) { + + this._target = options.target; + + // 生命周期 + this._life = options.life || 1000; + // 延时 + this._delay = options.delay || 0; + // 开始时间 + // this._startTime = new Date().getTime() + this._delay;// 单位毫秒 + this._initialized = false; + + // 是否循环 + this.loop = options.loop == null ? false : options.loop; + + this.gap = options.gap || 0; + + this.easing = options.easing || 'Linear'; + + this.onframe = options.onframe; + this.ondestroy = options.ondestroy; + this.onrestart = options.onrestart; + + this._pausedTime = 0; + this._paused = false; + } + + Clip.prototype = { + + constructor: Clip, + + step: function(globalTime, deltaTime) { + // Set startTime on first step, or _startTime may has milleseconds different between clips + // PENDING + if (!this._initialized) { + this._startTime = globalTime + this._delay; + this._initialized = true; + } + + if (this._paused) { + this._pausedTime += deltaTime; + return; + } + + var percent = (globalTime - this._startTime - this._pausedTime) / this._life; + + // 还没开始 + if (percent < 0) { + return; + } + + percent = Math.min(percent, 1); + + var easing$$1 = this.easing; + var easingFunc = typeof easing$$1 == 'string' ? easing[easing$$1] : easing$$1; + var schedule = typeof easingFunc === 'function' ? + easingFunc(percent) : + percent; + + this.fire('frame', schedule); + + // 结束 + if (percent == 1) { + if (this.loop) { + this.restart(globalTime); + // 重新开始周期 + // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件 + return 'restart'; + } + + // 动画完成将这个控制器标识为待删除 + // 在Animation.update中进行批量删除 + this._needsRemove = true; + return 'destroy'; + } + + return null; + }, + + restart: function(globalTime) { + var remainder = (globalTime - this._startTime - this._pausedTime) % this._life; + this._startTime = globalTime - remainder + this.gap; + this._pausedTime = 0; + + this._needsRemove = false; + }, + + fire: function(eventType, arg) { + eventType = 'on' + eventType; + if (this[eventType]) { + this[eventType](this._target, arg); + } + }, + + pause: function() { + this._paused = true; + }, + + resume: function() { + this._paused = false; + } + }; + + // Simple LRU cache use doubly linked list + // @module zrender/core/LRU + + /** + * Simple double linked list. Compared with array, it has O(1) remove operation. + * @constructor + */ + var LinkedList = function() { + + /** + * @type {module:zrender/core/LRU~Entry} + */ + this.head = null; + + /** + * @type {module:zrender/core/LRU~Entry} + */ + this.tail = null; + + this._len = 0; + }; + + var linkedListProto = LinkedList.prototype; + /** + * Insert a new value at the tail + * @param {} val + * @return {module:zrender/core/LRU~Entry} + */ + linkedListProto.insert = function(val) { + var entry = new Entry(val); + this.insertEntry(entry); + return entry; + }; + + /** + * Insert an entry at the tail + * @param {module:zrender/core/LRU~Entry} entry + */ + linkedListProto.insertEntry = function(entry) { + if (!this.head) { + this.head = this.tail = entry; + } else { + this.tail.next = entry; + entry.prev = this.tail; + entry.next = null; + this.tail = entry; + } + this._len++; + }; + + /** + * Remove entry. + * @param {module:zrender/core/LRU~Entry} entry + */ + linkedListProto.remove = function(entry) { + var prev = entry.prev; + var next = entry.next; + if (prev) { + prev.next = next; + } else { + // Is head + this.head = next; + } + if (next) { + next.prev = prev; + } else { + // Is tail + this.tail = prev; + } + entry.next = entry.prev = null; + this._len--; + }; + + /** + * @return {number} + */ + linkedListProto.len = function() { + return this._len; + }; + + /** + * Clear list + */ + linkedListProto.clear = function() { + this.head = this.tail = null; + this._len = 0; + }; + + /** + * @constructor + * @param {} val + */ + var Entry = function(val) { + /** + * @type {} + */ + this.value = val; + + /** + * @type {module:zrender/core/LRU~Entry} + */ + this.next; + + /** + * @type {module:zrender/core/LRU~Entry} + */ + this.prev; + }; + + /** + * LRU Cache + * @constructor + * @alias module:zrender/core/LRU + */ + var LRU = function(maxSize) { + + this._list = new LinkedList(); + + this._map = {}; + + this._maxSize = maxSize || 10; + + this._lastRemovedEntry = null; + }; + + var LRUProto = LRU.prototype; + + /** + * @param {string} key + * @param {} value + * @return {} Removed value + */ + LRUProto.put = function(key, value) { + var list = this._list; + var map = this._map; + var removed = null; + if (map[key] == null) { + var len = list.len(); + // Reuse last removed entry + var entry = this._lastRemovedEntry; + + if (len >= this._maxSize && len > 0) { + // Remove the least recently used + var leastUsedEntry = list.head; + list.remove(leastUsedEntry); + delete map[leastUsedEntry.key]; + + removed = leastUsedEntry.value; + this._lastRemovedEntry = leastUsedEntry; + } + + if (entry) { + entry.value = value; + } else { + entry = new Entry(value); + } + entry.key = key; + list.insertEntry(entry); + map[key] = entry; + } + + return removed; + }; + + /** + * @param {string} key + * @return {} + */ + LRUProto.get = function(key) { + var entry = this._map[key]; + var list = this._list; + if (entry != null) { + // Put the latest used entry in the tail + if (entry !== list.tail) { + list.remove(entry); + list.insertEntry(entry); + } + + return entry.value; + } + }; + + /** + * Clear the cache + */ + LRUProto.clear = function() { + this._list.clear(); + this._map = {}; + }; + + var kCSSColorTable = { + 'transparent': [0, 0, 0, 0], + 'aliceblue': [240, 248, 255, 1], + 'antiquewhite': [250, 235, 215, 1], + 'aqua': [0, 255, 255, 1], + 'aquamarine': [127, 255, 212, 1], + 'azure': [240, 255, 255, 1], + 'beige': [245, 245, 220, 1], + 'bisque': [255, 228, 196, 1], + 'black': [0, 0, 0, 1], + 'blanchedalmond': [255, 235, 205, 1], + 'blue': [0, 0, 255, 1], + 'blueviolet': [138, 43, 226, 1], + 'brown': [165, 42, 42, 1], + 'burlywood': [222, 184, 135, 1], + 'cadetblue': [95, 158, 160, 1], + 'chartreuse': [127, 255, 0, 1], + 'chocolate': [210, 105, 30, 1], + 'coral': [255, 127, 80, 1], + 'cornflowerblue': [100, 149, 237, 1], + 'cornsilk': [255, 248, 220, 1], + 'crimson': [220, 20, 60, 1], + 'cyan': [0, 255, 255, 1], + 'darkblue': [0, 0, 139, 1], + 'darkcyan': [0, 139, 139, 1], + 'darkgoldenrod': [184, 134, 11, 1], + 'darkgray': [169, 169, 169, 1], + 'darkgreen': [0, 100, 0, 1], + 'darkgrey': [169, 169, 169, 1], + 'darkkhaki': [189, 183, 107, 1], + 'darkmagenta': [139, 0, 139, 1], + 'darkolivegreen': [85, 107, 47, 1], + 'darkorange': [255, 140, 0, 1], + 'darkorchid': [153, 50, 204, 1], + 'darkred': [139, 0, 0, 1], + 'darksalmon': [233, 150, 122, 1], + 'darkseagreen': [143, 188, 143, 1], + 'darkslateblue': [72, 61, 139, 1], + 'darkslategray': [47, 79, 79, 1], + 'darkslategrey': [47, 79, 79, 1], + 'darkturquoise': [0, 206, 209, 1], + 'darkviolet': [148, 0, 211, 1], + 'deeppink': [255, 20, 147, 1], + 'deepskyblue': [0, 191, 255, 1], + 'dimgray': [105, 105, 105, 1], + 'dimgrey': [105, 105, 105, 1], + 'dodgerblue': [30, 144, 255, 1], + 'firebrick': [178, 34, 34, 1], + 'floralwhite': [255, 250, 240, 1], + 'forestgreen': [34, 139, 34, 1], + 'fuchsia': [255, 0, 255, 1], + 'gainsboro': [220, 220, 220, 1], + 'ghostwhite': [248, 248, 255, 1], + 'gold': [255, 215, 0, 1], + 'goldenrod': [218, 165, 32, 1], + 'gray': [128, 128, 128, 1], + 'green': [0, 128, 0, 1], + 'greenyellow': [173, 255, 47, 1], + 'grey': [128, 128, 128, 1], + 'honeydew': [240, 255, 240, 1], + 'hotpink': [255, 105, 180, 1], + 'indianred': [205, 92, 92, 1], + 'indigo': [75, 0, 130, 1], + 'ivory': [255, 255, 240, 1], + 'khaki': [240, 230, 140, 1], + 'lavender': [230, 230, 250, 1], + 'lavenderblush': [255, 240, 245, 1], + 'lawngreen': [124, 252, 0, 1], + 'lemonchiffon': [255, 250, 205, 1], + 'lightblue': [173, 216, 230, 1], + 'lightcoral': [240, 128, 128, 1], + 'lightcyan': [224, 255, 255, 1], + 'lightgoldenrodyellow': [250, 250, 210, 1], + 'lightgray': [211, 211, 211, 1], + 'lightgreen': [144, 238, 144, 1], + 'lightgrey': [211, 211, 211, 1], + 'lightpink': [255, 182, 193, 1], + 'lightsalmon': [255, 160, 122, 1], + 'lightseagreen': [32, 178, 170, 1], + 'lightskyblue': [135, 206, 250, 1], + 'lightslategray': [119, 136, 153, 1], + 'lightslategrey': [119, 136, 153, 1], + 'lightsteelblue': [176, 196, 222, 1], + 'lightyellow': [255, 255, 224, 1], + 'lime': [0, 255, 0, 1], + 'limegreen': [50, 205, 50, 1], + 'linen': [250, 240, 230, 1], + 'magenta': [255, 0, 255, 1], + 'maroon': [128, 0, 0, 1], + 'mediumaquamarine': [102, 205, 170, 1], + 'mediumblue': [0, 0, 205, 1], + 'mediumorchid': [186, 85, 211, 1], + 'mediumpurple': [147, 112, 219, 1], + 'mediumseagreen': [60, 179, 113, 1], + 'mediumslateblue': [123, 104, 238, 1], + 'mediumspringgreen': [0, 250, 154, 1], + 'mediumturquoise': [72, 209, 204, 1], + 'mediumvioletred': [199, 21, 133, 1], + 'midnightblue': [25, 25, 112, 1], + 'mintcream': [245, 255, 250, 1], + 'mistyrose': [255, 228, 225, 1], + 'moccasin': [255, 228, 181, 1], + 'navajowhite': [255, 222, 173, 1], + 'navy': [0, 0, 128, 1], + 'oldlace': [253, 245, 230, 1], + 'olive': [128, 128, 0, 1], + 'olivedrab': [107, 142, 35, 1], + 'orange': [255, 165, 0, 1], + 'orangered': [255, 69, 0, 1], + 'orchid': [218, 112, 214, 1], + 'palegoldenrod': [238, 232, 170, 1], + 'palegreen': [152, 251, 152, 1], + 'paleturquoise': [175, 238, 238, 1], + 'palevioletred': [219, 112, 147, 1], + 'papayawhip': [255, 239, 213, 1], + 'peachpuff': [255, 218, 185, 1], + 'peru': [205, 133, 63, 1], + 'pink': [255, 192, 203, 1], + 'plum': [221, 160, 221, 1], + 'powderblue': [176, 224, 230, 1], + 'purple': [128, 0, 128, 1], + 'red': [255, 0, 0, 1], + 'rosybrown': [188, 143, 143, 1], + 'royalblue': [65, 105, 225, 1], + 'saddlebrown': [139, 69, 19, 1], + 'salmon': [250, 128, 114, 1], + 'sandybrown': [244, 164, 96, 1], + 'seagreen': [46, 139, 87, 1], + 'seashell': [255, 245, 238, 1], + 'sienna': [160, 82, 45, 1], + 'silver': [192, 192, 192, 1], + 'skyblue': [135, 206, 235, 1], + 'slateblue': [106, 90, 205, 1], + 'slategray': [112, 128, 144, 1], + 'slategrey': [112, 128, 144, 1], + 'snow': [255, 250, 250, 1], + 'springgreen': [0, 255, 127, 1], + 'steelblue': [70, 130, 180, 1], + 'tan': [210, 180, 140, 1], + 'teal': [0, 128, 128, 1], + 'thistle': [216, 191, 216, 1], + 'tomato': [255, 99, 71, 1], + 'turquoise': [64, 224, 208, 1], + 'violet': [238, 130, 238, 1], + 'wheat': [245, 222, 179, 1], + 'white': [255, 255, 255, 1], + 'whitesmoke': [245, 245, 245, 1], + 'yellow': [255, 255, 0, 1], + 'yellowgreen': [154, 205, 50, 1] + }; + + function clampCssByte(i) { // Clamp to integer 0 .. 255. + i = Math.round(i); // Seems to be what Chrome does (vs truncation). + return i < 0 ? 0 : i > 255 ? 255 : i; + } + + function clampCssAngle(i) { // Clamp to integer 0 .. 360. + i = Math.round(i); // Seems to be what Chrome does (vs truncation). + return i < 0 ? 0 : i > 360 ? 360 : i; + } + + function clampCssFloat(f) { // Clamp to float 0.0 .. 1.0. + return f < 0 ? 0 : f > 1 ? 1 : f; + } + + function parseCssInt(str) { // int or percentage. + if (str.length && str.charAt(str.length - 1) === '%') { + return clampCssByte(parseFloat(str) / 100 * 255); + } + return clampCssByte(parseInt(str, 10)); + } + + function parseCssFloat(str) { // float or percentage. + if (str.length && str.charAt(str.length - 1) === '%') { + return clampCssFloat(parseFloat(str) / 100); + } + return clampCssFloat(parseFloat(str)); + } + + function cssHueToRgb(m1, m2, h) { + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + + if (h * 6 < 1) { + return m1 + (m2 - m1) * h * 6; + } + if (h * 2 < 1) { + return m2; + } + if (h * 3 < 2) { + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + } + return m1; + } + + function lerpNumber(a, b, p) { + return a + (b - a) * p; + } + + function setRgba(out, r, g, b, a) { + out[0] = r; + out[1] = g; + out[2] = b; + out[3] = a; + return out; + } + + function copyRgba(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + + var colorCache = new LRU(20); + var lastRemovedArr = null; + + function putToCache(colorStr, rgbaArr) { + // Reuse removed array + if (lastRemovedArr) { + copyRgba(lastRemovedArr, rgbaArr); + } + lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice())); + } + + /** + * @param {string} colorStr + * @param {Array.} out + * @return {Array.} + * @memberOf module:zrender/util/color + */ + function parse(colorStr, rgbaArr) { + if (!colorStr) { + return; + } + rgbaArr = rgbaArr || []; + + var cached = colorCache.get(colorStr); + if (cached) { + return copyRgba(rgbaArr, cached); + } + + // colorStr may be not string + colorStr = colorStr + ''; + // Remove all whitespace, not compliant, but should just be more accepting. + var str = colorStr.replace(/ /g, '').toLowerCase(); + + // Color keywords (and transparent) lookup. + if (str in kCSSColorTable) { + copyRgba(rgbaArr, kCSSColorTable[str]); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + + // #abc and #abc123 syntax. + if (str.charAt(0) === '#') { + if (str.length === 4) { + var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. + if (!(iv >= 0 && iv <= 0xfff)) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; // Covers NaN. + } + setRgba(rgbaArr, + ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), + (iv & 0xf0) | ((iv & 0xf0) >> 4), + (iv & 0xf) | ((iv & 0xf) << 4), + 1 + ); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } else if (str.length === 7) { + var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. + if (!(iv >= 0 && iv <= 0xffffff)) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; // Covers NaN. + } + setRgba(rgbaArr, + (iv & 0xff0000) >> 16, + (iv & 0xff00) >> 8, + iv & 0xff, + 1 + ); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + + return; + } + var op = str.indexOf('('), + ep = str.indexOf(')'); + if (op !== -1 && ep + 1 === str.length) { + var fname = str.substr(0, op); + var params = str.substr(op + 1, ep - (op + 1)).split(','); + var alpha = 1; // To allow case fallthrough. + switch (fname) { + case 'rgba': + if (params.length !== 4) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + alpha = parseCssFloat(params.pop()); // jshint ignore:line + // Fall through. + case 'rgb': + if (params.length !== 3) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + setRgba(rgbaArr, + parseCssInt(params[0]), + parseCssInt(params[1]), + parseCssInt(params[2]), + alpha + ); + putToCache(colorStr, rgbaArr); + return rgbaArr; + case 'hsla': + if (params.length !== 4) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + params[3] = parseCssFloat(params[3]); + hsla2rgba(params, rgbaArr); + putToCache(colorStr, rgbaArr); + return rgbaArr; + case 'hsl': + if (params.length !== 3) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + hsla2rgba(params, rgbaArr); + putToCache(colorStr, rgbaArr); + return rgbaArr; + default: + return; + } + } + + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + + /** + * @param {Array.} hsla + * @param {Array.} rgba + * @return {Array.} rgba + */ + function hsla2rgba(hsla, rgba) { + var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; // 0 .. 1 + // NOTE(deanm): According to the CSS spec s/l should only be + // percentages, but we don't bother and let float or percentage. + var s = parseCssFloat(hsla[1]); + var l = parseCssFloat(hsla[2]); + var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + var m1 = l * 2 - m2; + + rgba = rgba || []; + setRgba(rgba, + clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), + clampCssByte(cssHueToRgb(m1, m2, h) * 255), + clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), + 1 + ); + + if (hsla.length === 4) { + rgba[3] = hsla[3]; + } + + return rgba; + } + + /** + * @param {Array.} rgba + * @return {Array.} hsla + */ + function rgba2hsla(rgba) { + if (!rgba) { + return; + } + + // RGB from 0 to 255 + var R = rgba[0] / 255; + var G = rgba[1] / 255; + var B = rgba[2] / 255; + + var vMin = Math.min(R, G, B); // Min. value of RGB + var vMax = Math.max(R, G, B); // Max. value of RGB + var delta = vMax - vMin; // Delta RGB value + + var L = (vMax + vMin) / 2; + var H; + var S; + // HSL results from 0 to 1 + if (delta === 0) { + H = 0; + S = 0; + } else { + if (L < 0.5) { + S = delta / (vMax + vMin); + } else { + S = delta / (2 - vMax - vMin); + } + + var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta; + var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta; + var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta; + + if (R === vMax) { + H = deltaB - deltaG; + } else if (G === vMax) { + H = (1 / 3) + deltaR - deltaB; + } else if (B === vMax) { + H = (2 / 3) + deltaG - deltaR; + } + + if (H < 0) { + H += 1; + } + + if (H > 1) { + H -= 1; + } + } + + var hsla = [H * 360, S, L]; + + if (rgba[3] != null) { + hsla.push(rgba[3]); + } + + return hsla; + } + + /** + * @param {string} color + * @param {number} level + * @return {string} + * @memberOf module:zrender/util/color + */ + function lift(color, level) { + var colorArr = parse(color); + if (colorArr) { + for (var i = 0; i < 3; i++) { + if (level < 0) { + colorArr[i] = colorArr[i] * (1 - level) | 0; + } else { + colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0; + } + if (colorArr[i] > 255) { + colorArr[i] = 255; + } else if (color[i] < 0) { + colorArr[i] = 0; + } + } + return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb'); + } + } + + /** + * @param {string} color + * @return {string} + * @memberOf module:zrender/util/color + */ + function toHex(color) { + var colorArr = parse(color); + if (colorArr) { + return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1); + } + } + + /** + * Map value to color. Faster than lerp methods because color is represented by rgba array. + * @param {number} normalizedValue A float between 0 and 1. + * @param {Array.>} colors List of rgba color array + * @param {Array.} [out] Mapped gba color array + * @return {Array.} will be null/undefined if input illegal. + */ + function fastLerp(normalizedValue, colors, out) { + if (!(colors && colors.length) || + !(normalizedValue >= 0 && normalizedValue <= 1) + ) { + return; + } + + out = out || []; + + var value = normalizedValue * (colors.length - 1); + var leftIndex = Math.floor(value); + var rightIndex = Math.ceil(value); + var leftColor = colors[leftIndex]; + var rightColor = colors[rightIndex]; + var dv = value - leftIndex; + out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)); + out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)); + out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)); + out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)); + + return out; + } + + /** + * @deprecated + */ + var fastMapToColor = fastLerp; + + /** + * @param {number} normalizedValue A float between 0 and 1. + * @param {Array.} colors Color list. + * @param {boolean=} fullOutput Default false. + * @return {(string|Object)} Result color. If fullOutput, + * return {color: ..., leftIndex: ..., rightIndex: ..., value: ...}, + * @memberOf module:zrender/util/color + */ + function lerp$1(normalizedValue, colors, fullOutput) { + if (!(colors && colors.length) || + !(normalizedValue >= 0 && normalizedValue <= 1) + ) { + return; + } + + var value = normalizedValue * (colors.length - 1); + var leftIndex = Math.floor(value); + var rightIndex = Math.ceil(value); + var leftColor = parse(colors[leftIndex]); + var rightColor = parse(colors[rightIndex]); + var dv = value - leftIndex; + + var color = stringify( + [ + clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), + clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), + clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), + clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)) + ], + 'rgba' + ); + + return fullOutput ? + { + color: color, + leftIndex: leftIndex, + rightIndex: rightIndex, + value: value + } : + color; + } + + /** + * @deprecated + */ + var mapToColor = lerp$1; + + /** + * @param {string} color + * @param {number=} h 0 ~ 360, ignore when null. + * @param {number=} s 0 ~ 1, ignore when null. + * @param {number=} l 0 ~ 1, ignore when null. + * @return {string} Color string in rgba format. + * @memberOf module:zrender/util/color + */ + function modifyHSL(color, h, s, l) { + color = parse(color); + + if (color) { + color = rgba2hsla(color); + h != null && (color[0] = clampCssAngle(h)); + s != null && (color[1] = parseCssFloat(s)); + l != null && (color[2] = parseCssFloat(l)); + + return stringify(hsla2rgba(color), 'rgba'); + } + } + + /** + * @param {string} color + * @param {number=} alpha 0 ~ 1 + * @return {string} Color string in rgba format. + * @memberOf module:zrender/util/color + */ + function modifyAlpha(color, alpha) { + color = parse(color); + + if (color && alpha != null) { + color[3] = clampCssFloat(alpha); + return stringify(color, 'rgba'); + } + } + + /** + * @param {Array.} arrColor like [12,33,44,0.4] + * @param {string} type 'rgba', 'hsva', ... + * @return {string} Result color. (If input illegal, return undefined). + */ + function stringify(arrColor, type) { + if (!arrColor || !arrColor.length) { + return; + } + var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2]; + if (type === 'rgba' || type === 'hsva' || type === 'hsla') { + colorStr += ',' + arrColor[3]; + } + return type + '(' + colorStr + ')'; + } + + + var color = (Object.freeze || Object)({ + parse: parse, + lift: lift, + toHex: toHex, + fastLerp: fastLerp, + fastMapToColor: fastMapToColor, + lerp: lerp$1, + mapToColor: mapToColor, + modifyHSL: modifyHSL, + modifyAlpha: modifyAlpha, + stringify: stringify + }); + + /** + * @module echarts/animation/Animator + */ + + var arraySlice = Array.prototype.slice; + + function defaultGetter(target, key) { + return target[key]; + } + + function defaultSetter(target, key, value) { + target[key] = value; + } + + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} percent + * @return {number} + */ + function interpolateNumber(p0, p1, percent) { + return (p1 - p0) * percent + p0; + } + + /** + * @param {string} p0 + * @param {string} p1 + * @param {number} percent + * @return {string} + */ + function interpolateString(p0, p1, percent) { + return percent > 0.5 ? p1 : p0; + } + + /** + * @param {Array} p0 + * @param {Array} p1 + * @param {number} percent + * @param {Array} out + * @param {number} arrDim + */ + function interpolateArray(p0, p1, percent, out, arrDim) { + var len = p0.length; + if (arrDim == 1) { + for (var i = 0; i < len; i++) { + out[i] = interpolateNumber(p0[i], p1[i], percent); + } + } else { + var len2 = len && p0[0].length; + for (var i = 0; i < len; i++) { + for (var j = 0; j < len2; j++) { + out[i][j] = interpolateNumber( + p0[i][j], p1[i][j], percent + ); + } + } + } + } + + // arr0 is source array, arr1 is target array. + // Do some preprocess to avoid error happened when interpolating from arr0 to arr1 + function fillArr(arr0, arr1, arrDim) { + var arr0Len = arr0.length; + var arr1Len = arr1.length; + if (arr0Len !== arr1Len) { + // FIXME Not work for TypedArray + var isPreviousLarger = arr0Len > arr1Len; + if (isPreviousLarger) { + // Cut the previous + arr0.length = arr1Len; + } else { + // Fill the previous + for (var i = arr0Len; i < arr1Len; i++) { + arr0.push( + arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]) + ); + } + } + } + // Handling NaN value + var len2 = arr0[0] && arr0[0].length; + for (var i = 0; i < arr0.length; i++) { + if (arrDim === 1) { + if (isNaN(arr0[i])) { + arr0[i] = arr1[i]; + } + } else { + for (var j = 0; j < len2; j++) { + if (isNaN(arr0[i][j])) { + arr0[i][j] = arr1[i][j]; + } + } + } + } + } + + /** + * @param {Array} arr0 + * @param {Array} arr1 + * @param {number} arrDim + * @return {boolean} + */ + function isArraySame(arr0, arr1, arrDim) { + if (arr0 === arr1) { + return true; + } + var len = arr0.length; + if (len !== arr1.length) { + return false; + } + if (arrDim === 1) { + for (var i = 0; i < len; i++) { + if (arr0[i] !== arr1[i]) { + return false; + } + } + } else { + var len2 = arr0[0].length; + for (var i = 0; i < len; i++) { + for (var j = 0; j < len2; j++) { + if (arr0[i][j] !== arr1[i][j]) { + return false; + } + } + } + } + return true; + } + + /** + * Catmull Rom interpolate array + * @param {Array} p0 + * @param {Array} p1 + * @param {Array} p2 + * @param {Array} p3 + * @param {number} t + * @param {number} t2 + * @param {number} t3 + * @param {Array} out + * @param {number} arrDim + */ + function catmullRomInterpolateArray( + p0, p1, p2, p3, t, t2, t3, out, arrDim + ) { + var len = p0.length; + if (arrDim == 1) { + for (var i = 0; i < len; i++) { + out[i] = catmullRomInterpolate( + p0[i], p1[i], p2[i], p3[i], t, t2, t3 + ); + } + } else { + var len2 = p0[0].length; + for (var i = 0; i < len; i++) { + for (var j = 0; j < len2; j++) { + out[i][j] = catmullRomInterpolate( + p0[i][j], p1[i][j], p2[i][j], p3[i][j], + t, t2, t3 + ); + } + } + } + } + + /** + * Catmull Rom interpolate number + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * @param {number} t2 + * @param {number} t3 + * @return {number} + */ + function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) { + var v0 = (p2 - p0) * 0.5; + var v1 = (p3 - p1) * 0.5; + return (2 * (p1 - p2) + v0 + v1) * t3 + + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + + v0 * t + p1; + } + + function cloneValue(value) { + if (isArrayLike(value)) { + var len = value.length; + if (isArrayLike(value[0])) { + var ret = []; + for (var i = 0; i < len; i++) { + ret.push(arraySlice.call(value[i])); + } + return ret; + } + + return arraySlice.call(value); + } + + return value; + } + + function rgba2String(rgba) { + rgba[0] = Math.floor(rgba[0]); + rgba[1] = Math.floor(rgba[1]); + rgba[2] = Math.floor(rgba[2]); + + return 'rgba(' + rgba.join(',') + ')'; + } + + function getArrayDim(keyframes) { + var lastValue = keyframes[keyframes.length - 1].value; + return isArrayLike(lastValue && lastValue[0]) ? 2 : 1; + } + + function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, forceAnimate) { + var getter = animator._getter; + var setter = animator._setter; + var useSpline = easing === 'spline'; + + var trackLen = keyframes.length; + if (!trackLen) { + return; + } + // Guess data type + var firstVal = keyframes[0].value; + var isValueArray = isArrayLike(firstVal); + var isValueColor = false; + var isValueString = false; + + // For vertices morphing + var arrDim = isValueArray ? getArrayDim(keyframes) : 0; + + var trackMaxTime; + // Sort keyframe as ascending + keyframes.sort(function(a, b) { + return a.time - b.time; + }); + + trackMaxTime = keyframes[trackLen - 1].time; + // Percents of each keyframe + var kfPercents = []; + // Value of each keyframe + var kfValues = []; + var prevValue = keyframes[0].value; + var isAllValueEqual = true; + for (var i = 0; i < trackLen; i++) { + kfPercents.push(keyframes[i].time / trackMaxTime); + // Assume value is a color when it is a string + var value = keyframes[i].value; + + // Check if value is equal, deep check if value is array + if (!((isValueArray && isArraySame(value, prevValue, arrDim)) || + (!isValueArray && value === prevValue))) { + isAllValueEqual = false; + } + prevValue = value; + + // Try converting a string to a color array + if (typeof value == 'string') { + var colorArray = parse(value); + if (colorArray) { + value = colorArray; + isValueColor = true; + } else { + isValueString = true; + } + } + kfValues.push(value); + } + if (!forceAnimate && isAllValueEqual) { + return; + } + + var lastValue = kfValues[trackLen - 1]; + // Polyfill array and NaN value + for (var i = 0; i < trackLen - 1; i++) { + if (isValueArray) { + fillArr(kfValues[i], lastValue, arrDim); + } else { + if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) { + kfValues[i] = lastValue; + } + } + } + isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim); + + // Cache the key of last frame to speed up when + // animation playback is sequency + var lastFrame = 0; + var lastFramePercent = 0; + var start; + var w; + var p0; + var p1; + var p2; + var p3; + + if (isValueColor) { + var rgba = [0, 0, 0, 0]; + } + + var onframe = function(target, percent) { + // Find the range keyframes + // kf1-----kf2---------current--------kf3 + // find kf2 and kf3 and do interpolation + var frame; + // In the easing function like elasticOut, percent may less than 0 + if (percent < 0) { + frame = 0; + } else if (percent < lastFramePercent) { + // Start from next key + // PENDING start from lastFrame ? + start = Math.min(lastFrame + 1, trackLen - 1); + for (frame = start; frame >= 0; frame--) { + if (kfPercents[frame] <= percent) { + break; + } + } + // PENDING really need to do this ? + frame = Math.min(frame, trackLen - 2); + } else { + for (frame = lastFrame; frame < trackLen; frame++) { + if (kfPercents[frame] > percent) { + break; + } + } + frame = Math.min(frame - 1, trackLen - 2); + } + lastFrame = frame; + lastFramePercent = percent; + + var range = (kfPercents[frame + 1] - kfPercents[frame]); + if (range === 0) { + return; + } else { + w = (percent - kfPercents[frame]) / range; + } + if (useSpline) { + p1 = kfValues[frame]; + p0 = kfValues[frame === 0 ? frame : frame - 1]; + p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1]; + p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2]; + if (isValueArray) { + catmullRomInterpolateArray( + p0, p1, p2, p3, w, w * w, w * w * w, + getter(target, propName), + arrDim + ); + } else { + var value; + if (isValueColor) { + value = catmullRomInterpolateArray( + p0, p1, p2, p3, w, w * w, w * w * w, + rgba, 1 + ); + value = rgba2String(rgba); + } else if (isValueString) { + // String is step(0.5) + return interpolateString(p1, p2, w); + } else { + value = catmullRomInterpolate( + p0, p1, p2, p3, w, w * w, w * w * w + ); + } + setter( + target, + propName, + value + ); + } + } else { + if (isValueArray) { + interpolateArray( + kfValues[frame], kfValues[frame + 1], w, + getter(target, propName), + arrDim + ); + } else { + var value; + if (isValueColor) { + interpolateArray( + kfValues[frame], kfValues[frame + 1], w, + rgba, 1 + ); + value = rgba2String(rgba); + } else if (isValueString) { + // String is step(0.5) + return interpolateString(kfValues[frame], kfValues[frame + 1], w); + } else { + value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w); + } + setter( + target, + propName, + value + ); + } + } + }; + + var clip = new Clip({ + target: animator._target, + life: trackMaxTime, + loop: animator._loop, + delay: animator._delay, + onframe: onframe, + ondestroy: oneTrackDone + }); + + if (easing && easing !== 'spline') { + clip.easing = easing; + } + + return clip; + } + + /** + * @alias module:zrender/animation/Animator + * @constructor + * @param {Object} target + * @param {boolean} loop + * @param {Function} getter + * @param {Function} setter + */ + var Animator = function(target, loop, getter, setter) { + this._tracks = {}; + this._target = target; + + this._loop = loop || false; + + this._getter = getter || defaultGetter; + this._setter = setter || defaultSetter; + + this._clipCount = 0; + + this._delay = 0; + + this._doneList = []; + + this._onframeList = []; + + this._clipList = []; + }; + + Animator.prototype = { + /** + * 设置动画关键帧 + * @param {number} time 关键帧时间,单位是ms + * @param {Object} props 关键帧的属性值,key-value表示 + * @return {module:zrender/animation/Animator} + */ + when: function(time /* ms */ , props) { + var tracks = this._tracks; + for (var propName in props) { + if (!props.hasOwnProperty(propName)) { + continue; + } + + if (!tracks[propName]) { + tracks[propName] = []; + // Invalid value + var value = this._getter(this._target, propName); + if (value == null) { + // zrLog('Invalid property ' + propName); + continue; + } + // If time is 0 + // Then props is given initialize value + // Else + // Initialize value from current prop value + if (time !== 0) { + tracks[propName].push({ + time: 0, + value: cloneValue(value) + }); + } + } + tracks[propName].push({ + time: time, + value: props[propName] + }); + } + return this; + }, + /** + * 添加动画每一帧的回调函数 + * @param {Function} callback + * @return {module:zrender/animation/Animator} + */ + during: function(callback) { + this._onframeList.push(callback); + return this; + }, + + pause: function() { + for (var i = 0; i < this._clipList.length; i++) { + this._clipList[i].pause(); + } + this._paused = true; + }, + + resume: function() { + for (var i = 0; i < this._clipList.length; i++) { + this._clipList[i].resume(); + } + this._paused = false; + }, + + isPaused: function() { + return !!this._paused; + }, + + _doneCallback: function() { + // Clear all tracks + this._tracks = {}; + // Clear all clips + this._clipList.length = 0; + + var doneList = this._doneList; + var len = doneList.length; + for (var i = 0; i < len; i++) { + doneList[i].call(this); + } + }, + /** + * 开始执行动画 + * @param {string|Function} [easing] + * 动画缓动函数,详见{@link module:zrender/animation/easing} + * @param {boolean} forceAnimate + * @return {module:zrender/animation/Animator} + */ + start: function(easing, forceAnimate) { + + var self = this; + var clipCount = 0; + + var oneTrackDone = function() { + clipCount--; + if (!clipCount) { + self._doneCallback(); + } + }; + + var lastClip; + for (var propName in this._tracks) { + if (!this._tracks.hasOwnProperty(propName)) { + continue; + } + var clip = createTrackClip( + this, easing, oneTrackDone, + this._tracks[propName], propName, forceAnimate + ); + if (clip) { + this._clipList.push(clip); + clipCount++; + + // If start after added to animation + if (this.animation) { + this.animation.addClip(clip); + } + + lastClip = clip; + } + } + + // Add during callback on the last clip + if (lastClip) { + var oldOnFrame = lastClip.onframe; + lastClip.onframe = function(target, percent) { + oldOnFrame(target, percent); + + for (var i = 0; i < self._onframeList.length; i++) { + self._onframeList[i](target, percent); + } + }; + } + + // This optimization will help the case that in the upper application + // the view may be refreshed frequently, where animation will be + // called repeatly but nothing changed. + if (!clipCount) { + this._doneCallback(); + } + return this; + }, + /** + * 停止动画 + * @param {boolean} forwardToLast If move to last frame before stop + */ + stop: function(forwardToLast) { + var clipList = this._clipList; + var animation = this.animation; + for (var i = 0; i < clipList.length; i++) { + var clip = clipList[i]; + if (forwardToLast) { + // Move to last frame before stop + clip.onframe(this._target, 1); + } + animation && animation.removeClip(clip); + } + clipList.length = 0; + }, + /** + * 设置动画延迟开始的时间 + * @param {number} time 单位ms + * @return {module:zrender/animation/Animator} + */ + delay: function(time) { + this._delay = time; + return this; + }, + /** + * 添加动画结束的回调 + * @param {Function} cb + * @return {module:zrender/animation/Animator} + */ + done: function(cb) { + if (cb) { + this._doneList.push(cb); + } + return this; + }, + + /** + * @return {Array.} + */ + getClips: function() { + return this._clipList; + } + }; + + var dpr = 1; + + // If in browser environment + if (typeof window !== 'undefined') { + dpr = Math.max(window.devicePixelRatio || 1, 1); + } + + /** + * config默认配置项 + * @exports zrender/config + * @author Kener (@Kener-林峰, kener.linfeng@gmail.com) + */ + + /** + * debug日志选项:catchBrushException为true下有效 + * 0 : 不生成debug数据,发布用 + * 1 : 异常抛出,调试用 + * 2 : 控制台输出,调试用 + */ + var debugMode = 0; + + // retina 屏幕优化 + var devicePixelRatio = dpr; + + var log = function() {}; + + if (debugMode === 1) { + log = function() { + for (var k in arguments) { + throw new Error(arguments[k]); + } + }; + } else if (debugMode > 1) { + log = function() { + for (var k in arguments) { + console.log(arguments[k]); + } + }; + } + + var zrLog = log; + + /** + * @alias modue:zrender/mixin/Animatable + * @constructor + */ + var Animatable = function() { + + /** + * @type {Array.} + * @readOnly + */ + this.animators = []; + }; + + Animatable.prototype = { + + constructor: Animatable, + + /** + * 动画 + * + * @param {string} path The path to fetch value from object, like 'a.b.c'. + * @param {boolean} [loop] Whether to loop animation. + * @return {module:zrender/animation/Animator} + * @example: + * el.animate('style', false) + * .when(1000, {x: 10} ) + * .done(function(){ // Animation done }) + * .start() + */ + animate: function(path, loop) { + var target; + var animatingShape = false; + var el = this; + var zr = this.__zr; + if (path) { + var pathSplitted = path.split('.'); + var prop = el; + // If animating shape + animatingShape = pathSplitted[0] === 'shape'; + for (var i = 0, l = pathSplitted.length; i < l; i++) { + if (!prop) { + continue; + } + prop = prop[pathSplitted[i]]; + } + if (prop) { + target = prop; + } + } else { + target = el; + } + + if (!target) { + zrLog( + 'Property "' + + path + + '" is not existed in element ' + + el.id + ); + return; + } + + var animators = el.animators; + + var animator = new Animator(target, loop); + + animator.during(function(target) { + el.dirty(animatingShape); + }) + .done(function() { + // FIXME Animator will not be removed if use `Animator#stop` to stop animation + animators.splice(indexOf(animators, animator), 1); + }); + + animators.push(animator); + + // If animate after added to the zrender + if (zr) { + zr.animation.addAnimator(animator); + } + + return animator; + }, + + /** + * 停止动画 + * @param {boolean} forwardToLast If move to last frame before stop + */ + stopAnimation: function(forwardToLast) { + var animators = this.animators; + var len = animators.length; + for (var i = 0; i < len; i++) { + animators[i].stop(forwardToLast); + } + animators.length = 0; + + return this; + }, + + /** + * Caution: this method will stop previous animation. + * So do not use this method to one element twice before + * animation starts, unless you know what you are doing. + * @param {Object} target + * @param {number} [time=500] Time in ms + * @param {string} [easing='linear'] + * @param {number} [delay=0] + * @param {Function} [callback] + * @param {Function} [forceAnimate] Prevent stop animation and callback + * immediently when target values are the same as current values. + * + * @example + * // Animate position + * el.animateTo({ + * position: [10, 10] + * }, function () { // done }) + * + * // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing + * el.animateTo({ + * shape: { + * width: 500 + * }, + * style: { + * fill: 'red' + * } + * position: [10, 10] + * }, 100, 100, 'cubicOut', function () { // done }) + */ + // TODO Return animation key + animateTo: function(target, time, delay, easing, callback, forceAnimate) { + // animateTo(target, time, easing, callback); + if (isString(delay)) { + callback = easing; + easing = delay; + delay = 0; + } + // animateTo(target, time, delay, callback); + else if (isFunction$1(easing)) { + callback = easing; + easing = 'linear'; + delay = 0; + } + // animateTo(target, time, callback); + else if (isFunction$1(delay)) { + callback = delay; + delay = 0; + } + // animateTo(target, callback) + else if (isFunction$1(time)) { + callback = time; + time = 500; + } + // animateTo(target) + else if (!time) { + time = 500; + } + // Stop all previous animations + this.stopAnimation(); + this._animateToShallow('', this, target, time, delay); + + // Animators may be removed immediately after start + // if there is nothing to animate + var animators = this.animators.slice(); + var count = animators.length; + + function done() { + count--; + if (!count) { + callback && callback(); + } + } + + // No animators. This should be checked before animators[i].start(), + // because 'done' may be executed immediately if no need to animate. + if (!count) { + callback && callback(); + } + // Start after all animators created + // Incase any animator is done immediately when all animation properties are not changed + for (var i = 0; i < animators.length; i++) { + animators[i] + .done(done) + .start(easing, forceAnimate); + } + }, + + /** + * @private + * @param {string} path='' + * @param {Object} source=this + * @param {Object} target + * @param {number} [time=500] + * @param {number} [delay=0] + * + * @example + * // Animate position + * el._animateToShallow({ + * position: [10, 10] + * }) + * + * // Animate shape, style and position in 100ms, delayed 100ms + * el._animateToShallow({ + * shape: { + * width: 500 + * }, + * style: { + * fill: 'red' + * } + * position: [10, 10] + * }, 100, 100) + */ + _animateToShallow: function(path, source, target, time, delay) { + var objShallow = {}; + var propertyCount = 0; + for (var name in target) { + if (!target.hasOwnProperty(name)) { + continue; + } + + if (source[name] != null) { + if (isObject$1(target[name]) && !isArrayLike(target[name])) { + this._animateToShallow( + path ? path + '.' + name : name, + source[name], + target[name], + time, + delay + ); + } else { + objShallow[name] = target[name]; + propertyCount++; + } + } else if (target[name] != null) { + // Attr directly if not has property + // FIXME, if some property not needed for element ? + if (!path) { + this.attr(name, target[name]); + } else { // Shape or style + var props = {}; + props[path] = {}; + props[path][name] = target[name]; + this.attr(props); + } + } + } + + if (propertyCount > 0) { + this.animate(path, false) + .when(time == null ? 500 : time, objShallow) + .delay(delay || 0); + } + + return this; + } + }; + + /** + * @alias module:zrender/Element + * @constructor + * @extends {module:zrender/mixin/Animatable} + * @extends {module:zrender/mixin/Transformable} + * @extends {module:zrender/mixin/Eventful} + */ + var Element = function(opts) { // jshint ignore:line + + Transformable.call(this, opts); + Eventful.call(this, opts); + Animatable.call(this, opts); + + /** + * 画布元素ID + * @type {string} + */ + this.id = opts.id || guid(); + }; + + Element.prototype = { + + /** + * 元素类型 + * Element type + * @type {string} + */ + type: 'element', + + /** + * 元素名字 + * Element name + * @type {string} + */ + name: '', + + /** + * ZRender 实例对象,会在 element 添加到 zrender 实例中后自动赋值 + * ZRender instance will be assigned when element is associated with zrender + * @name module:/zrender/Element#__zr + * @type {module:zrender/ZRender} + */ + __zr: null, + + /** + * 图形是否忽略,为true时忽略图形的绘制以及事件触发 + * If ignore drawing and events of the element object + * @name module:/zrender/Element#ignore + * @type {boolean} + * @default false + */ + ignore: false, + + /** + * 用于裁剪的路径(shape),所有 Group 内的路径在绘制时都会被这个路径裁剪 + * 该路径会继承被裁减对象的变换 + * @type {module:zrender/graphic/Path} + * @see http://www.w3.org/TR/2dcontext/#clipping-region + * @readOnly + */ + clipPath: null, + + /** + * 是否是 Group + * @type {boolean} + */ + isGroup: false, + + /** + * Drift element + * @param {number} dx dx on the global space + * @param {number} dy dy on the global space + */ + drift: function(dx, dy) { + switch (this.draggable) { + case 'horizontal': + dy = 0; + break; + case 'vertical': + dx = 0; + break; + } + + var m = this.transform; + if (!m) { + m = this.transform = [1, 0, 0, 1, 0, 0]; + } + m[4] += dx; + m[5] += dy; + + this.decomposeTransform(); + this.dirty(false); + }, + + /** + * Hook before update + */ + beforeUpdate: function() {}, + /** + * Hook after update + */ + afterUpdate: function() {}, + /** + * Update each frame + */ + update: function() { + this.updateTransform(); + }, + + /** + * @param {Function} cb + * @param {} context + */ + traverse: function(cb, context) {}, + + /** + * @protected + */ + attrKV: function(key, value) { + if (key === 'position' || key === 'scale' || key === 'origin') { + // Copy the array + if (value) { + var target = this[key]; + if (!target) { + target = this[key] = []; + } + target[0] = value[0]; + target[1] = value[1]; + } + } else { + this[key] = value; + } + }, + + /** + * Hide the element + */ + hide: function() { + this.ignore = true; + this.__zr && this.__zr.refresh(); + }, + + /** + * Show the element + */ + show: function() { + this.ignore = false; + this.__zr && this.__zr.refresh(); + }, + + /** + * @param {string|Object} key + * @param {*} value + */ + attr: function(key, value) { + if (typeof key === 'string') { + this.attrKV(key, value); + } else if (isObject$1(key)) { + for (var name in key) { + if (key.hasOwnProperty(name)) { + this.attrKV(name, key[name]); + } + } + } + + this.dirty(false); + + return this; + }, + + /** + * @param {module:zrender/graphic/Path} clipPath + */ + setClipPath: function(clipPath) { + var zr = this.__zr; + if (zr) { + clipPath.addSelfToZr(zr); + } + + // Remove previous clip path + if (this.clipPath && this.clipPath !== clipPath) { + this.removeClipPath(); + } + + this.clipPath = clipPath; + clipPath.__zr = zr; + clipPath.__clipTarget = this; + + this.dirty(false); + }, + + /** + */ + removeClipPath: function() { + var clipPath = this.clipPath; + if (clipPath) { + if (clipPath.__zr) { + clipPath.removeSelfFromZr(clipPath.__zr); + } + + clipPath.__zr = null; + clipPath.__clipTarget = null; + this.clipPath = null; + + this.dirty(false); + } + }, + + /** + * Add self from zrender instance. + * Not recursively because it will be invoked when element added to storage. + * @param {module:zrender/ZRender} zr + */ + addSelfToZr: function(zr) { + this.__zr = zr; + // 添加动画 + var animators = this.animators; + if (animators) { + for (var i = 0; i < animators.length; i++) { + zr.animation.addAnimator(animators[i]); + } + } + + if (this.clipPath) { + this.clipPath.addSelfToZr(zr); + } + }, + + /** + * Remove self from zrender instance. + * Not recursively because it will be invoked when element added to storage. + * @param {module:zrender/ZRender} zr + */ + removeSelfFromZr: function(zr) { + this.__zr = null; + // 移除动画 + var animators = this.animators; + if (animators) { + for (var i = 0; i < animators.length; i++) { + zr.animation.removeAnimator(animators[i]); + } + } + + if (this.clipPath) { + this.clipPath.removeSelfFromZr(zr); + } + } + }; + + mixin(Element, Animatable); + mixin(Element, Transformable); + mixin(Element, Eventful); + + /** + * @module echarts/core/BoundingRect + */ + + var v2ApplyTransform = applyTransform; + var mathMin = Math.min; + var mathMax = Math.max; + + /** + * @alias module:echarts/core/BoundingRect + */ + function BoundingRect(x, y, width, height) { + + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } + + /** + * @type {number} + */ + this.x = x; + /** + * @type {number} + */ + this.y = y; + /** + * @type {number} + */ + this.width = width; + /** + * @type {number} + */ + this.height = height; + } + + BoundingRect.prototype = { + + constructor: BoundingRect, + + /** + * @param {module:echarts/core/BoundingRect} other + */ + union: function(other) { + var x = mathMin(other.x, this.x); + var y = mathMin(other.y, this.y); + + this.width = mathMax( + other.x + other.width, + this.x + this.width + ) - x; + this.height = mathMax( + other.y + other.height, + this.y + this.height + ) - y; + this.x = x; + this.y = y; + }, + + /** + * @param {Array.} m + * @methods + */ + applyTransform: (function() { + var lt = []; + var rb = []; + var lb = []; + var rt = []; + return function(m) { + // In case usage like this + // el.getBoundingRect().applyTransform(el.transform) + // And element has no transform + if (!m) { + return; + } + lt[0] = lb[0] = this.x; + lt[1] = rt[1] = this.y; + rb[0] = rt[0] = this.x + this.width; + rb[1] = lb[1] = this.y + this.height; + + v2ApplyTransform(lt, lt, m); + v2ApplyTransform(rb, rb, m); + v2ApplyTransform(lb, lb, m); + v2ApplyTransform(rt, rt, m); + + this.x = mathMin(lt[0], rb[0], lb[0], rt[0]); + this.y = mathMin(lt[1], rb[1], lb[1], rt[1]); + var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]); + var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]); + this.width = maxX - this.x; + this.height = maxY - this.y; + }; + })(), + + /** + * Calculate matrix of transforming from self to target rect + * @param {module:zrender/core/BoundingRect} b + * @return {Array.} + */ + calculateTransform: function(b) { + var a = this; + var sx = b.width / a.width; + var sy = b.height / a.height; + + var m = create$1(); + + // 矩阵右乘 + translate(m, m, [-a.x, -a.y]); + scale$1(m, m, [sx, sy]); + translate(m, m, [b.x, b.y]); + + return m; + }, + + /** + * @param {(module:echarts/core/BoundingRect|Object)} b + * @return {boolean} + */ + intersect: function(b) { + if (!b) { + return false; + } + + if (!(b instanceof BoundingRect)) { + // Normalize negative width/height. + b = BoundingRect.create(b); + } + + var a = this; + var ax0 = a.x; + var ax1 = a.x + a.width; + var ay0 = a.y; + var ay1 = a.y + a.height; + + var bx0 = b.x; + var bx1 = b.x + b.width; + var by0 = b.y; + var by1 = b.y + b.height; + + return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0); + }, + + contain: function(x, y) { + var rect = this; + return x >= rect.x && + x <= (rect.x + rect.width) && + y >= rect.y && + y <= (rect.y + rect.height); + }, + + /** + * @return {module:echarts/core/BoundingRect} + */ + clone: function() { + return new BoundingRect(this.x, this.y, this.width, this.height); + }, + + /** + * Copy from another rect + */ + copy: function(other) { + this.x = other.x; + this.y = other.y; + this.width = other.width; + this.height = other.height; + }, + + plain: function() { + return { + x: this.x, + y: this.y, + width: this.width, + height: this.height + }; + } + }; + + /** + * @param {Object|module:zrender/core/BoundingRect} rect + * @param {number} rect.x + * @param {number} rect.y + * @param {number} rect.width + * @param {number} rect.height + * @return {module:zrender/core/BoundingRect} + */ + BoundingRect.create = function(rect) { + return new BoundingRect(rect.x, rect.y, rect.width, rect.height); + }; + + /** + * Group是一个容器,可以插入子节点,Group的变换也会被应用到子节点上 + * @module zrender/graphic/Group + * @example + * var Group = require('zrender/container/Group'); + * var Circle = require('zrender/graphic/shape/Circle'); + * var g = new Group(); + * g.position[0] = 100; + * g.position[1] = 100; + * g.add(new Circle({ + * style: { + * x: 100, + * y: 100, + * r: 20, + * } + * })); + * zr.add(g); + */ + + /** + * @alias module:zrender/graphic/Group + * @constructor + * @extends module:zrender/mixin/Transformable + * @extends module:zrender/mixin/Eventful + */ + var Group = function(opts) { + + opts = opts || {}; + + Element.call(this, opts); + + for (var key in opts) { + if (opts.hasOwnProperty(key)) { + this[key] = opts[key]; + } + } + + this._children = []; + + this.__storage = null; + + this.__dirty = true; + }; + + Group.prototype = { + + constructor: Group, + + isGroup: true, + + /** + * @type {string} + */ + type: 'group', + + /** + * 所有子孙元素是否响应鼠标事件 + * @name module:/zrender/container/Group#silent + * @type {boolean} + * @default false + */ + silent: false, + + /** + * @return {Array.} + */ + children: function() { + return this._children.slice(); + }, + + /** + * 获取指定 index 的儿子节点 + * @param {number} idx + * @return {module:zrender/Element} + */ + childAt: function(idx) { + return this._children[idx]; + }, + + /** + * 获取指定名字的儿子节点 + * @param {string} name + * @return {module:zrender/Element} + */ + childOfName: function(name) { + var children = this._children; + for (var i = 0; i < children.length; i++) { + if (children[i].name === name) { + return children[i]; + } + } + }, + + /** + * @return {number} + */ + childCount: function() { + return this._children.length; + }, + + /** + * 添加子节点到最后 + * @param {module:zrender/Element} child + */ + add: function(child) { + if (child && child !== this && child.parent !== this) { + + this._children.push(child); + + this._doAdd(child); + } + + return this; + }, + + /** + * 添加子节点在 nextSibling 之前 + * @param {module:zrender/Element} child + * @param {module:zrender/Element} nextSibling + */ + addBefore: function(child, nextSibling) { + if (child && child !== this && child.parent !== this && + nextSibling && nextSibling.parent === this) { + + var children = this._children; + var idx = children.indexOf(nextSibling); + + if (idx >= 0) { + children.splice(idx, 0, child); + this._doAdd(child); + } + } + + return this; + }, + + _doAdd: function(child) { + if (child.parent) { + child.parent.remove(child); + } + + child.parent = this; + + var storage = this.__storage; + var zr = this.__zr; + if (storage && storage !== child.__storage) { + + storage.addToStorage(child); + + if (child instanceof Group) { + child.addChildrenToStorage(storage); + } + } + + zr && zr.refresh(); + }, + + /** + * 移除子节点 + * @param {module:zrender/Element} child + */ + remove: function(child) { + var zr = this.__zr; + var storage = this.__storage; + var children = this._children; + + var idx = indexOf(children, child); + if (idx < 0) { + return this; + } + children.splice(idx, 1); + + child.parent = null; + + if (storage) { + + storage.delFromStorage(child); + + if (child instanceof Group) { + child.delChildrenFromStorage(storage); + } + } + + zr && zr.refresh(); + + return this; + }, + + /** + * 移除所有子节点 + */ + removeAll: function() { + var children = this._children; + var storage = this.__storage; + var child; + var i; + for (i = 0; i < children.length; i++) { + child = children[i]; + if (storage) { + storage.delFromStorage(child); + if (child instanceof Group) { + child.delChildrenFromStorage(storage); + } + } + child.parent = null; + } + children.length = 0; + + return this; + }, + + /** + * 遍历所有子节点 + * @param {Function} cb + * @param {} context + */ + eachChild: function(cb, context) { + var children = this._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + cb.call(context, child, i); + } + return this; + }, + + /** + * 深度优先遍历所有子孙节点 + * @param {Function} cb + * @param {} context + */ + traverse: function(cb, context) { + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + cb.call(context, child); + + if (child.type === 'group') { + child.traverse(cb, context); + } + } + return this; + }, + + addChildrenToStorage: function(storage) { + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + storage.addToStorage(child); + if (child instanceof Group) { + child.addChildrenToStorage(storage); + } + } + }, + + delChildrenFromStorage: function(storage) { + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + storage.delFromStorage(child); + if (child instanceof Group) { + child.delChildrenFromStorage(storage); + } + } + }, + + dirty: function() { + this.__dirty = true; + this.__zr && this.__zr.refresh(); + return this; + }, + + /** + * @return {module:zrender/core/BoundingRect} + */ + getBoundingRect: function(includeChildren) { + // TODO Caching + var rect = null; + var tmpRect = new BoundingRect(0, 0, 0, 0); + var children = includeChildren || this._children; + var tmpMat = []; + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.ignore || child.invisible) { + continue; + } + + var childRect = child.getBoundingRect(); + var transform = child.getLocalTransform(tmpMat); + // TODO + // The boundingRect cacluated by transforming original + // rect may be bigger than the actual bundingRect when rotation + // is used. (Consider a circle rotated aginst its center, where + // the actual boundingRect should be the same as that not be + // rotated.) But we can not find better approach to calculate + // actual boundingRect yet, considering performance. + if (transform) { + tmpRect.copy(childRect); + tmpRect.applyTransform(transform); + rect = rect || tmpRect.clone(); + rect.union(tmpRect); + } else { + rect = rect || childRect.clone(); + rect.union(childRect); + } + } + return rect || tmpRect; + } + }; + + inherits(Group, Element); + + // https://github.com/mziccard/node-timsort + var DEFAULT_MIN_MERGE = 32; + + var DEFAULT_MIN_GALLOPING = 7; + + function minRunLength(n) { + var r = 0; + + while (n >= DEFAULT_MIN_MERGE) { + r |= n & 1; + n >>= 1; + } + + return n + r; + } + + function makeAscendingRun(array, lo, hi, compare) { + var runHi = lo + 1; + + if (runHi === hi) { + return 1; + } + + if (compare(array[runHi++], array[lo]) < 0) { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) { + runHi++; + } + + reverseRun(array, lo, runHi); + } else { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) { + runHi++; + } + } + + return runHi - lo; + } + + function reverseRun(array, lo, hi) { + hi--; + + while (lo < hi) { + var t = array[lo]; + array[lo++] = array[hi]; + array[hi--] = t; + } + } + + function binaryInsertionSort(array, lo, hi, start, compare) { + if (start === lo) { + start++; + } + + for (; start < hi; start++) { + var pivot = array[start]; + + var left = lo; + var right = start; + var mid; + + while (left < right) { + mid = left + right >>> 1; + + if (compare(pivot, array[mid]) < 0) { + right = mid; + } else { + left = mid + 1; + } + } + + var n = start - left; + + switch (n) { + case 3: + array[left + 3] = array[left + 2]; + + case 2: + array[left + 2] = array[left + 1]; + + case 1: + array[left + 1] = array[left]; + break; + default: + while (n > 0) { + array[left + n] = array[left + n - 1]; + n--; + } + } + + array[left] = pivot; + } + } + + function gallopLeft(value, array, start, length, hint, compare) { + var lastOffset = 0; + var maxOffset = 0; + var offset = 1; + + if (compare(value, array[start + hint]) > 0) { + maxOffset = length - hint; + + while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + + if (offset <= 0) { + offset = maxOffset; + } + } + + if (offset > maxOffset) { + offset = maxOffset; + } + + lastOffset += hint; + offset += hint; + } else { + maxOffset = hint + 1; + while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + + if (offset <= 0) { + offset = maxOffset; + } + } + if (offset > maxOffset) { + offset = maxOffset; + } + + var tmp = lastOffset; + lastOffset = hint - offset; + offset = hint - tmp; + } + + lastOffset++; + while (lastOffset < offset) { + var m = lastOffset + (offset - lastOffset >>> 1); + + if (compare(value, array[start + m]) > 0) { + lastOffset = m + 1; + } else { + offset = m; + } + } + return offset; + } + + function gallopRight(value, array, start, length, hint, compare) { + var lastOffset = 0; + var maxOffset = 0; + var offset = 1; + + if (compare(value, array[start + hint]) < 0) { + maxOffset = hint + 1; + + while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + + if (offset <= 0) { + offset = maxOffset; + } + } + + if (offset > maxOffset) { + offset = maxOffset; + } + + var tmp = lastOffset; + lastOffset = hint - offset; + offset = hint - tmp; + } else { + maxOffset = length - hint; + + while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + + if (offset <= 0) { + offset = maxOffset; + } + } + + if (offset > maxOffset) { + offset = maxOffset; + } + + lastOffset += hint; + offset += hint; + } + + lastOffset++; + + while (lastOffset < offset) { + var m = lastOffset + (offset - lastOffset >>> 1); + + if (compare(value, array[start + m]) < 0) { + offset = m; + } else { + lastOffset = m + 1; + } + } + + return offset; + } + + function TimSort(array, compare) { + var minGallop = DEFAULT_MIN_GALLOPING; + var runStart; + var runLength; + var stackSize = 0; + + var tmp = []; + + runStart = []; + runLength = []; + + function pushRun(_runStart, _runLength) { + runStart[stackSize] = _runStart; + runLength[stackSize] = _runLength; + stackSize += 1; + } + + function mergeRuns() { + while (stackSize > 1) { + var n = stackSize - 2; + + if (n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1] || n >= 2 && runLength[n - 2] <= runLength[n] + + runLength[n - 1]) { + if (runLength[n - 1] < runLength[n + 1]) { + n--; + } + } else if (runLength[n] > runLength[n + 1]) { + break; + } + mergeAt(n); + } + } + + function forceMergeRuns() { + while (stackSize > 1) { + var n = stackSize - 2; + + if (n > 0 && runLength[n - 1] < runLength[n + 1]) { + n--; + } + + mergeAt(n); + } + } + + function mergeAt(i) { + var start1 = runStart[i]; + var length1 = runLength[i]; + var start2 = runStart[i + 1]; + var length2 = runLength[i + 1]; + + runLength[i] = length1 + length2; + + if (i === stackSize - 3) { + runStart[i + 1] = runStart[i + 2]; + runLength[i + 1] = runLength[i + 2]; + } + + stackSize--; + + var k = gallopRight(array[start2], array, start1, length1, 0, compare); + start1 += k; + length1 -= k; + + if (length1 === 0) { + return; + } + + length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare); + + if (length2 === 0) { + return; + } + + if (length1 <= length2) { + mergeLow(start1, length1, start2, length2); + } else { + mergeHigh(start1, length1, start2, length2); + } + } + + function mergeLow(start1, length1, start2, length2) { + var i = 0; + + for (i = 0; i < length1; i++) { + tmp[i] = array[start1 + i]; + } + + var cursor1 = 0; + var cursor2 = start2; + var dest = start1; + + array[dest++] = array[cursor2++]; + + if (--length2 === 0) { + for (i = 0; i < length1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + return; + } + + if (length1 === 1) { + for (i = 0; i < length2; i++) { + array[dest + i] = array[cursor2 + i]; + } + array[dest + length2] = tmp[cursor1]; + return; + } + + var _minGallop = minGallop; + var count1, count2, exit; + + while (1) { + count1 = 0; + count2 = 0; + exit = false; + + do { + if (compare(array[cursor2], tmp[cursor1]) < 0) { + array[dest++] = array[cursor2++]; + count2++; + count1 = 0; + + if (--length2 === 0) { + exit = true; + break; + } + } else { + array[dest++] = tmp[cursor1++]; + count1++; + count2 = 0; + if (--length1 === 1) { + exit = true; + break; + } + } + } while ((count1 | count2) < _minGallop); + + if (exit) { + break; + } + + do { + count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare); + + if (count1 !== 0) { + for (i = 0; i < count1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + + dest += count1; + cursor1 += count1; + length1 -= count1; + if (length1 <= 1) { + exit = true; + break; + } + } + + array[dest++] = array[cursor2++]; + + if (--length2 === 0) { + exit = true; + break; + } + + count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare); + + if (count2 !== 0) { + for (i = 0; i < count2; i++) { + array[dest + i] = array[cursor2 + i]; + } + + dest += count2; + cursor2 += count2; + length2 -= count2; + + if (length2 === 0) { + exit = true; + break; + } + } + array[dest++] = tmp[cursor1++]; + + if (--length1 === 1) { + exit = true; + break; + } + + _minGallop--; + } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING); + + if (exit) { + break; + } + + if (_minGallop < 0) { + _minGallop = 0; + } + + _minGallop += 2; + } + + minGallop = _minGallop; + + minGallop < 1 && (minGallop = 1); + + if (length1 === 1) { + for (i = 0; i < length2; i++) { + array[dest + i] = array[cursor2 + i]; + } + array[dest + length2] = tmp[cursor1]; + } else if (length1 === 0) { + throw new Error(); + // throw new Error('mergeLow preconditions were not respected'); + } else { + for (i = 0; i < length1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + } + } + + function mergeHigh(start1, length1, start2, length2) { + var i = 0; + + for (i = 0; i < length2; i++) { + tmp[i] = array[start2 + i]; + } + + var cursor1 = start1 + length1 - 1; + var cursor2 = length2 - 1; + var dest = start2 + length2 - 1; + var customCursor = 0; + var customDest = 0; + + array[dest--] = array[cursor1--]; + + if (--length1 === 0) { + customCursor = dest - (length2 - 1); + + for (i = 0; i < length2; i++) { + array[customCursor + i] = tmp[i]; + } + + return; + } + + if (length2 === 1) { + dest -= length1; + cursor1 -= length1; + customDest = dest + 1; + customCursor = cursor1 + 1; + + for (i = length1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + + array[dest] = tmp[cursor2]; + return; + } + + var _minGallop = minGallop; + + while (true) { + var count1 = 0; + var count2 = 0; + var exit = false; + + do { + if (compare(tmp[cursor2], array[cursor1]) < 0) { + array[dest--] = array[cursor1--]; + count1++; + count2 = 0; + if (--length1 === 0) { + exit = true; + break; + } + } else { + array[dest--] = tmp[cursor2--]; + count2++; + count1 = 0; + if (--length2 === 1) { + exit = true; + break; + } + } + } while ((count1 | count2) < _minGallop); + + if (exit) { + break; + } + + do { + count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare); + + if (count1 !== 0) { + dest -= count1; + cursor1 -= count1; + length1 -= count1; + customDest = dest + 1; + customCursor = cursor1 + 1; + + for (i = count1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + + if (length1 === 0) { + exit = true; + break; + } + } + + array[dest--] = tmp[cursor2--]; + + if (--length2 === 1) { + exit = true; + break; + } + + count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare); + + if (count2 !== 0) { + dest -= count2; + cursor2 -= count2; + length2 -= count2; + customDest = dest + 1; + customCursor = cursor2 + 1; + + for (i = 0; i < count2; i++) { + array[customDest + i] = tmp[customCursor + i]; + } + + if (length2 <= 1) { + exit = true; + break; + } + } + + array[dest--] = array[cursor1--]; + + if (--length1 === 0) { + exit = true; + break; + } + + _minGallop--; + } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING); + + if (exit) { + break; + } + + if (_minGallop < 0) { + _minGallop = 0; + } + + _minGallop += 2; + } + + minGallop = _minGallop; + + if (minGallop < 1) { + minGallop = 1; + } + + if (length2 === 1) { + dest -= length1; + cursor1 -= length1; + customDest = dest + 1; + customCursor = cursor1 + 1; + + for (i = length1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + + array[dest] = tmp[cursor2]; + } else if (length2 === 0) { + throw new Error(); + // throw new Error('mergeHigh preconditions were not respected'); + } else { + customCursor = dest - (length2 - 1); + for (i = 0; i < length2; i++) { + array[customCursor + i] = tmp[i]; + } + } + } + + this.mergeRuns = mergeRuns; + this.forceMergeRuns = forceMergeRuns; + this.pushRun = pushRun; + } + + function sort(array, compare, lo, hi) { + if (!lo) { + lo = 0; + } + if (!hi) { + hi = array.length; + } + + var remaining = hi - lo; + + if (remaining < 2) { + return; + } + + var runLength = 0; + + if (remaining < DEFAULT_MIN_MERGE) { + runLength = makeAscendingRun(array, lo, hi, compare); + binaryInsertionSort(array, lo, hi, lo + runLength, compare); + return; + } + + var ts = new TimSort(array, compare); + + var minRun = minRunLength(remaining); + + do { + runLength = makeAscendingRun(array, lo, hi, compare); + if (runLength < minRun) { + var force = remaining; + if (force > minRun) { + force = minRun; + } + + binaryInsertionSort(array, lo, lo + force, lo + runLength, compare); + runLength = force; + } + + ts.pushRun(lo, runLength); + ts.mergeRuns(); + + remaining -= runLength; + lo += runLength; + } while (remaining !== 0); + + ts.forceMergeRuns(); + } + + // Use timsort because in most case elements are partially sorted + // https://jsfiddle.net/pissang/jr4x7mdm/8/ + function shapeCompareFunc(a, b) { + if (a.zlevel === b.zlevel) { + if (a.z === b.z) { + // if (a.z2 === b.z2) { + // // FIXME Slow has renderidx compare + // // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement + // // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012 + // return a.__renderidx - b.__renderidx; + // } + return a.z2 - b.z2; + } + return a.z - b.z; + } + return a.zlevel - b.zlevel; + } + /** + * 内容仓库 (M) + * @alias module:zrender/Storage + * @constructor + */ + var Storage = function() { // jshint ignore:line + this._roots = []; + + this._displayList = []; + + this._displayListLen = 0; + }; + + Storage.prototype = { + + constructor: Storage, + + /** + * @param {Function} cb + * + */ + traverse: function(cb, context) { + for (var i = 0; i < this._roots.length; i++) { + this._roots[i].traverse(cb, context); + } + }, + + /** + * 返回所有图形的绘制队列 + * @param {boolean} [update=false] 是否在返回前更新该数组 + * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组, 在 update 为 true 的时候有效 + * + * 详见{@link module:zrender/graphic/Displayable.prototype.updateDisplayList} + * @return {Array.} + */ + getDisplayList: function(update, includeIgnore) { + includeIgnore = includeIgnore || false; + if (update) { + this.updateDisplayList(includeIgnore); + } + return this._displayList; + }, + + /** + * 更新图形的绘制队列。 + * 每次绘制前都会调用,该方法会先深度优先遍历整个树,更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中, + * 最后根据绘制的优先级(zlevel > z > 插入顺序)排序得到绘制队列 + * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组 + */ + updateDisplayList: function(includeIgnore) { + this._displayListLen = 0; + + var roots = this._roots; + var displayList = this._displayList; + for (var i = 0, len = roots.length; i < len; i++) { + this._updateAndAddDisplayable(roots[i], null, includeIgnore); + } + + displayList.length = this._displayListLen; + + env$1.canvasSupported && sort(displayList, shapeCompareFunc); + }, + + _updateAndAddDisplayable: function(el, clipPaths, includeIgnore) { + + if (el.ignore && !includeIgnore) { + return; + } + + el.beforeUpdate(); + + if (el.__dirty) { + + el.update(); + + } + + el.afterUpdate(); + + var userSetClipPath = el.clipPath; + if (userSetClipPath) { + + // FIXME 效率影响 + if (clipPaths) { + clipPaths = clipPaths.slice(); + } else { + clipPaths = []; + } + + var currentClipPath = userSetClipPath; + var parentClipPath = el; + // Recursively add clip path + while (currentClipPath) { + // clipPath 的变换是基于使用这个 clipPath 的元素 + currentClipPath.parent = parentClipPath; + currentClipPath.updateTransform(); + + clipPaths.push(currentClipPath); + + parentClipPath = currentClipPath; + currentClipPath = currentClipPath.clipPath; + } + } + + if (el.isGroup) { + var children = el._children; + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + + // Force to mark as dirty if group is dirty + // FIXME __dirtyPath ? + if (el.__dirty) { + child.__dirty = true; + } + + this._updateAndAddDisplayable(child, clipPaths, includeIgnore); + } + + // Mark group clean here + el.__dirty = false; + + } else { + el.__clipPaths = clipPaths; + + this._displayList[this._displayListLen++] = el; + } + }, + + /** + * 添加图形(Shape)或者组(Group)到根节点 + * @param {module:zrender/Element} el + */ + addRoot: function(el) { + if (el.__storage === this) { + return; + } + + if (el instanceof Group) { + el.addChildrenToStorage(this); + } + + this.addToStorage(el); + this._roots.push(el); + }, + + /** + * 删除指定的图形(Shape)或者组(Group) + * @param {string|Array.} [el] 如果为空清空整个Storage + */ + delRoot: function(el) { + if (el == null) { + // 不指定el清空 + for (var i = 0; i < this._roots.length; i++) { + var root = this._roots[i]; + if (root instanceof Group) { + root.delChildrenFromStorage(this); + } + } + + this._roots = []; + this._displayList = []; + this._displayListLen = 0; + + return; + } + + if (el instanceof Array) { + for (var i = 0, l = el.length; i < l; i++) { + this.delRoot(el[i]); + } + return; + } + + + var idx = indexOf(this._roots, el); + if (idx >= 0) { + this.delFromStorage(el); + this._roots.splice(idx, 1); + if (el instanceof Group) { + el.delChildrenFromStorage(this); + } + } + }, + + addToStorage: function(el) { + if (el) { + el.__storage = this; + el.dirty(false); + } + return this; + }, + + delFromStorage: function(el) { + if (el) { + el.__storage = null; + } + + return this; + }, + + /** + * 清空并且释放Storage + */ + dispose: function() { + this._renderList = + this._roots = null; + }, + + displayableSortFunc: shapeCompareFunc + }; + + var SHADOW_PROPS = { + 'shadowBlur': 1, + 'shadowOffsetX': 1, + 'shadowOffsetY': 1, + 'textShadowBlur': 1, + 'textShadowOffsetX': 1, + 'textShadowOffsetY': 1, + 'textBoxShadowBlur': 1, + 'textBoxShadowOffsetX': 1, + 'textBoxShadowOffsetY': 1 + }; + + var fixShadow = function(ctx, propName, value) { + if (SHADOW_PROPS.hasOwnProperty(propName)) { + return value *= ctx.dpr; + } + return value; + }; + + var STYLE_COMMON_PROPS = [ + ['shadowBlur', 0], + ['shadowOffsetX', 0], + ['shadowOffsetY', 0], + ['shadowColor', '#000'], + ['lineCap', 'butt'], + ['lineJoin', 'miter'], + ['miterLimit', 10] + ]; + + // var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4); + // var LINE_PROPS = STYLE_COMMON_PROPS.slice(4); + + var Style = function(opts, host) { + this.extendFrom(opts, false); + this.host = host; + }; + + function createLinearGradient(ctx, obj, rect) { + var x = obj.x == null ? 0 : obj.x; + var x2 = obj.x2 == null ? 1 : obj.x2; + var y = obj.y == null ? 0 : obj.y; + var y2 = obj.y2 == null ? 0 : obj.y2; + + if (!obj.global) { + x = x * rect.width + rect.x; + x2 = x2 * rect.width + rect.x; + y = y * rect.height + rect.y; + y2 = y2 * rect.height + rect.y; + } + + // Fix NaN when rect is Infinity + x = isNaN(x) ? 0 : x; + x2 = isNaN(x2) ? 1 : x2; + y = isNaN(y) ? 0 : y; + y2 = isNaN(y2) ? 0 : y2; + + var canvasGradient = ctx.createLinearGradient(x, y, x2, y2); + + return canvasGradient; + } + + function createRadialGradient(ctx, obj, rect) { + var width = rect.width; + var height = rect.height; + var min = Math.min(width, height); + + var x = obj.x == null ? 0.5 : obj.x; + var y = obj.y == null ? 0.5 : obj.y; + var r = obj.r == null ? 0.5 : obj.r; + if (!obj.global) { + x = x * width + rect.x; + y = y * height + rect.y; + r = r * min; + } + + var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r); + + return canvasGradient; + } + + + Style.prototype = { + + constructor: Style, + + /** + * @type {module:zrender/graphic/Displayable} + */ + host: null, + + /** + * @type {string} + */ + fill: '#000', + + /** + * @type {string} + */ + stroke: null, + + /** + * @type {number} + */ + opacity: 1, + + /** + * @type {Array.} + */ + lineDash: null, + + /** + * @type {number} + */ + lineDashOffset: 0, + + /** + * @type {number} + */ + shadowBlur: 0, + + /** + * @type {number} + */ + shadowOffsetX: 0, + + /** + * @type {number} + */ + shadowOffsetY: 0, + + /** + * @type {number} + */ + lineWidth: 1, + + /** + * If stroke ignore scale + * @type {Boolean} + */ + strokeNoScale: false, + + // Bounding rect text configuration + // Not affected by element transform + /** + * @type {string} + */ + text: null, + + /** + * If `fontSize` or `fontFamily` exists, `font` will be reset by + * `fontSize`, `fontStyle`, `fontWeight`, `fontFamily`. + * So do not visit it directly in upper application (like echarts), + * but use `contain/text#makeFont` instead. + * @type {string} + */ + font: null, + + /** + * The same as font. Use font please. + * @deprecated + * @type {string} + */ + textFont: null, + + /** + * It helps merging respectively, rather than parsing an entire font string. + * @type {string} + */ + fontStyle: null, + + /** + * It helps merging respectively, rather than parsing an entire font string. + * @type {string} + */ + fontWeight: null, + + /** + * It helps merging respectively, rather than parsing an entire font string. + * Should be 12 but not '12px'. + * @type {number} + */ + fontSize: null, + + /** + * It helps merging respectively, rather than parsing an entire font string. + * @type {string} + */ + fontFamily: null, + + /** + * Reserved for special functinality, like 'hr'. + * @type {string} + */ + textTag: null, + + /** + * @type {string} + */ + textFill: '#000', + + /** + * @type {string} + */ + textStroke: null, + + /** + * @type {number} + */ + textWidth: null, + + /** + * Only for textBackground. + * @type {number} + */ + textHeight: null, + + /** + * textStroke may be set as some color as a default + * value in upper applicaion, where the default value + * of textStrokeWidth should be 0 to make sure that + * user can choose to do not use text stroke. + * @type {number} + */ + textStrokeWidth: 0, + + /** + * @type {number} + */ + textLineHeight: null, + + /** + * 'inside', 'left', 'right', 'top', 'bottom' + * [x, y] + * Based on x, y of rect. + * @type {string|Array.} + * @default 'inside' + */ + textPosition: 'inside', + + /** + * If not specified, use the boundingRect of a `displayable`. + * @type {Object} + */ + textRect: null, + + /** + * [x, y] + * @type {Array.} + */ + textOffset: null, + + /** + * @type {string} + */ + textAlign: null, + + /** + * @type {string} + */ + textVerticalAlign: null, + + /** + * @type {number} + */ + textDistance: 5, + + /** + * @type {string} + */ + textShadowColor: 'transparent', + + /** + * @type {number} + */ + textShadowBlur: 0, + + /** + * @type {number} + */ + textShadowOffsetX: 0, + + /** + * @type {number} + */ + textShadowOffsetY: 0, + + /** + * @type {string} + */ + textBoxShadowColor: 'transparent', + + /** + * @type {number} + */ + textBoxShadowBlur: 0, + + /** + * @type {number} + */ + textBoxShadowOffsetX: 0, + + /** + * @type {number} + */ + textBoxShadowOffsetY: 0, + + /** + * Whether transform text. + * Only useful in Path and Image element + * @type {boolean} + */ + transformText: false, + + /** + * Text rotate around position of Path or Image + * Only useful in Path and Image element and transformText is false. + */ + textRotation: 0, + + /** + * Text origin of text rotation, like [10, 40]. + * Based on x, y of rect. + * Useful in label rotation of circular symbol. + * By default, this origin is textPosition. + * Can be 'center'. + * @type {string|Array.} + */ + textOrigin: null, + + /** + * @type {string} + */ + textBackgroundColor: null, + + /** + * @type {string} + */ + textBorderColor: null, + + /** + * @type {number} + */ + textBorderWidth: 0, + + /** + * @type {number} + */ + textBorderRadius: 0, + + /** + * Can be `2` or `[2, 4]` or `[2, 3, 4, 5]` + * @type {number|Array.} + */ + textPadding: null, + + /** + * Text styles for rich text. + * @type {Object} + */ + rich: null, + + /** + * {outerWidth, outerHeight, ellipsis, placeholder} + * @type {Object} + */ + truncate: null, + + /** + * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation + * @type {string} + */ + blend: null, + + /** + * @param {CanvasRenderingContext2D} ctx + */ + bind: function(ctx, el, prevEl) { + var style = this; + var prevStyle = prevEl && prevEl.style; + var firstDraw = !prevStyle; + + for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) { + var prop = STYLE_COMMON_PROPS[i]; + var styleName = prop[0]; + + if (firstDraw || style[styleName] !== prevStyle[styleName]) { + // FIXME Invalid property value will cause style leak from previous element. + ctx[styleName] = + fixShadow(ctx, styleName, style[styleName] || prop[1]); + } + } + + if ((firstDraw || style.fill !== prevStyle.fill)) { + ctx.fillStyle = style.fill; + } + if ((firstDraw || style.stroke !== prevStyle.stroke)) { + ctx.strokeStyle = style.stroke; + } + if ((firstDraw || style.opacity !== prevStyle.opacity)) { + ctx.globalAlpha = style.opacity == null ? 1 : style.opacity; + } + + if ((firstDraw || style.blend !== prevStyle.blend)) { + ctx.globalCompositeOperation = style.blend || 'source-over'; + } + if (this.hasStroke()) { + var lineWidth = style.lineWidth; + ctx.lineWidth = lineWidth / ( + (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1 + ); + } + }, + + hasFill: function() { + var fill = this.fill; + return fill != null && fill !== 'none'; + }, + + hasStroke: function() { + var stroke = this.stroke; + return stroke != null && stroke !== 'none' && this.lineWidth > 0; + }, + + /** + * Extend from other style + * @param {zrender/graphic/Style} otherStyle + * @param {boolean} overwrite true: overwrirte any way. + * false: overwrite only when !target.hasOwnProperty + * others: overwrite when property is not null/undefined. + */ + extendFrom: function(otherStyle, overwrite) { + if (otherStyle) { + for (var name in otherStyle) { + if (otherStyle.hasOwnProperty(name) && + (overwrite === true || + ( + overwrite === false ? + !this.hasOwnProperty(name) : + otherStyle[name] != null + ) + ) + ) { + this[name] = otherStyle[name]; + } + } + } + }, + + /** + * Batch setting style with a given object + * @param {Object|string} obj + * @param {*} [obj] + */ + set: function(obj, value) { + if (typeof obj === 'string') { + this[obj] = value; + } else { + this.extendFrom(obj, true); + } + }, + + /** + * Clone + * @return {zrender/graphic/Style} [description] + */ + clone: function() { + var newStyle = new this.constructor(); + newStyle.extendFrom(this, true); + return newStyle; + }, + + getGradient: function(ctx, obj, rect) { + var method = obj.type === 'radial' ? createRadialGradient : createLinearGradient; + var canvasGradient = method(ctx, obj, rect); + var colorStops = obj.colorStops; + for (var i = 0; i < colorStops.length; i++) { + canvasGradient.addColorStop( + colorStops[i].offset, colorStops[i].color + ); + } + return canvasGradient; + } + + }; + + var styleProto = Style.prototype; + for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) { + var prop = STYLE_COMMON_PROPS[i]; + if (!(prop[0] in styleProto)) { + styleProto[prop[0]] = prop[1]; + } + } + + // Provide for others + Style.getGradient = styleProto.getGradient; + + var Pattern = function(image, repeat) { + // Should do nothing more in this constructor. Because gradient can be + // declard by `color: {image: ...}`, where this constructor will not be called. + + this.image = image; + this.repeat = repeat; + + // Can be cloned + this.type = 'pattern'; + }; + + Pattern.prototype.getCanvasPattern = function(ctx) { + return ctx.createPattern(this.image, this.repeat || 'repeat'); + }; + + /** + * @module zrender/Layer + * @author pissang(https://www.github.com/pissang) + */ + + function returnFalse() { + return false; + } + + /** + * 创建dom + * + * @inner + * @param {string} id dom id 待用 + * @param {Painter} painter painter instance + * @param {number} number + */ + function createDom(id, painter, dpr) { + var newDom = createCanvas(); + var width = painter.getWidth(); + var height = painter.getHeight(); + + var newDomStyle = newDom.style; + if (newDomStyle) { // In node or some other non-browser environment + newDomStyle.position = 'absolute'; + newDomStyle.left = 0; + newDomStyle.top = 0; + newDomStyle.width = width + 'px'; + newDomStyle.height = height + 'px'; + + newDom.setAttribute('data-zr-dom-id', id); + } + + newDom.width = width * dpr; + newDom.height = height * dpr; + + return newDom; + } + + /** + * @alias module:zrender/Layer + * @constructor + * @extends module:zrender/mixin/Transformable + * @param {string} id + * @param {module:zrender/Painter} painter + * @param {number} [dpr] + */ + var Layer = function(id, painter, dpr) { + var dom; + dpr = dpr || devicePixelRatio; + if (typeof id === 'string') { + dom = createDom(id, painter, dpr); + } + // Not using isDom because in node it will return false + else if (isObject$1(id)) { + dom = id; + id = dom.id; + } + this.id = id; + this.dom = dom; + + var domStyle = dom.style; + if (domStyle) { // Not in node + dom.onselectstart = returnFalse; // 避免页面选中的尴尬 + domStyle['-webkit-user-select'] = 'none'; + domStyle['user-select'] = 'none'; + domStyle['-webkit-touch-callout'] = 'none'; + domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)'; + domStyle['padding'] = 0; + domStyle['margin'] = 0; + domStyle['border-width'] = 0; + } + + this.domBack = null; + this.ctxBack = null; + + this.painter = painter; + + this.config = null; + + // Configs + /** + * 每次清空画布的颜色 + * @type {string} + * @default 0 + */ + this.clearColor = 0; + /** + * 是否开启动态模糊 + * @type {boolean} + * @default false + */ + this.motionBlur = false; + /** + * 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显 + * @type {number} + * @default 0.7 + */ + this.lastFrameAlpha = 0.7; + + /** + * Layer dpr + * @type {number} + */ + this.dpr = dpr; + }; + + Layer.prototype = { + + constructor: Layer, + + __dirty: true, + + __used: false, + + __drawIndex: 0, + __startIndex: 0, + __endIndex: 0, + + incremental: false, + + getElementCount: function() { + return this.__endIndex - this.__startIndex; + }, + + initContext: function() { + this.ctx = this.dom.getContext('2d'); + this.ctx.dpr = this.dpr; + }, + + createBackBuffer: function() { + var dpr = this.dpr; + + this.domBack = createDom('back-' + this.id, this.painter, dpr); + this.ctxBack = this.domBack.getContext('2d'); + + if (dpr != 1) { + this.ctxBack.scale(dpr, dpr); + } + }, + + /** + * @param {number} width + * @param {number} height + */ + resize: function(width, height) { + var dpr = this.dpr; + + var dom = this.dom; + var domStyle = dom.style; + var domBack = this.domBack; + + if (domStyle) { + domStyle.width = width + 'px'; + domStyle.height = height + 'px'; + } + + dom.width = width * dpr; + dom.height = height * dpr; + + if (domBack) { + domBack.width = width * dpr; + domBack.height = height * dpr; + + if (dpr != 1) { + this.ctxBack.scale(dpr, dpr); + } + } + }, + + /** + * 清空该层画布 + * @param {boolean} [clearAll]=false Clear all with out motion blur + * @param {Color} [clearColor] + */ + clear: function(clearAll, clearColor) { + var dom = this.dom; + var ctx = this.ctx; + var width = dom.width; + var height = dom.height; + + var clearColor = clearColor || this.clearColor; + var haveMotionBLur = this.motionBlur && !clearAll; + var lastFrameAlpha = this.lastFrameAlpha; + + var dpr = this.dpr; + + if (haveMotionBLur) { + if (!this.domBack) { + this.createBackBuffer(); + } + + this.ctxBack.globalCompositeOperation = 'copy'; + this.ctxBack.drawImage( + dom, 0, 0, + width / dpr, + height / dpr + ); + } + + ctx.clearRect(0, 0, width, height); + if (clearColor && clearColor !== 'transparent') { + var clearColorGradientOrPattern; + // Gradient + if (clearColor.colorStops) { + // Cache canvas gradient + clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, { + x: 0, + y: 0, + width: width, + height: height + }); + + clearColor.__canvasGradient = clearColorGradientOrPattern; + } + // Pattern + else if (clearColor.image) { + clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx); + } + ctx.save(); + ctx.fillStyle = clearColorGradientOrPattern || clearColor; + ctx.fillRect(0, 0, width, height); + ctx.restore(); + } + + if (haveMotionBLur) { + var domBack = this.domBack; + ctx.save(); + ctx.globalAlpha = lastFrameAlpha; + ctx.drawImage(domBack, 0, 0, width, height); + ctx.restore(); + } + } + }; + + var requestAnimationFrame = ( + typeof window !== 'undefined' && + ( + (window.requestAnimationFrame && window.requestAnimationFrame.bind(window)) + // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809 + || + (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window)) || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame + ) + ) || function(func) { + setTimeout(func, 16); + }; + + var globalImageCache = new LRU(50); + + /** + * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc + * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image + */ + function findExistImage(newImageOrSrc) { + if (typeof newImageOrSrc === 'string') { + var cachedImgObj = globalImageCache.get(newImageOrSrc); + return cachedImgObj && cachedImgObj.image; + } else { + return newImageOrSrc; + } + } + + /** + * Caution: User should cache loaded images, but not just count on LRU. + * Consider if required images more than LRU size, will dead loop occur? + * + * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc + * @param {HTMLImageElement|HTMLCanvasElement|Canvas} image Existent image. + * @param {module:zrender/Element} [hostEl] For calling `dirty`. + * @param {Function} [cb] params: (image, cbPayload) + * @param {Object} [cbPayload] Payload on cb calling. + * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image + */ + function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) { + if (!newImageOrSrc) { + return image; + } else if (typeof newImageOrSrc === 'string') { + + // Image should not be loaded repeatly. + if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) { + return image; + } + + // Only when there is no existent image or existent image src + // is different, this method is responsible for load. + var cachedImgObj = globalImageCache.get(newImageOrSrc); + + var pendingWrap = { + hostEl: hostEl, + cb: cb, + cbPayload: cbPayload + }; + + if (cachedImgObj) { + image = cachedImgObj.image; + !isImageReady(image) && cachedImgObj.pending.push(pendingWrap); + } else { + !image && (image = new Image()); + image.onload = imageOnLoad; + + globalImageCache.put( + newImageOrSrc, + image.__cachedImgObj = { + image: image, + pending: [pendingWrap] + } + ); + + image.src = image.__zrImageSrc = newImageOrSrc; + } + + return image; + } + // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas + else { + return newImageOrSrc; + } + } + + function imageOnLoad() { + var cachedImgObj = this.__cachedImgObj; + this.onload = this.__cachedImgObj = null; + + for (var i = 0; i < cachedImgObj.pending.length; i++) { + var pendingWrap = cachedImgObj.pending[i]; + var cb = pendingWrap.cb; + cb && cb(this, pendingWrap.cbPayload); + pendingWrap.hostEl.dirty(); + } + cachedImgObj.pending.length = 0; + } + + function isImageReady(image) { + return image && image.width && image.height; + } + + var textWidthCache = {}; + var textWidthCacheCounter = 0; + + var TEXT_CACHE_MAX = 5000; + var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g; + + var DEFAULT_FONT = '12px sans-serif'; + + // Avoid assign to an exported variable, for transforming to cjs. + var methods$1 = {}; + + function $override$1(name, fn) { + methods$1[name] = fn; + } + + /** + * @public + * @param {string} text + * @param {string} font + * @return {number} width + */ + function getWidth(text, font) { + font = font || DEFAULT_FONT; + var key = text + ':' + font; + if (textWidthCache[key]) { + return textWidthCache[key]; + } + + var textLines = (text + '').split('\n'); + var width = 0; + + for (var i = 0, l = textLines.length; i < l; i++) { + // textContain.measureText may be overrided in SVG or VML + width = Math.max(measureText(textLines[i], font).width, width); + } + + if (textWidthCacheCounter > TEXT_CACHE_MAX) { + textWidthCacheCounter = 0; + textWidthCache = {}; + } + textWidthCacheCounter++; + textWidthCache[key] = width; + + return width; + } + + /** + * @public + * @param {string} text + * @param {string} font + * @param {string} [textAlign='left'] + * @param {string} [textVerticalAlign='top'] + * @param {Array.} [textPadding] + * @param {Object} [rich] + * @param {Object} [truncate] + * @return {Object} {x, y, width, height, lineHeight} + */ + function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) { + return rich ? + getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) : + getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate); + } + + function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate) { + var contentBlock = parsePlainText(text, font, textPadding, truncate); + var outerWidth = getWidth(text, font); + if (textPadding) { + outerWidth += textPadding[1] + textPadding[3]; + } + var outerHeight = contentBlock.outerHeight; + + var x = adjustTextX(0, outerWidth, textAlign); + var y = adjustTextY(0, outerHeight, textVerticalAlign); + + var rect = new BoundingRect(x, y, outerWidth, outerHeight); + rect.lineHeight = contentBlock.lineHeight; + + return rect; + } + + function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) { + var contentBlock = parseRichText(text, { + rich: rich, + truncate: truncate, + font: font, + textAlign: textAlign, + textPadding: textPadding + }); + var outerWidth = contentBlock.outerWidth; + var outerHeight = contentBlock.outerHeight; + + var x = adjustTextX(0, outerWidth, textAlign); + var y = adjustTextY(0, outerHeight, textVerticalAlign); + + return new BoundingRect(x, y, outerWidth, outerHeight); + } + + /** + * @public + * @param {number} x + * @param {number} width + * @param {string} [textAlign='left'] + * @return {number} Adjusted x. + */ + function adjustTextX(x, width, textAlign) { + // FIXME Right to left language + if (textAlign === 'right') { + x -= width; + } else if (textAlign === 'center') { + x -= width / 2; + } + return x; + } + + /** + * @public + * @param {number} y + * @param {number} height + * @param {string} [textVerticalAlign='top'] + * @return {number} Adjusted y. + */ + function adjustTextY(y, height, textVerticalAlign) { + if (textVerticalAlign === 'middle') { + y -= height / 2; + } else if (textVerticalAlign === 'bottom') { + y -= height; + } + return y; + } + + /** + * @public + * @param {stirng} textPosition + * @param {Object} rect {x, y, width, height} + * @param {number} distance + * @return {Object} {x, y, textAlign, textVerticalAlign} + */ + function adjustTextPositionOnRect(textPosition, rect, distance) { + + var x = rect.x; + var y = rect.y; + + var height = rect.height; + var width = rect.width; + var halfHeight = height / 2; + + var textAlign = 'left'; + var textVerticalAlign = 'top'; + + switch (textPosition) { + case 'left': + x -= distance; + y += halfHeight; + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + case 'right': + x += distance + width; + y += halfHeight; + textVerticalAlign = 'middle'; + break; + case 'top': + x += width / 2; + y -= distance; + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'bottom': + x += width / 2; + y += height + distance; + textAlign = 'center'; + break; + case 'inside': + x += width / 2; + y += halfHeight; + textAlign = 'center'; + textVerticalAlign = 'middle'; + break; + case 'insideLeft': + x += distance; + y += halfHeight; + textVerticalAlign = 'middle'; + break; + case 'insideRight': + x += width - distance; + y += halfHeight; + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + case 'insideTop': + x += width / 2; + y += distance; + textAlign = 'center'; + break; + case 'insideBottom': + x += width / 2; + y += height - distance; + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'insideTopLeft': + x += distance; + y += distance; + break; + case 'insideTopRight': + x += width - distance; + y += distance; + textAlign = 'right'; + break; + case 'insideBottomLeft': + x += distance; + y += height - distance; + textVerticalAlign = 'bottom'; + break; + case 'insideBottomRight': + x += width - distance; + y += height - distance; + textAlign = 'right'; + textVerticalAlign = 'bottom'; + break; + } + + return { + x: x, + y: y, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + } + + /** + * Show ellipsis if overflow. + * + * @public + * @param {string} text + * @param {string} containerWidth + * @param {string} font + * @param {number} [ellipsis='...'] + * @param {Object} [options] + * @param {number} [options.maxIterations=3] + * @param {number} [options.minChar=0] If truncate result are less + * then minChar, ellipsis will not show, which is + * better for user hint in some cases. + * @param {number} [options.placeholder=''] When all truncated, use the placeholder. + * @return {string} + */ + function truncateText(text, containerWidth, font, ellipsis, options) { + if (!containerWidth) { + return ''; + } + + var textLines = (text + '').split('\n'); + options = prepareTruncateOptions(containerWidth, font, ellipsis, options); + + // FIXME + // It is not appropriate that every line has '...' when truncate multiple lines. + for (var i = 0, len = textLines.length; i < len; i++) { + textLines[i] = truncateSingleLine(textLines[i], options); + } + + return textLines.join('\n'); + } + + function prepareTruncateOptions(containerWidth, font, ellipsis, options) { + options = extend({}, options); + + options.font = font; + var ellipsis = retrieve2(ellipsis, '...'); + options.maxIterations = retrieve2(options.maxIterations, 2); + var minChar = options.minChar = retrieve2(options.minChar, 0); + // FIXME + // Other languages? + options.cnCharWidth = getWidth('国', font); + // FIXME + // Consider proportional font? + var ascCharWidth = options.ascCharWidth = getWidth('a', font); + options.placeholder = retrieve2(options.placeholder, ''); + + // Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'. + // Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'. + var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap. + for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) { + contentWidth -= ascCharWidth; + } + + var ellipsisWidth = getWidth(ellipsis); + if (ellipsisWidth > contentWidth) { + ellipsis = ''; + ellipsisWidth = 0; + } + + contentWidth = containerWidth - ellipsisWidth; + + options.ellipsis = ellipsis; + options.ellipsisWidth = ellipsisWidth; + options.contentWidth = contentWidth; + options.containerWidth = containerWidth; + + return options; + } + + function truncateSingleLine(textLine, options) { + var containerWidth = options.containerWidth; + var font = options.font; + var contentWidth = options.contentWidth; + + if (!containerWidth) { + return ''; + } + + var lineWidth = getWidth(textLine, font); + + if (lineWidth <= containerWidth) { + return textLine; + } + + for (var j = 0;; j++) { + if (lineWidth <= contentWidth || j >= options.maxIterations) { + textLine += options.ellipsis; + break; + } + + var subLength = j === 0 ? + estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth) : + lineWidth > 0 ? + Math.floor(textLine.length * contentWidth / lineWidth) : + 0; + + textLine = textLine.substr(0, subLength); + lineWidth = getWidth(textLine, font); + } + + if (textLine === '') { + textLine = options.placeholder; + } + + return textLine; + } + + function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) { + var width = 0; + var i = 0; + for (var len = text.length; i < len && width < contentWidth; i++) { + var charCode = text.charCodeAt(i); + width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth; + } + return i; + } + + /** + * @public + * @param {string} font + * @return {number} line height + */ + function getLineHeight(font) { + // FIXME A rough approach. + return getWidth('国', font); + } + + /** + * @public + * @param {string} text + * @param {string} font + * @return {Object} width + */ + function measureText(text, font) { + return methods$1.measureText(text, font); + } + + // Avoid assign to an exported variable, for transforming to cjs. + methods$1.measureText = function(text, font) { + var ctx = getContext(); + ctx.font = font || DEFAULT_FONT; + return ctx.measureText(text); + }; + + /** + * @public + * @param {string} text + * @param {string} font + * @param {Object} [truncate] + * @return {Object} block: {lineHeight, lines, height, outerHeight} + * Notice: for performance, do not calculate outerWidth util needed. + */ + function parsePlainText(text, font, padding, truncate) { + text != null && (text += ''); + + var lineHeight = getLineHeight(font); + var lines = text ? text.split('\n') : []; + var height = lines.length * lineHeight; + var outerHeight = height; + + if (padding) { + outerHeight += padding[0] + padding[2]; + } + + if (text && truncate) { + var truncOuterHeight = truncate.outerHeight; + var truncOuterWidth = truncate.outerWidth; + if (truncOuterHeight != null && outerHeight > truncOuterHeight) { + text = ''; + lines = []; + } else if (truncOuterWidth != null) { + var options = prepareTruncateOptions( + truncOuterWidth - (padding ? padding[1] + padding[3] : 0), + font, + truncate.ellipsis, { + minChar: truncate.minChar, + placeholder: truncate.placeholder + } + ); + + // FIXME + // It is not appropriate that every line has '...' when truncate multiple lines. + for (var i = 0, len = lines.length; i < len; i++) { + lines[i] = truncateSingleLine(lines[i], options); + } + } + } + + return { + lines: lines, + height: height, + outerHeight: outerHeight, + lineHeight: lineHeight + }; + } + + /** + * For example: 'some text {a|some text}other text{b|some text}xxx{c|}xxx' + * Also consider 'bbbb{a|xxx\nzzz}xxxx\naaaa'. + * + * @public + * @param {string} text + * @param {Object} style + * @return {Object} block + * { + * width, + * height, + * lines: [{ + * lineHeight, + * width, + * tokens: [[{ + * styleName, + * text, + * width, // include textPadding + * height, // include textPadding + * textWidth, // pure text width + * textHeight, // pure text height + * lineHeihgt, + * font, + * textAlign, + * textVerticalAlign + * }], [...], ...] + * }, ...] + * } + * If styleName is undefined, it is plain text. + */ + function parseRichText(text, style) { + var contentBlock = { + lines: [], + width: 0, + height: 0 + }; + + text != null && (text += ''); + if (!text) { + return contentBlock; + } + + var lastIndex = STYLE_REG.lastIndex = 0; + var result; + while ((result = STYLE_REG.exec(text)) != null) { + var matchedIndex = result.index; + if (matchedIndex > lastIndex) { + pushTokens(contentBlock, text.substring(lastIndex, matchedIndex)); + } + pushTokens(contentBlock, result[2], result[1]); + lastIndex = STYLE_REG.lastIndex; + } + + if (lastIndex < text.length) { + pushTokens(contentBlock, text.substring(lastIndex, text.length)); + } + + var lines = contentBlock.lines; + var contentHeight = 0; + var contentWidth = 0; + // For `textWidth: 100%` + var pendingList = []; + + var stlPadding = style.textPadding; + + var truncate = style.truncate; + var truncateWidth = truncate && truncate.outerWidth; + var truncateHeight = truncate && truncate.outerHeight; + if (stlPadding) { + truncateWidth != null && (truncateWidth -= stlPadding[1] + stlPadding[3]); + truncateHeight != null && (truncateHeight -= stlPadding[0] + stlPadding[2]); + } + + // Calculate layout info of tokens. + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + var lineHeight = 0; + var lineWidth = 0; + + for (var j = 0; j < line.tokens.length; j++) { + var token = line.tokens[j]; + var tokenStyle = token.styleName && style.rich[token.styleName] || {}; + // textPadding should not inherit from style. + var textPadding = token.textPadding = tokenStyle.textPadding; + + // textFont has been asigned to font by `normalizeStyle`. + var font = token.font = tokenStyle.font || style.font; + + // textHeight can be used when textVerticalAlign is specified in token. + var tokenHeight = token.textHeight = retrieve2( + // textHeight should not be inherited, consider it can be specified + // as box height of the block. + tokenStyle.textHeight, getLineHeight(font) + ); + textPadding && (tokenHeight += textPadding[0] + textPadding[2]); + token.height = tokenHeight; + token.lineHeight = retrieve3( + tokenStyle.textLineHeight, style.textLineHeight, tokenHeight + ); + + token.textAlign = tokenStyle && tokenStyle.textAlign || style.textAlign; + token.textVerticalAlign = tokenStyle && tokenStyle.textVerticalAlign || 'middle'; + + if (truncateHeight != null && contentHeight + token.lineHeight > truncateHeight) { + return { + lines: [], + width: 0, + height: 0 + }; + } + + token.textWidth = getWidth(token.text, font); + var tokenWidth = tokenStyle.textWidth; + var tokenWidthNotSpecified = tokenWidth == null || tokenWidth === 'auto'; + + // Percent width, can be `100%`, can be used in drawing separate + // line when box width is needed to be auto. + if (typeof tokenWidth === 'string' && tokenWidth.charAt(tokenWidth.length - 1) === '%') { + token.percentWidth = tokenWidth; + pendingList.push(token); + tokenWidth = 0; + // Do not truncate in this case, because there is no user case + // and it is too complicated. + } else { + if (tokenWidthNotSpecified) { + tokenWidth = token.textWidth; + + // FIXME: If image is not loaded and textWidth is not specified, calling + // `getBoundingRect()` will not get correct result. + var textBackgroundColor = tokenStyle.textBackgroundColor; + var bgImg = textBackgroundColor && textBackgroundColor.image; + + // Use cases: + // (1) If image is not loaded, it will be loaded at render phase and call + // `dirty()` and `textBackgroundColor.image` will be replaced with the loaded + // image, and then the right size will be calculated here at the next tick. + // See `graphic/helper/text.js`. + // (2) If image loaded, and `textBackgroundColor.image` is image src string, + // use `imageHelper.findExistImage` to find cached image. + // `imageHelper.findExistImage` will always be called here before + // `imageHelper.createOrUpdateImage` in `graphic/helper/text.js#renderRichText` + // which ensures that image will not be rendered before correct size calcualted. + if (bgImg) { + bgImg = findExistImage(bgImg); + if (isImageReady(bgImg)) { + tokenWidth = Math.max(tokenWidth, bgImg.width * tokenHeight / bgImg.height); + } + } + } + + var paddingW = textPadding ? textPadding[1] + textPadding[3] : 0; + tokenWidth += paddingW; + + var remianTruncWidth = truncateWidth != null ? truncateWidth - lineWidth : null; + + if (remianTruncWidth != null && remianTruncWidth < tokenWidth) { + if (!tokenWidthNotSpecified || remianTruncWidth < paddingW) { + token.text = ''; + token.textWidth = tokenWidth = 0; + } else { + token.text = truncateText( + token.text, remianTruncWidth - paddingW, font, truncate.ellipsis, { + minChar: truncate.minChar + } + ); + token.textWidth = getWidth(token.text, font); + tokenWidth = token.textWidth + paddingW; + } + } + } + + lineWidth += (token.width = tokenWidth); + tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight)); + } + + line.width = lineWidth; + line.lineHeight = lineHeight; + contentHeight += lineHeight; + contentWidth = Math.max(contentWidth, lineWidth); + } + + contentBlock.outerWidth = contentBlock.width = retrieve2(style.textWidth, contentWidth); + contentBlock.outerHeight = contentBlock.height = retrieve2(style.textHeight, contentHeight); + + if (stlPadding) { + contentBlock.outerWidth += stlPadding[1] + stlPadding[3]; + contentBlock.outerHeight += stlPadding[0] + stlPadding[2]; + } + + for (var i = 0; i < pendingList.length; i++) { + var token = pendingList[i]; + var percentWidth = token.percentWidth; + // Should not base on outerWidth, because token can not be placed out of padding. + token.width = parseInt(percentWidth, 10) / 100 * contentWidth; + } + + return contentBlock; + } + + function pushTokens(block, str, styleName) { + var isEmptyStr = str === ''; + var strs = str.split('\n'); + var lines = block.lines; + + for (var i = 0; i < strs.length; i++) { + var text = strs[i]; + var token = { + styleName: styleName, + text: text, + isLineHolder: !text && !isEmptyStr + }; + + // The first token should be appended to the last line. + if (!i) { + var tokens = (lines[lines.length - 1] || (lines[0] = { + tokens: [] + })).tokens; + + // Consider cases: + // (1) ''.split('\n') => ['', '\n', ''], the '' at the first item + // (which is a placeholder) should be replaced by new token. + // (2) A image backage, where token likes {a|}. + // (3) A redundant '' will affect textAlign in line. + // (4) tokens with the same tplName should not be merged, because + // they should be displayed in different box (with border and padding). + var tokensLen = tokens.length; + (tokensLen === 1 && tokens[0].isLineHolder) ? + (tokens[0] = token) + // Consider text is '', only insert when it is the "lineHolder" or + // "emptyStr". Otherwise a redundant '' will affect textAlign in line. + : + ((text || !tokensLen || isEmptyStr) && tokens.push(token)); + } + // Other tokens always start a new line. + else { + // If there is '', insert it as a placeholder. + lines.push({ + tokens: [token] + }); + } + } + } + + function makeFont(style) { + // FIXME in node-canvas fontWeight is before fontStyle + // Use `fontSize` `fontFamily` to check whether font properties are defined. + var font = (style.fontSize || style.fontFamily) && [ + style.fontStyle, + style.fontWeight, + (style.fontSize || 12) + 'px', + // If font properties are defined, `fontFamily` should not be ignored. + style.fontFamily || 'sans-serif' + ].join(' '); + return font && trim(font) || style.textFont || style.font; + } + + function buildPath(ctx, shape) { + var x = shape.x; + var y = shape.y; + var width = shape.width; + var height = shape.height; + var r = shape.r; + var r1; + var r2; + var r3; + var r4; + + // Convert width and height to positive for better borderRadius + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } + + if (typeof r === 'number') { + r1 = r2 = r3 = r4 = r; + } else if (r instanceof Array) { + if (r.length === 1) { + r1 = r2 = r3 = r4 = r[0]; + } else if (r.length === 2) { + r1 = r3 = r[0]; + r2 = r4 = r[1]; + } else if (r.length === 3) { + r1 = r[0]; + r2 = r4 = r[1]; + r3 = r[2]; + } else { + r1 = r[0]; + r2 = r[1]; + r3 = r[2]; + r4 = r[3]; + } + } else { + r1 = r2 = r3 = r4 = 0; + } + + var total; + if (r1 + r2 > width) { + total = r1 + r2; + r1 *= width / total; + r2 *= width / total; + } + if (r3 + r4 > width) { + total = r3 + r4; + r3 *= width / total; + r4 *= width / total; + } + if (r2 + r3 > height) { + total = r2 + r3; + r2 *= height / total; + r3 *= height / total; + } + if (r1 + r4 > height) { + total = r1 + r4; + r1 *= height / total; + r4 *= height / total; + } + ctx.moveTo(x + r1, y); + ctx.lineTo(x + width - r2, y); + r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0); + ctx.lineTo(x + width, y + height - r3); + r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2); + ctx.lineTo(x + r4, y + height); + r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI); + ctx.lineTo(x, y + r1); + r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5); + } + + // TODO: Have not support 'start', 'end' yet. + var VALID_TEXT_ALIGN = { + left: 1, + right: 1, + center: 1 + }; + var VALID_TEXT_VERTICAL_ALIGN = { + top: 1, + bottom: 1, + middle: 1 + }; + + /** + * @param {module:zrender/graphic/Style} style + * @return {module:zrender/graphic/Style} The input style. + */ + function normalizeTextStyle(style) { + normalizeStyle(style); + each$1(style.rich, normalizeStyle); + return style; + } + + function normalizeStyle(style) { + if (style) { + + style.font = makeFont(style); + + var textAlign = style.textAlign; + textAlign === 'middle' && (textAlign = 'center'); + style.textAlign = ( + textAlign == null || VALID_TEXT_ALIGN[textAlign] + ) ? textAlign : 'left'; + + // Compatible with textBaseline. + var textVerticalAlign = style.textVerticalAlign || style.textBaseline; + textVerticalAlign === 'center' && (textVerticalAlign = 'middle'); + style.textVerticalAlign = ( + textVerticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[textVerticalAlign] + ) ? textVerticalAlign : 'top'; + + var textPadding = style.textPadding; + if (textPadding) { + style.textPadding = normalizeCssArray(style.textPadding); + } + } + } + + /** + * @param {CanvasRenderingContext2D} ctx + * @param {string} text + * @param {module:zrender/graphic/Style} style + * @param {Object|boolean} [rect] {x, y, width, height} + * If set false, rect text is not used. + */ + function renderText(hostEl, ctx, text, style, rect) { + style.rich ? + renderRichText(hostEl, ctx, text, style, rect) : + renderPlainText(hostEl, ctx, text, style, rect); + } + + function renderPlainText(hostEl, ctx, text, style, rect) { + var font = setCtx(ctx, 'font', style.font || DEFAULT_FONT); + + var textPadding = style.textPadding; + + var contentBlock = hostEl.__textCotentBlock; + if (!contentBlock || hostEl.__dirty) { + contentBlock = hostEl.__textCotentBlock = parsePlainText( + text, font, textPadding, style.truncate + ); + } + + var outerHeight = contentBlock.outerHeight; + + var textLines = contentBlock.lines; + var lineHeight = contentBlock.lineHeight; + + var boxPos = getBoxPosition(outerHeight, style, rect); + var baseX = boxPos.baseX; + var baseY = boxPos.baseY; + var textAlign = boxPos.textAlign; + var textVerticalAlign = boxPos.textVerticalAlign; + + // Origin of textRotation should be the base point of text drawing. + applyTextRotation(ctx, style, rect, baseX, baseY); + + var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign); + var textX = baseX; + var textY = boxY; + + var needDrawBg = needDrawBackground(style); + if (needDrawBg || textPadding) { + // Consider performance, do not call getTextWidth util necessary. + var textWidth = getWidth(text, font); + var outerWidth = textWidth; + textPadding && (outerWidth += textPadding[1] + textPadding[3]); + var boxX = adjustTextX(baseX, outerWidth, textAlign); + + needDrawBg && drawBackground(hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight); + + if (textPadding) { + textX = getTextXForPadding(baseX, textAlign, textPadding); + textY += textPadding[0]; + } + } + + setCtx(ctx, 'textAlign', textAlign || 'left'); + // Force baseline to be "middle". Otherwise, if using "top", the + // text will offset downward a little bit in font "Microsoft YaHei". + setCtx(ctx, 'textBaseline', 'middle'); + + // Always set shadowBlur and shadowOffset to avoid leak from displayable. + setCtx(ctx, 'shadowBlur', style.textShadowBlur || 0); + setCtx(ctx, 'shadowColor', style.textShadowColor || 'transparent'); + setCtx(ctx, 'shadowOffsetX', style.textShadowOffsetX || 0); + setCtx(ctx, 'shadowOffsetY', style.textShadowOffsetY || 0); + + // `textBaseline` is set as 'middle'. + textY += lineHeight / 2; + + var textStrokeWidth = style.textStrokeWidth; + var textStroke = getStroke(style.textStroke, textStrokeWidth); + var textFill = getFill(style.textFill); + + if (textStroke) { + setCtx(ctx, 'lineWidth', textStrokeWidth); + setCtx(ctx, 'strokeStyle', textStroke); + } + if (textFill) { + setCtx(ctx, 'fillStyle', textFill); + } + + for (var i = 0; i < textLines.length; i++) { + // Fill after stroke so the outline will not cover the main part. + textStroke && ctx.strokeText(textLines[i], textX, textY); + textFill && ctx.fillText(textLines[i], textX, textY); + textY += lineHeight; + } + } + + function renderRichText(hostEl, ctx, text, style, rect) { + var contentBlock = hostEl.__textCotentBlock; + + if (!contentBlock || hostEl.__dirty) { + contentBlock = hostEl.__textCotentBlock = parseRichText(text, style); + } + + drawRichText(hostEl, ctx, contentBlock, style, rect); + } + + function drawRichText(hostEl, ctx, contentBlock, style, rect) { + var contentWidth = contentBlock.width; + var outerWidth = contentBlock.outerWidth; + var outerHeight = contentBlock.outerHeight; + var textPadding = style.textPadding; + + var boxPos = getBoxPosition(outerHeight, style, rect); + var baseX = boxPos.baseX; + var baseY = boxPos.baseY; + var textAlign = boxPos.textAlign; + var textVerticalAlign = boxPos.textVerticalAlign; + + // Origin of textRotation should be the base point of text drawing. + applyTextRotation(ctx, style, rect, baseX, baseY); + + var boxX = adjustTextX(baseX, outerWidth, textAlign); + var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign); + var xLeft = boxX; + var lineTop = boxY; + if (textPadding) { + xLeft += textPadding[3]; + lineTop += textPadding[0]; + } + var xRight = xLeft + contentWidth; + + needDrawBackground(style) && drawBackground( + hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight + ); + + for (var i = 0; i < contentBlock.lines.length; i++) { + var line = contentBlock.lines[i]; + var tokens = line.tokens; + var tokenCount = tokens.length; + var lineHeight = line.lineHeight; + var usedWidth = line.width; + + var leftIndex = 0; + var lineXLeft = xLeft; + var lineXRight = xRight; + var rightIndex = tokenCount - 1; + var token; + + while ( + leftIndex < tokenCount && + (token = tokens[leftIndex], !token.textAlign || token.textAlign === 'left') + ) { + placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft, 'left'); + usedWidth -= token.width; + lineXLeft += token.width; + leftIndex++; + } + + while ( + rightIndex >= 0 && + (token = tokens[rightIndex], token.textAlign === 'right') + ) { + placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXRight, 'right'); + usedWidth -= token.width; + lineXRight -= token.width; + rightIndex--; + } + + // The other tokens are placed as textAlign 'center' if there is enough space. + lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - usedWidth) / 2; + while (leftIndex <= rightIndex) { + token = tokens[leftIndex]; + // Consider width specified by user, use 'center' rather than 'left'. + placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center'); + lineXLeft += token.width; + leftIndex++; + } + + lineTop += lineHeight; + } + } + + function applyTextRotation(ctx, style, rect, x, y) { + // textRotation only apply in RectText. + if (rect && style.textRotation) { + var origin = style.textOrigin; + if (origin === 'center') { + x = rect.width / 2 + rect.x; + y = rect.height / 2 + rect.y; + } else if (origin) { + x = origin[0] + rect.x; + y = origin[1] + rect.y; + } + + ctx.translate(x, y); + // Positive: anticlockwise + ctx.rotate(-style.textRotation); + ctx.translate(-x, -y); + } + } + + function placeToken(hostEl, ctx, token, style, lineHeight, lineTop, x, textAlign) { + var tokenStyle = style.rich[token.styleName] || {}; + + // 'ctx.textBaseline' is always set as 'middle', for sake of + // the bias of "Microsoft YaHei". + var textVerticalAlign = token.textVerticalAlign; + var y = lineTop + lineHeight / 2; + if (textVerticalAlign === 'top') { + y = lineTop + token.height / 2; + } else if (textVerticalAlign === 'bottom') { + y = lineTop + lineHeight - token.height / 2; + } + + !token.isLineHolder && needDrawBackground(tokenStyle) && drawBackground( + hostEl, + ctx, + tokenStyle, + textAlign === 'right' ? + x - token.width : + textAlign === 'center' ? + x - token.width / 2 : + x, + y - token.height / 2, + token.width, + token.height + ); + + var textPadding = token.textPadding; + if (textPadding) { + x = getTextXForPadding(x, textAlign, textPadding); + y -= token.height / 2 - textPadding[2] - token.textHeight / 2; + } + + setCtx(ctx, 'shadowBlur', retrieve3(tokenStyle.textShadowBlur, style.textShadowBlur, 0)); + setCtx(ctx, 'shadowColor', tokenStyle.textShadowColor || style.textShadowColor || 'transparent'); + setCtx(ctx, 'shadowOffsetX', retrieve3(tokenStyle.textShadowOffsetX, style.textShadowOffsetX, 0)); + setCtx(ctx, 'shadowOffsetY', retrieve3(tokenStyle.textShadowOffsetY, style.textShadowOffsetY, 0)); + + setCtx(ctx, 'textAlign', textAlign); + // Force baseline to be "middle". Otherwise, if using "top", the + // text will offset downward a little bit in font "Microsoft YaHei". + setCtx(ctx, 'textBaseline', 'middle'); + + setCtx(ctx, 'font', token.font || DEFAULT_FONT); + + var textStroke = getStroke(tokenStyle.textStroke || style.textStroke, textStrokeWidth); + var textFill = getFill(tokenStyle.textFill || style.textFill); + var textStrokeWidth = retrieve2(tokenStyle.textStrokeWidth, style.textStrokeWidth); + + // Fill after stroke so the outline will not cover the main part. + if (textStroke) { + setCtx(ctx, 'lineWidth', textStrokeWidth); + setCtx(ctx, 'strokeStyle', textStroke); + ctx.strokeText(token.text, x, y); + } + if (textFill) { + setCtx(ctx, 'fillStyle', textFill); + ctx.fillText(token.text, x, y); + } + } + + function needDrawBackground(style) { + return style.textBackgroundColor || + (style.textBorderWidth && style.textBorderColor); + } + + // style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius} + // shape: {x, y, width, height} + function drawBackground(hostEl, ctx, style, x, y, width, height) { + var textBackgroundColor = style.textBackgroundColor; + var textBorderWidth = style.textBorderWidth; + var textBorderColor = style.textBorderColor; + var isPlainBg = isString(textBackgroundColor); + + setCtx(ctx, 'shadowBlur', style.textBoxShadowBlur || 0); + setCtx(ctx, 'shadowColor', style.textBoxShadowColor || 'transparent'); + setCtx(ctx, 'shadowOffsetX', style.textBoxShadowOffsetX || 0); + setCtx(ctx, 'shadowOffsetY', style.textBoxShadowOffsetY || 0); + + if (isPlainBg || (textBorderWidth && textBorderColor)) { + ctx.beginPath(); + var textBorderRadius = style.textBorderRadius; + if (!textBorderRadius) { + ctx.rect(x, y, width, height); + } else { + buildPath(ctx, { + x: x, + y: y, + width: width, + height: height, + r: textBorderRadius + }); + } + ctx.closePath(); + } + + if (isPlainBg) { + setCtx(ctx, 'fillStyle', textBackgroundColor); + ctx.fill(); + } else if (isObject$1(textBackgroundColor)) { + var image = textBackgroundColor.image; + + image = createOrUpdateImage( + image, null, hostEl, onBgImageLoaded, textBackgroundColor + ); + if (image && isImageReady(image)) { + ctx.drawImage(image, x, y, width, height); + } + } + + if (textBorderWidth && textBorderColor) { + setCtx(ctx, 'lineWidth', textBorderWidth); + setCtx(ctx, 'strokeStyle', textBorderColor); + ctx.stroke(); + } + } + + function onBgImageLoaded(image, textBackgroundColor) { + // Replace image, so that `contain/text.js#parseRichText` + // will get correct result in next tick. + textBackgroundColor.image = image; + } + + function getBoxPosition(blockHeiht, style, rect) { + var baseX = style.x || 0; + var baseY = style.y || 0; + var textAlign = style.textAlign; + var textVerticalAlign = style.textVerticalAlign; + + // Text position represented by coord + if (rect) { + var textPosition = style.textPosition; + if (textPosition instanceof Array) { + // Percent + baseX = rect.x + parsePercent(textPosition[0], rect.width); + baseY = rect.y + parsePercent(textPosition[1], rect.height); + } else { + var res = adjustTextPositionOnRect( + textPosition, rect, style.textDistance + ); + baseX = res.x; + baseY = res.y; + // Default align and baseline when has textPosition + textAlign = textAlign || res.textAlign; + textVerticalAlign = textVerticalAlign || res.textVerticalAlign; + } + + // textOffset is only support in RectText, otherwise + // we have to adjust boundingRect for textOffset. + var textOffset = style.textOffset; + if (textOffset) { + baseX += textOffset[0]; + baseY += textOffset[1]; + } + } + + return { + baseX: baseX, + baseY: baseY, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + } + + function setCtx(ctx, prop, value) { + ctx[prop] = fixShadow(ctx, prop, value); + return ctx[prop]; + } + + /** + * @param {string} [stroke] If specified, do not check style.textStroke. + * @param {string} [lineWidth] If specified, do not check style.textStroke. + * @param {number} style + */ + function getStroke(stroke, lineWidth) { + return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none') ? + null + // TODO pattern and gradient? + : + (stroke.image || stroke.colorStops) ? + '#000' : + stroke; + } + + function getFill(fill) { + return (fill == null || fill === 'none') ? + null + // TODO pattern and gradient? + : + (fill.image || fill.colorStops) ? + '#000' : + fill; + } + + function parsePercent(value, maxValue) { + if (typeof value === 'string') { + if (value.lastIndexOf('%') >= 0) { + return parseFloat(value) / 100 * maxValue; + } + return parseFloat(value); + } + return value; + } + + function getTextXForPadding(x, textAlign, textPadding) { + return textAlign === 'right' ? + (x - textPadding[1]) : + textAlign === 'center' ? + (x + textPadding[3] / 2 - textPadding[1] / 2) : + (x + textPadding[3]); + } + + /** + * @param {string} text + * @param {module:zrender/Style} style + * @return {boolean} + */ + function needDrawText(text, style) { + return text != null && + (text || + style.textBackgroundColor || + (style.textBorderWidth && style.textBorderColor) || + style.textPadding + ); + } + + /** + * Mixin for drawing text in a element bounding rect + * @module zrender/mixin/RectText + */ + + var tmpRect$1 = new BoundingRect(); + + var RectText = function() {}; + + RectText.prototype = { + + constructor: RectText, + + /** + * Draw text in a rect with specified position. + * @param {CanvasRenderingContext2D} ctx + * @param {Object} rect Displayable rect + */ + drawRectText: function(ctx, rect) { + var style = this.style; + + rect = style.textRect || rect; + + // Optimize, avoid normalize every time. + this.__dirty && normalizeTextStyle(style, true); + + var text = style.text; + + // Convert to string + text != null && (text += ''); + + if (!needDrawText(text, style)) { + return; + } + + // FIXME + ctx.save(); + + // Transform rect to view space + var transform = this.transform; + if (!style.transformText) { + if (transform) { + tmpRect$1.copy(rect); + tmpRect$1.applyTransform(transform); + rect = tmpRect$1; + } + } else { + this.setTransform(ctx); + } + + // transformText and textRotation can not be used at the same time. + renderText(this, ctx, text, style, rect); + + ctx.restore(); + } + }; + + /** + * 可绘制的图形基类 + * Base class of all displayable graphic objects + * @module zrender/graphic/Displayable + */ + + + /** + * @alias module:zrender/graphic/Displayable + * @extends module:zrender/Element + * @extends module:zrender/graphic/mixin/RectText + */ + function Displayable(opts) { + + opts = opts || {}; + + Element.call(this, opts); + + // Extend properties + for (var name in opts) { + if ( + opts.hasOwnProperty(name) && + name !== 'style' + ) { + this[name] = opts[name]; + } + } + + /** + * @type {module:zrender/graphic/Style} + */ + this.style = new Style(opts.style, this); + + this._rect = null; + // Shapes for cascade clipping. + this.__clipPaths = []; + + // FIXME Stateful must be mixined after style is setted + // Stateful.call(this, opts); + } + + Displayable.prototype = { + + constructor: Displayable, + + type: 'displayable', + + /** + * Displayable 是否为脏,Painter 中会根据该标记判断是否需要是否需要重新绘制 + * Dirty flag. From which painter will determine if this displayable object needs brush + * @name module:zrender/graphic/Displayable#__dirty + * @type {boolean} + */ + __dirty: true, + + /** + * 图形是否可见,为true时不绘制图形,但是仍能触发鼠标事件 + * If ignore drawing of the displayable object. Mouse event will still be triggered + * @name module:/zrender/graphic/Displayable#invisible + * @type {boolean} + * @default false + */ + invisible: false, + + /** + * @name module:/zrender/graphic/Displayable#z + * @type {number} + * @default 0 + */ + z: 0, + + /** + * @name module:/zrender/graphic/Displayable#z + * @type {number} + * @default 0 + */ + z2: 0, + + /** + * z层level,决定绘画在哪层canvas中 + * @name module:/zrender/graphic/Displayable#zlevel + * @type {number} + * @default 0 + */ + zlevel: 0, + + /** + * 是否可拖拽 + * @name module:/zrender/graphic/Displayable#draggable + * @type {boolean} + * @default false + */ + draggable: false, + + /** + * 是否正在拖拽 + * @name module:/zrender/graphic/Displayable#draggable + * @type {boolean} + * @default false + */ + dragging: false, + + /** + * 是否相应鼠标事件 + * @name module:/zrender/graphic/Displayable#silent + * @type {boolean} + * @default false + */ + silent: false, + + /** + * If enable culling + * @type {boolean} + * @default false + */ + culling: false, + + /** + * Mouse cursor when hovered + * @name module:/zrender/graphic/Displayable#cursor + * @type {string} + */ + cursor: 'pointer', + + /** + * If hover area is bounding rect + * @name module:/zrender/graphic/Displayable#rectHover + * @type {string} + */ + rectHover: false, + + /** + * Render the element progressively when the value >= 0, + * usefull for large data. + * @type {boolean} + */ + progressive: false, + + /** + * @type {boolean} + */ + incremental: false, + // inplace is used with incremental + inplace: false, + + beforeBrush: function(ctx) {}, + + afterBrush: function(ctx) {}, + + /** + * 图形绘制方法 + * @param {CanvasRenderingContext2D} ctx + */ + // Interface + brush: function(ctx, prevEl) {}, + + /** + * 获取最小包围盒 + * @return {module:zrender/core/BoundingRect} + */ + // Interface + getBoundingRect: function() {}, + + /** + * 判断坐标 x, y 是否在图形上 + * If displayable element contain coord x, y + * @param {number} x + * @param {number} y + * @return {boolean} + */ + contain: function(x, y) { + return this.rectContain(x, y); + }, + + /** + * @param {Function} cb + * @param {} context + */ + traverse: function(cb, context) { + cb.call(context, this); + }, + + /** + * 判断坐标 x, y 是否在图形的包围盒上 + * If bounding rect of element contain coord x, y + * @param {number} x + * @param {number} y + * @return {boolean} + */ + rectContain: function(x, y) { + var coord = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + return rect.contain(coord[0], coord[1]); + }, + + /** + * 标记图形元素为脏,并且在下一帧重绘 + * Mark displayable element dirty and refresh next frame + */ + dirty: function() { + this.__dirty = true; + + this._rect = null; + + this.__zr && this.__zr.refresh(); + }, + + /** + * 图形是否会触发事件 + * If displayable object binded any event + * @return {boolean} + */ + // TODO, 通过 bind 绑定的事件 + // isSilent: function () { + // return !( + // this.hoverable || this.draggable + // || this.onmousemove || this.onmouseover || this.onmouseout + // || this.onmousedown || this.onmouseup || this.onclick + // || this.ondragenter || this.ondragover || this.ondragleave + // || this.ondrop + // ); + // }, + /** + * Alias for animate('style') + * @param {boolean} loop + */ + animateStyle: function(loop) { + return this.animate('style', loop); + }, + + attrKV: function(key, value) { + if (key !== 'style') { + Element.prototype.attrKV.call(this, key, value); + } else { + this.style.set(value); + } + }, + + /** + * @param {Object|string} key + * @param {*} value + */ + setStyle: function(key, value) { + this.style.set(key, value); + this.dirty(false); + return this; + }, + + /** + * Use given style object + * @param {Object} obj + */ + useStyle: function(obj) { + this.style = new Style(obj, this); + this.dirty(false); + return this; + } + }; + + inherits(Displayable, Element); + + mixin(Displayable, RectText); + + /** + * @alias zrender/graphic/Image + * @extends module:zrender/graphic/Displayable + * @constructor + * @param {Object} opts + */ + function ZImage(opts) { + Displayable.call(this, opts); + } + + ZImage.prototype = { + + constructor: ZImage, + + type: 'image', + + brush: function(ctx, prevEl) { + var style = this.style; + var src = style.image; + + // Must bind each time + style.bind(ctx, this, prevEl); + + var image = this._image = createOrUpdateImage( + src, + this._image, + this, + this.onload + ); + + if (!image || !isImageReady(image)) { + return; + } + + // 图片已经加载完成 + // if (image.nodeName.toUpperCase() == 'IMG') { + // if (!image.complete) { + // return; + // } + // } + // Else is canvas + + var x = style.x || 0; + var y = style.y || 0; + var width = style.width; + var height = style.height; + var aspect = image.width / image.height; + if (width == null && height != null) { + // Keep image/height ratio + width = height * aspect; + } else if (height == null && width != null) { + height = width / aspect; + } else if (width == null && height == null) { + width = image.width; + height = image.height; + } + + // 设置transform + this.setTransform(ctx); + + if (style.sWidth && style.sHeight) { + var sx = style.sx || 0; + var sy = style.sy || 0; + ctx.drawImage( + image, + sx, sy, style.sWidth, style.sHeight, + x, y, width, height + ); + } else if (style.sx && style.sy) { + var sx = style.sx; + var sy = style.sy; + var sWidth = width - sx; + var sHeight = height - sy; + ctx.drawImage( + image, + sx, sy, sWidth, sHeight, + x, y, width, height + ); + } else { + ctx.drawImage(image, x, y, width, height); + } + + // Draw rect text + if (style.text != null) { + // Only restore transform when needs draw text. + this.restoreTransform(ctx); + this.drawRectText(ctx, this.getBoundingRect()); + } + }, + + getBoundingRect: function() { + var style = this.style; + if (!this._rect) { + this._rect = new BoundingRect( + style.x || 0, style.y || 0, style.width || 0, style.height || 0 + ); + } + return this._rect; + } + }; + + inherits(ZImage, Displayable); + + var HOVER_LAYER_ZLEVEL = 1e5; + var CANVAS_ZLEVEL = 314159; + + var EL_AFTER_INCREMENTAL_INC = 0.01; + var INCREMENTAL_INC = 0.001; + + function parseInt10(val) { + return parseInt(val, 10); + } + + function isLayerValid(layer) { + if (!layer) { + return false; + } + + if (layer.__builtin__) { + return true; + } + + if (typeof(layer.resize) !== 'function' || + typeof(layer.refresh) !== 'function' + ) { + return false; + } + + return true; + } + + var tmpRect = new BoundingRect(0, 0, 0, 0); + var viewRect = new BoundingRect(0, 0, 0, 0); + + function isDisplayableCulled(el, width, height) { + tmpRect.copy(el.getBoundingRect()); + if (el.transform) { + tmpRect.applyTransform(el.transform); + } + viewRect.width = width; + viewRect.height = height; + return !tmpRect.intersect(viewRect); + } + + function isClipPathChanged(clipPaths, prevClipPaths) { + if (clipPaths == prevClipPaths) { // Can both be null or undefined + return false; + } + + if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) { + return true; + } + for (var i = 0; i < clipPaths.length; i++) { + if (clipPaths[i] !== prevClipPaths[i]) { + return true; + } + } + } + + function doClip(clipPaths, ctx) { + for (var i = 0; i < clipPaths.length; i++) { + var clipPath = clipPaths[i]; + + clipPath.setTransform(ctx); + ctx.beginPath(); + clipPath.buildPath(ctx, clipPath.shape); + ctx.clip(); + // Transform back + clipPath.restoreTransform(ctx); + } + } + + function createRoot(width, height) { + var domRoot = document.createElement('div'); + + // domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬 + domRoot.style.cssText = [ + 'position:relative', + 'overflow:hidden', + 'width:' + width + 'px', + 'height:' + height + 'px', + 'padding:0', + 'margin:0', + 'border-width:0' + ].join(';') + ';'; + + return domRoot; + } + + + /** + * @alias module:zrender/Painter + * @constructor + * @param {HTMLElement} root 绘图容器 + * @param {module:zrender/Storage} storage + * @param {Object} opts + */ + var Painter = function(root, storage, opts) { + + this.type = 'canvas'; + + // In node environment using node-canvas + var singleCanvas = !root.nodeName // In node ? + || + root.nodeName.toUpperCase() === 'CANVAS'; + + this._opts = opts = extend({}, opts || {}); + + /** + * @type {number} + */ + this.dpr = opts.devicePixelRatio || devicePixelRatio; + /** + * @type {boolean} + * @private + */ + this._singleCanvas = singleCanvas; + /** + * 绘图容器 + * @type {HTMLElement} + */ + this.root = root; + + var rootStyle = root.style; + + if (rootStyle) { + rootStyle['-webkit-tap-highlight-color'] = 'transparent'; + rootStyle['-webkit-user-select'] = + rootStyle['user-select'] = + rootStyle['-webkit-touch-callout'] = 'none'; + + root.innerHTML = ''; + } + + /** + * @type {module:zrender/Storage} + */ + this.storage = storage; + + /** + * @type {Array.} + * @private + */ + var zlevelList = this._zlevelList = []; + + /** + * @type {Object.} + * @private + */ + var layers = this._layers = {}; + + /** + * @type {Object.} + * @private + */ + this._layerConfig = {}; + + /** + * zrender will do compositing when root is a canvas and have multiple zlevels. + */ + this._needsManuallyCompositing = false; + + if (!singleCanvas) { + this._width = this._getSize(0); + this._height = this._getSize(1); + + var domRoot = this._domRoot = createRoot( + this._width, this._height + ); + root.appendChild(domRoot); + } else { + var width = root.width; + var height = root.height; + + if (opts.width != null) { + width = opts.width; + } + if (opts.height != null) { + height = opts.height; + } + this.dpr = opts.devicePixelRatio || 1; + + // Use canvas width and height directly + root.width = width * this.dpr; + root.height = height * this.dpr; + + this._width = width; + this._height = height; + + // Create layer if only one given canvas + // Device can be specified to create a high dpi image. + var mainLayer = new Layer(root, this, this.dpr); + mainLayer.__builtin__ = true; + mainLayer.initContext(); + // FIXME Use canvas width and height + // mainLayer.resize(width, height); + layers[CANVAS_ZLEVEL] = mainLayer; + mainLayer.zlevel = CANVAS_ZLEVEL; + // Not use common zlevel. + zlevelList.push(CANVAS_ZLEVEL); + + this._domRoot = root; + } + + /** + * @type {module:zrender/Layer} + * @private + */ + this._hoverlayer = null; + + this._hoverElements = []; + }; + + Painter.prototype = { + + constructor: Painter, + + getType: function() { + return 'canvas'; + }, + + /** + * If painter use a single canvas + * @return {boolean} + */ + isSingleCanvas: function() { + return this._singleCanvas; + }, + /** + * @return {HTMLDivElement} + */ + getViewportRoot: function() { + return this._domRoot; + }, + + getViewportRootOffset: function() { + var viewportRoot = this.getViewportRoot(); + if (viewportRoot) { + return { + offsetLeft: viewportRoot.offsetLeft || 0, + offsetTop: viewportRoot.offsetTop || 0 + }; + } + }, + + /** + * 刷新 + * @param {boolean} [paintAll=false] 强制绘制所有displayable + */ + refresh: function(paintAll) { + + var list = this.storage.getDisplayList(true); + + var zlevelList = this._zlevelList; + + this._redrawId = Math.random(); + + this._paintList(list, paintAll, this._redrawId); + + // Paint custum layers + for (var i = 0; i < zlevelList.length; i++) { + var z = zlevelList[i]; + var layer = this._layers[z]; + if (!layer.__builtin__ && layer.refresh) { + var clearColor = i === 0 ? this._backgroundColor : null; + layer.refresh(clearColor); + } + } + + this.refreshHover(); + + return this; + }, + + addHover: function(el, hoverStyle) { + if (el.__hoverMir) { + return; + } + var elMirror = new el.constructor({ + style: el.style, + shape: el.shape + }); + elMirror.__from = el; + el.__hoverMir = elMirror; + elMirror.setStyle(hoverStyle); + this._hoverElements.push(elMirror); + }, + + removeHover: function(el) { + var elMirror = el.__hoverMir; + var hoverElements = this._hoverElements; + var idx = indexOf(hoverElements, elMirror); + if (idx >= 0) { + hoverElements.splice(idx, 1); + } + el.__hoverMir = null; + }, + + clearHover: function(el) { + var hoverElements = this._hoverElements; + for (var i = 0; i < hoverElements.length; i++) { + var from = hoverElements[i].__from; + if (from) { + from.__hoverMir = null; + } + } + hoverElements.length = 0; + }, + + refreshHover: function() { + var hoverElements = this._hoverElements; + var len = hoverElements.length; + var hoverLayer = this._hoverlayer; + hoverLayer && hoverLayer.clear(); + + if (!len) { + return; + } + sort(hoverElements, this.storage.displayableSortFunc); + + // Use a extream large zlevel + // FIXME? + if (!hoverLayer) { + hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL); + } + + var scope = {}; + hoverLayer.ctx.save(); + for (var i = 0; i < len;) { + var el = hoverElements[i]; + var originalEl = el.__from; + // Original el is removed + // PENDING + if (!(originalEl && originalEl.__zr)) { + hoverElements.splice(i, 1); + originalEl.__hoverMir = null; + len--; + continue; + } + i++; + + // Use transform + // FIXME style and shape ? + if (!originalEl.invisible) { + el.transform = originalEl.transform; + el.invTransform = originalEl.invTransform; + el.__clipPaths = originalEl.__clipPaths; + // el. + this._doPaintEl(el, hoverLayer, true, scope); + } + } + hoverLayer.ctx.restore(); + }, + + getHoverLayer: function() { + return this.getLayer(HOVER_LAYER_ZLEVEL); + }, + + _paintList: function(list, paintAll, redrawId) { + if (this._redrawId !== redrawId) { + return; + } + + paintAll = paintAll || false; + + this._updateLayerStatus(list); + + var finished = this._doPaintList(list, paintAll); + + if (this._needsManuallyCompositing) { + this._compositeManually(); + } + + if (!finished) { + var self = this; + requestAnimationFrame(function() { + self._paintList(list, paintAll, redrawId); + }); + } + }, + + _compositeManually: function() { + var ctx = this.getLayer(CANVAS_ZLEVEL).ctx; + var width = this._domRoot.width; + var height = this._domRoot.height; + ctx.clearRect(0, 0, width, height); + // PENDING, If only builtin layer? + this.eachBuiltinLayer(function(layer) { + if (layer.virtual) { + ctx.drawImage(layer.dom, 0, 0, width, height); + } + }); + }, + + _doPaintList: function(list, paintAll) { + var layerList = []; + for (var zi = 0; zi < this._zlevelList.length; zi++) { + var zlevel = this._zlevelList[zi]; + var layer = this._layers[zlevel]; + if (layer.__builtin__ && + layer !== this._hoverlayer && + (layer.__dirty || paintAll) + ) { + layerList.push(layer); + } + } + + var finished = true; + + for (var k = 0; k < layerList.length; k++) { + var layer = layerList[k]; + var ctx = layer.ctx; + var scope = {}; + ctx.save(); + + var start = paintAll ? layer.__startIndex : layer.__drawIndex; + + var useTimer = !paintAll && layer.incremental && Date.now; + var startTime = useTimer && Date.now(); + + var clearColor = layer.zlevel === this._zlevelList[0] ? + this._backgroundColor : null; + // All elements in this layer are cleared. + if (layer.__startIndex === layer.__endIndex) { + layer.clear(false, clearColor); + } else if (start === layer.__startIndex) { + var firstEl = list[start]; + if (!firstEl.incremental || !firstEl.notClear || paintAll) { + layer.clear(false, clearColor); + } + } + if (start === -1) { + console.error('For some unknown reason. drawIndex is -1'); + start = layer.__startIndex; + } + for (var i = start; i < layer.__endIndex; i++) { + var el = list[i]; + this._doPaintEl(el, layer, paintAll, scope); + el.__dirty = false; + + if (useTimer) { + // Date.now can be executed in 13,025,305 ops/second. + var dTime = Date.now() - startTime; + // Give 15 millisecond to draw. + // The rest elements will be drawn in the next frame. + if (dTime > 15) { + break; + } + } + } + + layer.__drawIndex = i; + + if (layer.__drawIndex < layer.__endIndex) { + finished = false; + } + + if (scope.prevElClipPaths) { + // Needs restore the state. If last drawn element is in the clipping area. + ctx.restore(); + } + + ctx.restore(); + } + + if (env$1.wxa) { + // Flush for weixin application + each$1(this._layers, function(layer) { + if (layer && layer.ctx && layer.ctx.draw) { + layer.ctx.draw(); + } + }); + } + + return finished; + }, + + _doPaintEl: function(el, currentLayer, forcePaint, scope) { + var ctx = currentLayer.ctx; + var m = el.transform; + if ( + (currentLayer.__dirty || forcePaint) + // Ignore invisible element + && + !el.invisible + // Ignore transparent element + && + el.style.opacity !== 0 + // Ignore scale 0 element, in some environment like node-canvas + // Draw a scale 0 element can cause all following draw wrong + // And setTransform with scale 0 will cause set back transform failed. + && + !(m && !m[0] && !m[3]) + // Ignore culled element + && + !(el.culling && isDisplayableCulled(el, this._width, this._height)) + ) { + + var clipPaths = el.__clipPaths; + + // Optimize when clipping on group with several elements + if (!scope.prevElClipPaths || + isClipPathChanged(clipPaths, scope.prevElClipPaths) + ) { + // If has previous clipping state, restore from it + if (scope.prevElClipPaths) { + currentLayer.ctx.restore(); + scope.prevElClipPaths = null; + + // Reset prevEl since context has been restored + scope.prevEl = null; + } + // New clipping state + if (clipPaths) { + ctx.save(); + doClip(clipPaths, ctx); + scope.prevElClipPaths = clipPaths; + } + } + el.beforeBrush && el.beforeBrush(ctx); + + el.brush(ctx, scope.prevEl || null); + scope.prevEl = el; + + el.afterBrush && el.afterBrush(ctx); + } + }, + + /** + * 获取 zlevel 所在层,如果不存在则会创建一个新的层 + * @param {number} zlevel + * @param {boolean} virtual Virtual layer will not be inserted into dom. + * @return {module:zrender/Layer} + */ + getLayer: function(zlevel, virtual) { + if (this._singleCanvas && !this._needsManuallyCompositing) { + zlevel = CANVAS_ZLEVEL; + } + var layer = this._layers[zlevel]; + if (!layer) { + // Create a new layer + layer = new Layer('zr_' + zlevel, this, this.dpr); + layer.zlevel = zlevel; + layer.__builtin__ = true; + + if (this._layerConfig[zlevel]) { + merge(layer, this._layerConfig[zlevel], true); + } + + if (virtual) { + layer.virtual = virtual; + } + + this.insertLayer(zlevel, layer); + + // Context is created after dom inserted to document + // Or excanvas will get 0px clientWidth and clientHeight + layer.initContext(); + } + + return layer; + }, + + insertLayer: function(zlevel, layer) { + + var layersMap = this._layers; + var zlevelList = this._zlevelList; + var len = zlevelList.length; + var prevLayer = null; + var i = -1; + var domRoot = this._domRoot; + + if (layersMap[zlevel]) { + zrLog('ZLevel ' + zlevel + ' has been used already'); + return; + } + // Check if is a valid layer + if (!isLayerValid(layer)) { + zrLog('Layer of zlevel ' + zlevel + ' is not valid'); + return; + } + + if (len > 0 && zlevel > zlevelList[0]) { + for (i = 0; i < len - 1; i++) { + if ( + zlevelList[i] < zlevel && + zlevelList[i + 1] > zlevel + ) { + break; + } + } + prevLayer = layersMap[zlevelList[i]]; + } + zlevelList.splice(i + 1, 0, zlevel); + + layersMap[zlevel] = layer; + + // Vitual layer will not directly show on the screen. + // (It can be a WebGL layer and assigned to a ZImage element) + // But it still under management of zrender. + if (!layer.virtual) { + if (prevLayer) { + var prevDom = prevLayer.dom; + if (prevDom.nextSibling) { + domRoot.insertBefore( + layer.dom, + prevDom.nextSibling + ); + } else { + domRoot.appendChild(layer.dom); + } + } else { + if (domRoot.firstChild) { + domRoot.insertBefore(layer.dom, domRoot.firstChild); + } else { + domRoot.appendChild(layer.dom); + } + } + } + }, + + // Iterate each layer + eachLayer: function(cb, context) { + var zlevelList = this._zlevelList; + var z; + var i; + for (i = 0; i < zlevelList.length; i++) { + z = zlevelList[i]; + cb.call(context, this._layers[z], z); + } + }, + + // Iterate each buildin layer + eachBuiltinLayer: function(cb, context) { + var zlevelList = this._zlevelList; + var layer; + var z; + var i; + for (i = 0; i < zlevelList.length; i++) { + z = zlevelList[i]; + layer = this._layers[z]; + if (layer.__builtin__) { + cb.call(context, layer, z); + } + } + }, + + // Iterate each other layer except buildin layer + eachOtherLayer: function(cb, context) { + var zlevelList = this._zlevelList; + var layer; + var z; + var i; + for (i = 0; i < zlevelList.length; i++) { + z = zlevelList[i]; + layer = this._layers[z]; + if (!layer.__builtin__) { + cb.call(context, layer, z); + } + } + }, + + /** + * 获取所有已创建的层 + * @param {Array.} [prevLayer] + */ + getLayers: function() { + return this._layers; + }, + + _updateLayerStatus: function(list) { + + this.eachBuiltinLayer(function(layer, z) { + layer.__dirty = layer.__used = false; + }); + + function updatePrevLayer(idx) { + if (prevLayer) { + if (prevLayer.__endIndex !== idx) { + prevLayer.__dirty = true; + } + prevLayer.__endIndex = idx; + } + } + + if (this._singleCanvas) { + for (var i = 1; i < list.length; i++) { + var el = list[i]; + if (el.zlevel !== list[i - 1].zlevel || el.incremental) { + this._needsManuallyCompositing = true; + break; + } + } + } + + var prevLayer = null; + var incrementalLayerCount = 0; + for (var i = 0; i < list.length; i++) { + var el = list[i]; + var zlevel = el.zlevel; + var layer; + // PENDING If change one incremental element style ? + // TODO Where there are non-incremental elements between incremental elements. + if (el.incremental) { + layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing); + layer.incremental = true; + incrementalLayerCount = 1; + } else { + layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing); + } + + if (!layer.__builtin__) { + zrLog('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id); + } + + if (layer !== prevLayer) { + layer.__used = true; + if (layer.__startIndex !== i) { + layer.__dirty = true; + } + layer.__startIndex = i; + if (!layer.incremental) { + layer.__drawIndex = i; + } else { + // Mark layer draw index needs to update. + layer.__drawIndex = -1; + } + updatePrevLayer(i); + prevLayer = layer; + } + if (el.__dirty) { + layer.__dirty = true; + if (layer.incremental && layer.__drawIndex < 0) { + // Start draw from the first dirty element. + layer.__drawIndex = i; + } + } + } + + updatePrevLayer(i); + + this.eachBuiltinLayer(function(layer, z) { + // Used in last frame but not in this frame. Needs clear + if (!layer.__used && layer.getElementCount() > 0) { + layer.__dirty = true; + layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0; + } + // For incremental layer. In case start index changed and no elements are dirty. + if (layer.__dirty && layer.__drawIndex < 0) { + layer.__drawIndex = layer.__startIndex; + } + }); + }, + + /** + * 清除hover层外所有内容 + */ + clear: function() { + this.eachBuiltinLayer(this._clearLayer); + return this; + }, + + _clearLayer: function(layer) { + layer.clear(); + }, + + setBackgroundColor: function(backgroundColor) { + this._backgroundColor = backgroundColor; + }, + + /** + * 修改指定zlevel的绘制参数 + * + * @param {string} zlevel + * @param {Object} config 配置对象 + * @param {string} [config.clearColor=0] 每次清空画布的颜色 + * @param {string} [config.motionBlur=false] 是否开启动态模糊 + * @param {number} [config.lastFrameAlpha=0.7] + * 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显 + */ + configLayer: function(zlevel, config) { + if (config) { + var layerConfig = this._layerConfig; + if (!layerConfig[zlevel]) { + layerConfig[zlevel] = config; + } else { + merge(layerConfig[zlevel], config, true); + } + + for (var i = 0; i < this._zlevelList.length; i++) { + var _zlevel = this._zlevelList[i]; + if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) { + var layer = this._layers[_zlevel]; + merge(layer, layerConfig[zlevel], true); + } + } + } + }, + + /** + * 删除指定层 + * @param {number} zlevel 层所在的zlevel + */ + delLayer: function(zlevel) { + var layers = this._layers; + var zlevelList = this._zlevelList; + var layer = layers[zlevel]; + if (!layer) { + return; + } + layer.dom.parentNode.removeChild(layer.dom); + delete layers[zlevel]; + + zlevelList.splice(indexOf(zlevelList, zlevel), 1); + }, + + /** + * 区域大小变化后重绘 + */ + resize: function(width, height) { + if (!this._domRoot.style) { // Maybe in node or worker + if (width == null || height == null) { + return; + } + this._width = width; + this._height = height; + + this.getLayer(CANVAS_ZLEVEL).resize(width, height); + } else { + var domRoot = this._domRoot; + // FIXME Why ? + domRoot.style.display = 'none'; + + // Save input w/h + var opts = this._opts; + width != null && (opts.width = width); + height != null && (opts.height = height); + + width = this._getSize(0); + height = this._getSize(1); + + domRoot.style.display = ''; + + // 优化没有实际改变的resize + if (this._width != width || height != this._height) { + domRoot.style.width = width + 'px'; + domRoot.style.height = height + 'px'; + + for (var id in this._layers) { + if (this._layers.hasOwnProperty(id)) { + this._layers[id].resize(width, height); + } + } + each$1(this._progressiveLayers, function(layer) { + layer.resize(width, height); + }); + + this.refresh(true); + } + + this._width = width; + this._height = height; + + } + return this; + }, + + /** + * 清除单独的一个层 + * @param {number} zlevel + */ + clearLayer: function(zlevel) { + var layer = this._layers[zlevel]; + if (layer) { + layer.clear(); + } + }, + + /** + * 释放 + */ + dispose: function() { + this.root.innerHTML = ''; + + this.root = + this.storage = + + this._domRoot = + this._layers = null; + }, + + /** + * Get canvas which has all thing rendered + * @param {Object} opts + * @param {string} [opts.backgroundColor] + * @param {number} [opts.pixelRatio] + */ + getRenderedCanvas: function(opts) { + opts = opts || {}; + if (this._singleCanvas && !this._compositeManually) { + return this._layers[CANVAS_ZLEVEL].dom; + } + + var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr); + imageLayer.initContext(); + imageLayer.clear(false, opts.backgroundColor || this._backgroundColor); + + if (opts.pixelRatio <= this.dpr) { + this.refresh(); + + var width = imageLayer.dom.width; + var height = imageLayer.dom.height; + var ctx = imageLayer.ctx; + this.eachLayer(function(layer) { + if (layer.__builtin__) { + ctx.drawImage(layer.dom, 0, 0, width, height); + } else if (layer.renderToCanvas) { + imageLayer.ctx.save(); + layer.renderToCanvas(imageLayer.ctx); + imageLayer.ctx.restore(); + } + }); + } else { + // PENDING, echarts-gl and incremental rendering. + var scope = {}; + var displayList = this.storage.getDisplayList(true); + for (var i = 0; i < displayList.length; i++) { + var el = displayList[i]; + this._doPaintEl(el, imageLayer, true, scope); + } + } + + return imageLayer.dom; + }, + /** + * 获取绘图区域宽度 + */ + getWidth: function() { + return this._width; + }, + + /** + * 获取绘图区域高度 + */ + getHeight: function() { + return this._height; + }, + + _getSize: function(whIdx) { + var opts = this._opts; + var wh = ['width', 'height'][whIdx]; + var cwh = ['clientWidth', 'clientHeight'][whIdx]; + var plt = ['paddingLeft', 'paddingTop'][whIdx]; + var prb = ['paddingRight', 'paddingBottom'][whIdx]; + + if (opts[wh] != null && opts[wh] !== 'auto') { + return parseFloat(opts[wh]); + } + + var root = this.root; + // IE8 does not support getComputedStyle, but it use VML. + var stl = document.defaultView.getComputedStyle(root); + + return ( + (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh])) - + (parseInt10(stl[plt]) || 0) - + (parseInt10(stl[prb]) || 0) + ) | 0; + }, + + pathToImage: function(path, dpr) { + dpr = dpr || this.dpr; + + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + var rect = path.getBoundingRect(); + var style = path.style; + var shadowBlurSize = style.shadowBlur * dpr; + var shadowOffsetX = style.shadowOffsetX * dpr; + var shadowOffsetY = style.shadowOffsetY * dpr; + var lineWidth = style.hasStroke() ? style.lineWidth : 0; + + var leftMargin = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize); + var rightMargin = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize); + var topMargin = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize); + var bottomMargin = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize); + var width = rect.width + leftMargin + rightMargin; + var height = rect.height + topMargin + bottomMargin; + + canvas.width = width * dpr; + canvas.height = height * dpr; + + ctx.scale(dpr, dpr); + ctx.clearRect(0, 0, width, height); + ctx.dpr = dpr; + + var pathTransform = { + position: path.position, + rotation: path.rotation, + scale: path.scale + }; + path.position = [leftMargin - rect.x, topMargin - rect.y]; + path.rotation = 0; + path.scale = [1, 1]; + path.updateTransform(); + if (path) { + path.brush(ctx); + } + + var ImageShape = ZImage; + var imgShape = new ImageShape({ + style: { + x: 0, + y: 0, + image: canvas + } + }); + + if (pathTransform.position != null) { + imgShape.position = path.position = pathTransform.position; + } + + if (pathTransform.rotation != null) { + imgShape.rotation = path.rotation = pathTransform.rotation; + } + + if (pathTransform.scale != null) { + imgShape.scale = path.scale = pathTransform.scale; + } + + return imgShape; + } + }; + + /** + * 事件辅助类 + * @module zrender/core/event + * @author Kener (@Kener-林峰, kener.linfeng@gmail.com) + */ + + var isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener; + + var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/; + + function getBoundingClientRect(el) { + // BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect + return el.getBoundingClientRect ? el.getBoundingClientRect() : { + left: 0, + top: 0 + }; + } + + // `calculate` is optional, default false + function clientToLocal(el, e, out, calculate) { + out = out || {}; + + // According to the W3C Working Draft, offsetX and offsetY should be relative + // to the padding edge of the target element. The only browser using this convention + // is IE. Webkit uses the border edge, Opera uses the content edge, and FireFox does + // not support the properties. + // (see http://www.jacklmoore.com/notes/mouse-position/) + // In zr painter.dom, padding edge equals to border edge. + + // FIXME + // When mousemove event triggered on ec tooltip, target is not zr painter.dom, and + // offsetX/Y is relative to e.target, where the calculation of zrX/Y via offsetX/Y + // is too complex. So css-transfrom dont support in this case temporarily. + if (calculate || !env$1.canvasSupported) { + defaultGetZrXY(el, e, out); + } + // Caution: In FireFox, layerX/layerY Mouse position relative to the closest positioned + // ancestor element, so we should make sure el is positioned (e.g., not position:static). + // BTW1, Webkit don't return the same results as FF in non-simple cases (like add + // zoom-factor, overflow / opacity layers, transforms ...) + // BTW2, (ev.offsetY || ev.pageY - $(ev.target).offset().top) is not correct in preserve-3d. + // + // BTW3, In ff, offsetX/offsetY is always 0. + else if (env$1.browser.firefox && e.layerX != null && e.layerX !== e.offsetX) { + out.zrX = e.layerX; + out.zrY = e.layerY; + } + // For IE6+, chrome, safari, opera. (When will ff support offsetX?) + else if (e.offsetX != null) { + out.zrX = e.offsetX; + out.zrY = e.offsetY; + } + // For some other device, e.g., IOS safari. + else { + defaultGetZrXY(el, e, out); + } + + return out; + } + + function defaultGetZrXY(el, e, out) { + // This well-known method below does not support css transform. + var box = getBoundingClientRect(el); + out.zrX = e.clientX - box.left; + out.zrY = e.clientY - box.top; + } + + /** + * 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标. + * `calculate` is optional, default false. + */ + function normalizeEvent(el, e, calculate) { + + e = e || window.event; + + if (e.zrX != null) { + return e; + } + + var eventType = e.type; + var isTouch = eventType && eventType.indexOf('touch') >= 0; + + if (!isTouch) { + clientToLocal(el, e, e, calculate); + e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3; + } else { + var touch = eventType != 'touchend' ? + e.targetTouches[0] : + e.changedTouches[0]; + touch && clientToLocal(el, touch, e, calculate); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right; otherwise: 0; + // See jQuery: https://github.com/jquery/jquery/blob/master/src/event.js + // If e.which has been defined, if may be readonly, + // see: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which + var button = e.button; + if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) { + e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); + } + + return e; + } + + /** + * @param {HTMLElement} el + * @param {string} name + * @param {Function} handler + */ + function addEventListener(el, name, handler) { + if (isDomLevel2) { + // Reproduct the console warning: + // [Violation] Added non-passive event listener to a scroll-blocking event. + // Consider marking event handler as 'passive' to make the page more responsive. + // Just set console log level: verbose in chrome dev tool. + // then the warning log will be printed when addEventListener called. + // See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md + // We have not yet found a neat way to using passive. Because in zrender the dom event + // listener delegate all of the upper events of element. Some of those events need + // to prevent default. For example, the feature `preventDefaultMouseMove` of echarts. + // Before passive can be adopted, these issues should be considered: + // (1) Whether and how a zrender user specifies an event listener passive. And by default, + // passive or not. + // (2) How to tread that some zrender event listener is passive, and some is not. If + // we use other way but not preventDefault of mousewheel and touchmove, browser + // compatibility should be handled. + + // var opts = (env.passiveSupported && name === 'mousewheel') + // ? {passive: true} + // // By default, the third param of el.addEventListener is `capture: false`. + // : void 0; + // el.addEventListener(name, handler /* , opts */); + el.addEventListener(name, handler); + } else { + el.attachEvent('on' + name, handler); + } + } + + function removeEventListener(el, name, handler) { + if (isDomLevel2) { + el.removeEventListener(name, handler); + } else { + el.detachEvent('on' + name, handler); + } + } + + /** + * preventDefault and stopPropagation. + * Notice: do not do that in zrender. Upper application + * do that if necessary. + * + * @memberOf module:zrender/core/event + * @method + * @param {Event} e : event对象 + */ + var stop = isDomLevel2 ? + function(e) { + e.preventDefault(); + e.stopPropagation(); + e.cancelBubble = true; + } : + function(e) { + e.returnValue = false; + e.cancelBubble = true; + }; + + function notLeftMouse(e) { + // If e.which is undefined, considered as left mouse event. + return e.which > 1; + } + + /** + * 动画主类, 调度和管理所有动画控制器 + * + * @module zrender/animation/Animation + * @author pissang(https://github.com/pissang) + */ + // TODO Additive animation + // http://iosoteric.com/additive-animations-animatewithduration-in-ios-8/ + // https://developer.apple.com/videos/wwdc2014/#236 + + /** + * @typedef {Object} IZRenderStage + * @property {Function} update + */ + + /** + * @alias module:zrender/animation/Animation + * @constructor + * @param {Object} [options] + * @param {Function} [options.onframe] + * @param {IZRenderStage} [options.stage] + * @example + * var animation = new Animation(); + * var obj = { + * x: 100, + * y: 100 + * }; + * animation.animate(node.position) + * .when(1000, { + * x: 500, + * y: 500 + * }) + * .when(2000, { + * x: 100, + * y: 100 + * }) + * .start('spline'); + */ + var Animation = function(options) { + + options = options || {}; + + this.stage = options.stage || {}; + + this.onframe = options.onframe || function() {}; + + // private properties + this._clips = []; + + this._running = false; + + this._time; + + this._pausedTime; + + this._pauseStart; + + this._paused = false; + + Eventful.call(this); + }; + + Animation.prototype = { + + constructor: Animation, + /** + * 添加 clip + * @param {module:zrender/animation/Clip} clip + */ + addClip: function(clip) { + this._clips.push(clip); + }, + /** + * 添加 animator + * @param {module:zrender/animation/Animator} animator + */ + addAnimator: function(animator) { + animator.animation = this; + var clips = animator.getClips(); + for (var i = 0; i < clips.length; i++) { + this.addClip(clips[i]); + } + }, + /** + * 删除动画片段 + * @param {module:zrender/animation/Clip} clip + */ + removeClip: function(clip) { + var idx = indexOf(this._clips, clip); + if (idx >= 0) { + this._clips.splice(idx, 1); + } + }, + + /** + * 删除动画片段 + * @param {module:zrender/animation/Animator} animator + */ + removeAnimator: function(animator) { + var clips = animator.getClips(); + for (var i = 0; i < clips.length; i++) { + this.removeClip(clips[i]); + } + animator.animation = null; + }, + + _update: function() { + var time = new Date().getTime() - this._pausedTime; + var delta = time - this._time; + var clips = this._clips; + var len = clips.length; + + var deferredEvents = []; + var deferredClips = []; + for (var i = 0; i < len; i++) { + var clip = clips[i]; + var e = clip.step(time, delta); + // Throw out the events need to be called after + // stage.update, like destroy + if (e) { + deferredEvents.push(e); + deferredClips.push(clip); + } + } + + // Remove the finished clip + for (var i = 0; i < len;) { + if (clips[i]._needsRemove) { + clips[i] = clips[len - 1]; + clips.pop(); + len--; + } else { + i++; + } + } + + len = deferredEvents.length; + for (var i = 0; i < len; i++) { + deferredClips[i].fire(deferredEvents[i]); + } + + this._time = time; + + this.onframe(delta); + + // 'frame' should be triggered before stage, because upper application + // depends on the sequence (e.g., echarts-stream and finish + // event judge) + this.trigger('frame', delta); + + if (this.stage.update) { + this.stage.update(); + } + }, + + _startLoop: function() { + var self = this; + + this._running = true; + + function step() { + if (self._running) { + + requestAnimationFrame(step); + + !self._paused && self._update(); + } + } + + requestAnimationFrame(step); + }, + + /** + * Start animation. + */ + start: function() { + + this._time = new Date().getTime(); + this._pausedTime = 0; + + this._startLoop(); + }, + + /** + * Stop animation. + */ + stop: function() { + this._running = false; + }, + + /** + * Pause animation. + */ + pause: function() { + if (!this._paused) { + this._pauseStart = new Date().getTime(); + this._paused = true; + } + }, + + /** + * Resume animation. + */ + resume: function() { + if (this._paused) { + this._pausedTime += (new Date().getTime()) - this._pauseStart; + this._paused = false; + } + }, + + /** + * Clear animation. + */ + clear: function() { + this._clips = []; + }, + + /** + * Whether animation finished. + */ + isFinished: function() { + return !this._clips.length; + }, + + /** + * Creat animator for a target, whose props can be animated. + * + * @param {Object} target + * @param {Object} options + * @param {boolean} [options.loop=false] Whether loop animation. + * @param {Function} [options.getter=null] Get value from target. + * @param {Function} [options.setter=null] Set value to target. + * @return {module:zrender/animation/Animation~Animator} + */ + // TODO Gap + animate: function(target, options) { + options = options || {}; + + var animator = new Animator( + target, + options.loop, + options.getter, + options.setter + ); + + this.addAnimator(animator); + + return animator; + } + }; + + mixin(Animation, Eventful); + + /** + * Only implements needed gestures for mobile. + */ + + var GestureMgr = function() { + + /** + * @private + * @type {Array.} + */ + this._track = []; + }; + + GestureMgr.prototype = { + + constructor: GestureMgr, + + recognize: function(event, target, root) { + this._doTrack(event, target, root); + return this._recognize(event); + }, + + clear: function() { + this._track.length = 0; + return this; + }, + + _doTrack: function(event, target, root) { + var touches = event.touches; + + if (!touches) { + return; + } + + var trackItem = { + points: [], + touches: [], + target: target, + event: event + }; + + for (var i = 0, len = touches.length; i < len; i++) { + var touch = touches[i]; + var pos = clientToLocal(root, touch, {}); + trackItem.points.push([pos.zrX, pos.zrY]); + trackItem.touches.push(touch); + } + + this._track.push(trackItem); + }, + + _recognize: function(event) { + for (var eventName in recognizers) { + if (recognizers.hasOwnProperty(eventName)) { + var gestureInfo = recognizers[eventName](this._track, event); + if (gestureInfo) { + return gestureInfo; + } + } + } + } + }; + + function dist$1(pointPair) { + var dx = pointPair[1][0] - pointPair[0][0]; + var dy = pointPair[1][1] - pointPair[0][1]; + + return Math.sqrt(dx * dx + dy * dy); + } + + function center(pointPair) { + return [ + (pointPair[0][0] + pointPair[1][0]) / 2, + (pointPair[0][1] + pointPair[1][1]) / 2 + ]; + } + + var recognizers = { + + pinch: function(track, event) { + var trackLen = track.length; + + if (!trackLen) { + return; + } + + var pinchEnd = (track[trackLen - 1] || {}).points; + var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd; + + if (pinchPre && + pinchPre.length > 1 && + pinchEnd && + pinchEnd.length > 1 + ) { + var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre); + !isFinite(pinchScale) && (pinchScale = 1); + + event.pinchScale = pinchScale; + + var pinchCenter = center(pinchEnd); + event.pinchX = pinchCenter[0]; + event.pinchY = pinchCenter[1]; + + return { + type: 'pinch', + target: track[0].target, + event: event + }; + } + } + + // Only pinch currently. + }; + + var TOUCH_CLICK_DELAY = 300; + + var mouseHandlerNames = [ + 'click', 'dblclick', 'mousewheel', 'mouseout', + 'mouseup', 'mousedown', 'mousemove', 'contextmenu' + ]; + + var touchHandlerNames = [ + 'touchstart', 'touchend', 'touchmove' + ]; + + var pointerEventNames = { + pointerdown: 1, + pointerup: 1, + pointermove: 1, + pointerout: 1 + }; + + var pointerHandlerNames = map(mouseHandlerNames, function(name) { + var nm = name.replace('mouse', 'pointer'); + return pointerEventNames[nm] ? nm : name; + }); + + function eventNameFix(name) { + return (name === 'mousewheel' && env$1.browser.firefox) ? 'DOMMouseScroll' : name; + } + + function processGesture(proxy, event, stage) { + var gestureMgr = proxy._gestureMgr; + + stage === 'start' && gestureMgr.clear(); + + var gestureInfo = gestureMgr.recognize( + event, + proxy.handler.findHover(event.zrX, event.zrY, null).target, + proxy.dom + ); + + stage === 'end' && gestureMgr.clear(); + + // Do not do any preventDefault here. Upper application do that if necessary. + if (gestureInfo) { + var type = gestureInfo.type; + event.gestureEvent = type; + + proxy.handler.dispatchToElement({ + target: gestureInfo.target + }, type, gestureInfo.event); + } + } + + // function onMSGestureChange(proxy, event) { + // if (event.translationX || event.translationY) { + // // mousemove is carried by MSGesture to reduce the sensitivity. + // proxy.handler.dispatchToElement(event.target, 'mousemove', event); + // } + // if (event.scale !== 1) { + // event.pinchX = event.offsetX; + // event.pinchY = event.offsetY; + // event.pinchScale = event.scale; + // proxy.handler.dispatchToElement(event.target, 'pinch', event); + // } + // } + + /** + * Prevent mouse event from being dispatched after Touch Events action + * @see + * 1. Mobile browsers dispatch mouse events 300ms after touchend. + * 2. Chrome for Android dispatch mousedown for long-touch about 650ms + * Result: Blocking Mouse Events for 700ms. + */ + function setTouchTimer(instance) { + instance._touching = true; + clearTimeout(instance._touchTimer); + instance._touchTimer = setTimeout(function() { + instance._touching = false; + }, 700); + } + + + var domHandlers = { + /** + * Mouse move handler + * @inner + * @param {Event} event + */ + mousemove: function(event) { + event = normalizeEvent(this.dom, event); + + this.trigger('mousemove', event); + }, + + /** + * Mouse out handler + * @inner + * @param {Event} event + */ + mouseout: function(event) { + event = normalizeEvent(this.dom, event); + + var element = event.toElement || event.relatedTarget; + if (element != this.dom) { + while (element && element.nodeType != 9) { + // 忽略包含在root中的dom引起的mouseOut + if (element === this.dom) { + return; + } + + element = element.parentNode; + } + } + + this.trigger('mouseout', event); + }, + + /** + * Touch开始响应函数 + * @inner + * @param {Event} event + */ + touchstart: function(event) { + // Default mouse behaviour should not be disabled here. + // For example, page may needs to be slided. + event = normalizeEvent(this.dom, event); + + // Mark touch, which is useful in distinguish touch and + // mouse event in upper applicatoin. + event.zrByTouch = true; + + this._lastTouchMoment = new Date(); + + processGesture(this, event, 'start'); + + // In touch device, trigger `mousemove`(`mouseover`) should + // be triggered, and must before `mousedown` triggered. + domHandlers.mousemove.call(this, event); + + domHandlers.mousedown.call(this, event); + + setTouchTimer(this); + }, + + /** + * Touch移动响应函数 + * @inner + * @param {Event} event + */ + touchmove: function(event) { + + event = normalizeEvent(this.dom, event); + + // Mark touch, which is useful in distinguish touch and + // mouse event in upper applicatoin. + event.zrByTouch = true; + + processGesture(this, event, 'change'); + + // Mouse move should always be triggered no matter whether + // there is gestrue event, because mouse move and pinch may + // be used at the same time. + domHandlers.mousemove.call(this, event); + + setTouchTimer(this); + }, + + /** + * Touch结束响应函数 + * @inner + * @param {Event} event + */ + touchend: function(event) { + + event = normalizeEvent(this.dom, event); + + // Mark touch, which is useful in distinguish touch and + // mouse event in upper applicatoin. + event.zrByTouch = true; + + processGesture(this, event, 'end'); + + domHandlers.mouseup.call(this, event); + + // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is + // triggered in `touchstart`. This seems to be illogical, but by this mechanism, + // we can conveniently implement "hover style" in both PC and touch device just + // by listening to `mouseover` to add "hover style" and listening to `mouseout` + // to remove "hover style" on an element, without any additional code for + // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover + // style" will remain for user view) + + // click event should always be triggered no matter whether + // there is gestrue event. System click can not be prevented. + if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) { + domHandlers.click.call(this, event); + } + + setTouchTimer(this); + }, + + pointerdown: function(event) { + domHandlers.mousedown.call(this, event); + + // if (useMSGuesture(this, event)) { + // this._msGesture.addPointer(event.pointerId); + // } + }, + + pointermove: function(event) { + // FIXME + // pointermove is so sensitive that it always triggered when + // tap(click) on touch screen, which affect some judgement in + // upper application. So, we dont support mousemove on MS touch + // device yet. + if (!isPointerFromTouch(event)) { + domHandlers.mousemove.call(this, event); + } + }, + + pointerup: function(event) { + domHandlers.mouseup.call(this, event); + }, + + pointerout: function(event) { + // pointerout will be triggered when tap on touch screen + // (IE11+/Edge on MS Surface) after click event triggered, + // which is inconsistent with the mousout behavior we defined + // in touchend. So we unify them. + // (check domHandlers.touchend for detailed explanation) + if (!isPointerFromTouch(event)) { + domHandlers.mouseout.call(this, event); + } + } + }; + + function isPointerFromTouch(event) { + var pointerType = event.pointerType; + return pointerType === 'pen' || pointerType === 'touch'; + } + + // function useMSGuesture(handlerProxy, event) { + // return isPointerFromTouch(event) && !!handlerProxy._msGesture; + // } + + // Common handlers + each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function(name) { + domHandlers[name] = function(event) { + event = normalizeEvent(this.dom, event); + this.trigger(name, event); + }; + }); + + /** + * 为控制类实例初始化dom 事件处理函数 + * + * @inner + * @param {module:zrender/Handler} instance 控制类实例 + */ + function initDomHandler(instance) { + each$1(touchHandlerNames, function(name) { + instance._handlers[name] = bind(domHandlers[name], instance); + }); + + each$1(pointerHandlerNames, function(name) { + instance._handlers[name] = bind(domHandlers[name], instance); + }); + + each$1(mouseHandlerNames, function(name) { + instance._handlers[name] = makeMouseHandler(domHandlers[name], instance); + }); + + function makeMouseHandler(fn, instance) { + return function() { + if (instance._touching) { + return; + } + return fn.apply(instance, arguments); + }; + } + } + + + function HandlerDomProxy(dom) { + Eventful.call(this); + + this.dom = dom; + + /** + * @private + * @type {boolean} + */ + this._touching = false; + + /** + * @private + * @type {number} + */ + this._touchTimer; + + /** + * @private + * @type {module:zrender/core/GestureMgr} + */ + this._gestureMgr = new GestureMgr(); + + this._handlers = {}; + + initDomHandler(this); + + if (env$1.pointerEventsSupported) { // Only IE11+/Edge + // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240), + // IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event + // at the same time. + // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on + // screen, which do not occurs in pointer event. + // So we use pointer event to both detect touch gesture and mouse behavior. + mountHandlers(pointerHandlerNames, this); + + // FIXME + // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable, + // which does not prevent defuault behavior occasionally (which may cause view port + // zoomed in but use can not zoom it back). And event.preventDefault() does not work. + // So we have to not to use MSGesture and not to support touchmove and pinch on MS + // touch screen. And we only support click behavior on MS touch screen now. + + // MS Gesture Event is only supported on IE11+/Edge and on Windows 8+. + // We dont support touch on IE on win7. + // See + // if (typeof MSGesture === 'function') { + // (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line + // dom.addEventListener('MSGestureChange', onMSGestureChange); + // } + } else { + if (env$1.touchEventsSupported) { + mountHandlers(touchHandlerNames, this); + // Handler of 'mouseout' event is needed in touch mode, which will be mounted below. + // addEventListener(root, 'mouseout', this._mouseoutHandler); + } + + // 1. Considering some devices that both enable touch and mouse event (like on MS Surface + // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise + // mouse event can not be handle in those devices. + // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent + // mouseevent after touch event triggered, see `setTouchTimer`. + mountHandlers(mouseHandlerNames, this); + } + + function mountHandlers(handlerNames, instance) { + each$1(handlerNames, function(name) { + addEventListener(dom, eventNameFix(name), instance._handlers[name]); + }, instance); + } + } + + var handlerDomProxyProto = HandlerDomProxy.prototype; + handlerDomProxyProto.dispose = function() { + var handlerNames = mouseHandlerNames.concat(touchHandlerNames); + + for (var i = 0; i < handlerNames.length; i++) { + var name = handlerNames[i]; + removeEventListener(this.dom, eventNameFix(name), this._handlers[name]); + } + }; + + handlerDomProxyProto.setCursor = function(cursorStyle) { + this.dom.style && (this.dom.style.cursor = cursorStyle || 'default'); + }; + + mixin(HandlerDomProxy, Eventful); + + /*! + * ZRender, a high performance 2d drawing library. + * + * Copyright (c) 2013, Baidu Inc. + * All rights reserved. + * + * LICENSE + * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt + */ + + var useVML = !env$1.canvasSupported; + + var painterCtors = { + canvas: Painter + }; + + var instances$1 = {}; // ZRender实例map索引 + + /** + * @type {string} + */ + var version$1 = '4.0.4'; + + /** + * Initializing a zrender instance + * @param {HTMLElement} dom + * @param {Object} opts + * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg' + * @param {number} [opts.devicePixelRatio] + * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined) + * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined) + * @return {module:zrender/ZRender} + */ + function init$1(dom, opts) { + var zr = new ZRender(guid(), dom, opts); + instances$1[zr.id] = zr; + return zr; + } + + /** + * Dispose zrender instance + * @param {module:zrender/ZRender} zr + */ + function dispose$1(zr) { + if (zr) { + zr.dispose(); + } else { + for (var key in instances$1) { + if (instances$1.hasOwnProperty(key)) { + instances$1[key].dispose(); + } + } + instances$1 = {}; + } + + return this; + } + + /** + * Get zrender instance by id + * @param {string} id zrender instance id + * @return {module:zrender/ZRender} + */ + function getInstance(id) { + return instances$1[id]; + } + + function registerPainter(name, Ctor) { + painterCtors[name] = Ctor; + } + + function delInstance(id) { + delete instances$1[id]; + } + + /** + * @module zrender/ZRender + */ + /** + * @constructor + * @alias module:zrender/ZRender + * @param {string} id + * @param {HTMLElement} dom + * @param {Object} opts + * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg' + * @param {number} [opts.devicePixelRatio] + * @param {number} [opts.width] Can be 'auto' (the same as null/undefined) + * @param {number} [opts.height] Can be 'auto' (the same as null/undefined) + */ + var ZRender = function(id, dom, opts) { + + opts = opts || {}; + + /** + * @type {HTMLDomElement} + */ + this.dom = dom; + + /** + * @type {string} + */ + this.id = id; + + var self = this; + var storage = new Storage(); + + var rendererType = opts.renderer; + // TODO WebGL + if (useVML) { + if (!painterCtors.vml) { + throw new Error('You need to require \'zrender/vml/vml\' to support IE8'); + } + rendererType = 'vml'; + } else if (!rendererType || !painterCtors[rendererType]) { + rendererType = 'canvas'; + } + var painter = new painterCtors[rendererType](dom, storage, opts, id); + + this.storage = storage; + this.painter = painter; + + var handerProxy = (!env$1.node && !env$1.worker) ? new HandlerDomProxy(painter.getViewportRoot()) : null; + this.handler = new Handler(storage, painter, handerProxy, painter.root); + + /** + * @type {module:zrender/animation/Animation} + */ + this.animation = new Animation({ + stage: { + update: bind(this.flush, this) + } + }); + this.animation.start(); + + /** + * @type {boolean} + * @private + */ + this._needsRefresh; + + // 修改 storage.delFromStorage, 每次删除元素之前删除动画 + // FIXME 有点ugly + var oldDelFromStorage = storage.delFromStorage; + var oldAddToStorage = storage.addToStorage; + + storage.delFromStorage = function(el) { + oldDelFromStorage.call(storage, el); + + el && el.removeSelfFromZr(self); + }; + + storage.addToStorage = function(el) { + oldAddToStorage.call(storage, el); + + el.addSelfToZr(self); + }; + }; + + ZRender.prototype = { + + constructor: ZRender, + /** + * 获取实例唯一标识 + * @return {string} + */ + getId: function() { + return this.id; + }, + + /** + * 添加元素 + * @param {module:zrender/Element} el + */ + add: function(el) { + this.storage.addRoot(el); + this._needsRefresh = true; + }, + + /** + * 删除元素 + * @param {module:zrender/Element} el + */ + remove: function(el) { + this.storage.delRoot(el); + this._needsRefresh = true; + }, + + /** + * Change configuration of layer + * @param {string} zLevel + * @param {Object} config + * @param {string} [config.clearColor=0] Clear color + * @param {string} [config.motionBlur=false] If enable motion blur + * @param {number} [config.lastFrameAlpha=0.7] Motion blur factor. Larger value cause longer trailer + */ + configLayer: function(zLevel, config) { + if (this.painter.configLayer) { + this.painter.configLayer(zLevel, config); + } + this._needsRefresh = true; + }, + + /** + * Set background color + * @param {string} backgroundColor + */ + setBackgroundColor: function(backgroundColor) { + if (this.painter.setBackgroundColor) { + this.painter.setBackgroundColor(backgroundColor); + } + this._needsRefresh = true; + }, + + /** + * Repaint the canvas immediately + */ + refreshImmediately: function() { + // var start = new Date(); + // Clear needsRefresh ahead to avoid something wrong happens in refresh + // Or it will cause zrender refreshes again and again. + this._needsRefresh = false; + this.painter.refresh(); + /** + * Avoid trigger zr.refresh in Element#beforeUpdate hook + */ + this._needsRefresh = false; + // var end = new Date(); + // var log = document.getElementById('log'); + // if (log) { + // log.innerHTML = log.innerHTML + '
' + (end - start); + // } + }, + + /** + * Mark and repaint the canvas in the next frame of browser + */ + refresh: function() { + this._needsRefresh = true; + }, + + /** + * Perform all refresh + */ + flush: function() { + var triggerRendered; + + if (this._needsRefresh) { + triggerRendered = true; + this.refreshImmediately(); + } + if (this._needsRefreshHover) { + triggerRendered = true; + this.refreshHoverImmediately(); + } + + triggerRendered && this.trigger('rendered'); + }, + + /** + * Add element to hover layer + * @param {module:zrender/Element} el + * @param {Object} style + */ + addHover: function(el, style) { + if (this.painter.addHover) { + this.painter.addHover(el, style); + this.refreshHover(); + } + }, + + /** + * Add element from hover layer + * @param {module:zrender/Element} el + */ + removeHover: function(el) { + if (this.painter.removeHover) { + this.painter.removeHover(el); + this.refreshHover(); + } + }, + + /** + * Clear all hover elements in hover layer + * @param {module:zrender/Element} el + */ + clearHover: function() { + if (this.painter.clearHover) { + this.painter.clearHover(); + this.refreshHover(); + } + }, + + /** + * Refresh hover in next frame + */ + refreshHover: function() { + this._needsRefreshHover = true; + }, + + /** + * Refresh hover immediately + */ + refreshHoverImmediately: function() { + this._needsRefreshHover = false; + this.painter.refreshHover && this.painter.refreshHover(); + }, + + /** + * Resize the canvas. + * Should be invoked when container size is changed + * @param {Object} [opts] + * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined) + * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined) + */ + resize: function(opts) { + opts = opts || {}; + this.painter.resize(opts.width, opts.height); + this.handler.resize(); + }, + + /** + * Stop and clear all animation immediately + */ + clearAnimation: function() { + this.animation.clear(); + }, + + /** + * Get container width + */ + getWidth: function() { + return this.painter.getWidth(); + }, + + /** + * Get container height + */ + getHeight: function() { + return this.painter.getHeight(); + }, + + /** + * Export the canvas as Base64 URL + * @param {string} type + * @param {string} [backgroundColor='#fff'] + * @return {string} Base64 URL + */ + // toDataURL: function(type, backgroundColor) { + // return this.painter.getRenderedCanvas({ + // backgroundColor: backgroundColor + // }).toDataURL(type); + // }, + + /** + * Converting a path to image. + * It has much better performance of drawing image rather than drawing a vector path. + * @param {module:zrender/graphic/Path} e + * @param {number} width + * @param {number} height + */ + pathToImage: function(e, dpr) { + return this.painter.pathToImage(e, dpr); + }, + + /** + * Set default cursor + * @param {string} [cursorStyle='default'] 例如 crosshair + */ + setCursorStyle: function(cursorStyle) { + this.handler.setCursorStyle(cursorStyle); + }, + + /** + * Find hovered element + * @param {number} x + * @param {number} y + * @return {Object} {target, topTarget} + */ + findHover: function(x, y) { + return this.handler.findHover(x, y); + }, + + /** + * Bind event + * + * @param {string} eventName Event name + * @param {Function} eventHandler Handler function + * @param {Object} [context] Context object + */ + on: function(eventName, eventHandler, context) { + this.handler.on(eventName, eventHandler, context); + }, + + /** + * Unbind event + * @param {string} eventName Event name + * @param {Function} [eventHandler] Handler function + */ + off: function(eventName, eventHandler) { + this.handler.off(eventName, eventHandler); + }, + + /** + * Trigger event manually + * + * @param {string} eventName Event name + * @param {event=} event Event object + */ + trigger: function(eventName, event) { + this.handler.trigger(eventName, event); + }, + + + /** + * Clear all objects and the canvas. + */ + clear: function() { + this.storage.delRoot(); + this.painter.clear(); + }, + + /** + * Dispose self. + */ + dispose: function() { + this.animation.stop(); + + this.clear(); + this.storage.dispose(); + this.painter.dispose(); + this.handler.dispose(); + + this.animation = + this.storage = + this.painter = + this.handler = null; + + delInstance(this.id); + } + }; + + + + var zrender = (Object.freeze || Object)({ + version: version$1, + init: init$1, + dispose: dispose$1, + getInstance: getInstance, + registerPainter: registerPainter + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$2 = each$1; + var isObject$2 = isObject$1; + var isArray$1 = isArray; + + /** + * Make the name displayable. But we should + * make sure it is not duplicated with user + * specified name, so use '\0'; + */ + var DUMMY_COMPONENT_NAME_PREFIX = 'series\0'; + + /** + * If value is not array, then translate it to array. + * @param {*} value + * @return {Array} [value] or value + */ + function normalizeToArray(value) { + return value instanceof Array ? + value : + value == null ? + [] : + [value]; + } + + /** + * Sync default option between normal and emphasis like `position` and `show` + * In case some one will write code like + * label: { + * show: false, + * position: 'outside', + * fontSize: 18 + * }, + * emphasis: { + * label: { show: true } + * } + * @param {Object} opt + * @param {string} key + * @param {Array.} subOpts + */ + function defaultEmphasis(opt, key, subOpts) { + // Caution: performance sensitive. + if (opt) { + opt[key] = opt[key] || {}; + opt.emphasis = opt.emphasis || {}; + opt.emphasis[key] = opt.emphasis[key] || {}; + + // Default emphasis option from normal + for (var i = 0, len = subOpts.length; i < len; i++) { + var subOptName = subOpts[i]; + if (!opt.emphasis[key].hasOwnProperty(subOptName) && + opt[key].hasOwnProperty(subOptName) + ) { + opt.emphasis[key][subOptName] = opt[key][subOptName]; + } + } + } + } + + var TEXT_STYLE_OPTIONS = [ + 'fontStyle', 'fontWeight', 'fontSize', 'fontFamily', + 'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth', + 'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline', + 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', + 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY', + 'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding' + ]; + + // modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([ + // 'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter', + // 'fontStyle', 'fontWeight', 'fontSize', 'fontFamily', + // // FIXME: deprecated, check and remove it. + // 'textStyle' + // ]); + + /** + * The method do not ensure performance. + * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}] + * This helper method retieves value from data. + * @param {string|number|Date|Array|Object} dataItem + * @return {number|string|Date|Array.} + */ + function getDataItemValue(dataItem) { + return (isObject$2(dataItem) && !isArray$1(dataItem) && !(dataItem instanceof Date)) ? + dataItem.value : dataItem; + } + + /** + * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}] + * This helper method determine if dataItem has extra option besides value + * @param {string|number|Date|Array|Object} dataItem + */ + function isDataItemOption(dataItem) { + return isObject$2(dataItem) && + !(dataItem instanceof Array); + // // markLine data can be array + // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array)); + } + + /** + * Mapping to exists for merge. + * + * @public + * @param {Array.|Array.} exists + * @param {Object|Array.} newCptOptions + * @return {Array.} Result, like [{exist: ..., option: ...}, {}], + * index of which is the same as exists. + */ + function mappingToExists(exists, newCptOptions) { + // Mapping by the order by original option (but not order of + // new option) in merge mode. Because we should ensure + // some specified index (like xAxisIndex) is consistent with + // original option, which is easy to understand, espatially in + // media query. And in most case, merge option is used to + // update partial option but not be expected to change order. + newCptOptions = (newCptOptions || []).slice(); + + var result = map(exists || [], function(obj, index) { + return { + exist: obj + }; + }); + + // Mapping by id or name if specified. + each$2(newCptOptions, function(cptOption, index) { + if (!isObject$2(cptOption)) { + return; + } + + // id has highest priority. + for (var i = 0; i < result.length; i++) { + if (!result[i].option // Consider name: two map to one. + && + cptOption.id != null && + result[i].exist.id === cptOption.id + '' + ) { + result[i].option = cptOption; + newCptOptions[index] = null; + return; + } + } + + for (var i = 0; i < result.length; i++) { + var exist = result[i].exist; + if (!result[i].option // Consider name: two map to one. + // Can not match when both ids exist but different. + && + (exist.id == null || cptOption.id == null) && + cptOption.name != null && + !isIdInner(cptOption) && + !isIdInner(exist) && + exist.name === cptOption.name + '' + ) { + result[i].option = cptOption; + newCptOptions[index] = null; + return; + } + } + }); + + // Otherwise mapping by index. + each$2(newCptOptions, function(cptOption, index) { + if (!isObject$2(cptOption)) { + return; + } + + var i = 0; + for (; i < result.length; i++) { + var exist = result[i].exist; + if (!result[i].option + // Existing model that already has id should be able to + // mapped to (because after mapping performed model may + // be assigned with a id, whish should not affect next + // mapping), except those has inner id. + && + !isIdInner(exist) + // Caution: + // Do not overwrite id. But name can be overwritten, + // because axis use name as 'show label text'. + // 'exist' always has id and name and we dont + // need to check it. + && + cptOption.id == null + ) { + result[i].option = cptOption; + break; + } + } + + if (i >= result.length) { + result.push({ + option: cptOption + }); + } + }); + + return result; + } + + /** + * Make id and name for mapping result (result of mappingToExists) + * into `keyInfo` field. + * + * @public + * @param {Array.} Result, like [{exist: ..., option: ...}, {}], + * which order is the same as exists. + * @return {Array.} The input. + */ + function makeIdAndName(mapResult) { + // We use this id to hash component models and view instances + // in echarts. id can be specified by user, or auto generated. + + // The id generation rule ensures new view instance are able + // to mapped to old instance when setOption are called in + // no-merge mode. So we generate model id by name and plus + // type in view id. + + // name can be duplicated among components, which is convenient + // to specify multi components (like series) by one name. + + // Ensure that each id is distinct. + var idMap = createHashMap(); + + each$2(mapResult, function(item, index) { + var existCpt = item.exist; + existCpt && idMap.set(existCpt.id, item); + }); + + each$2(mapResult, function(item, index) { + var opt = item.option; + + assert$1( + !opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, + 'id duplicates: ' + (opt && opt.id) + ); + + opt && opt.id != null && idMap.set(opt.id, item); + !item.keyInfo && (item.keyInfo = {}); + }); + + // Make name and id. + each$2(mapResult, function(item, index) { + var existCpt = item.exist; + var opt = item.option; + var keyInfo = item.keyInfo; + + if (!isObject$2(opt)) { + return; + } + + // name can be overwitten. Consider case: axis.name = '20km'. + // But id generated by name will not be changed, which affect + // only in that case: setOption with 'not merge mode' and view + // instance will be recreated, which can be accepted. + keyInfo.name = opt.name != null ? + opt.name + '' : + existCpt ? + existCpt.name + // Avoid diffferent series has the same name, + // because name may be used like in color pallet. + : + DUMMY_COMPONENT_NAME_PREFIX + index; + + if (existCpt) { + keyInfo.id = existCpt.id; + } else if (opt.id != null) { + keyInfo.id = opt.id + ''; + } else { + // Consider this situatoin: + // optionA: [{name: 'a'}, {name: 'a'}, {..}] + // optionB [{..}, {name: 'a'}, {name: 'a'}] + // Series with the same name between optionA and optionB + // should be mapped. + var idNum = 0; + do { + keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++; + } + while (idMap.get(keyInfo.id)); + } + + idMap.set(keyInfo.id, item); + }); + } + + function isNameSpecified(componentModel) { + var name = componentModel.name; + // Is specified when `indexOf` get -1 or > 0. + return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX)); + } + + /** + * @public + * @param {Object} cptOption + * @return {boolean} + */ + function isIdInner(cptOption) { + return isObject$2(cptOption) && + cptOption.id && + (cptOption.id + '').indexOf('\0_ec_\0') === 0; + } + + /** + * A helper for removing duplicate items between batchA and batchB, + * and in themselves, and categorize by series. + * + * @param {Array.} batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...] + * @param {Array.} batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...] + * @return {Array., Array.>} result: [resultBatchA, resultBatchB] + */ + function compressBatches(batchA, batchB) { + var mapA = {}; + var mapB = {}; + + makeMap(batchA || [], mapA); + makeMap(batchB || [], mapB, mapA); + + return [mapToArray(mapA), mapToArray(mapB)]; + + function makeMap(sourceBatch, map$$1, otherMap) { + for (var i = 0, len = sourceBatch.length; i < len; i++) { + var seriesId = sourceBatch[i].seriesId; + var dataIndices = normalizeToArray(sourceBatch[i].dataIndex); + var otherDataIndices = otherMap && otherMap[seriesId]; + + for (var j = 0, lenj = dataIndices.length; j < lenj; j++) { + var dataIndex = dataIndices[j]; + + if (otherDataIndices && otherDataIndices[dataIndex]) { + otherDataIndices[dataIndex] = null; + } else { + (map$$1[seriesId] || (map$$1[seriesId] = {}))[dataIndex] = 1; + } + } + } + } + + function mapToArray(map$$1, isData) { + var result = []; + for (var i in map$$1) { + if (map$$1.hasOwnProperty(i) && map$$1[i] != null) { + if (isData) { + result.push(+i); + } else { + var dataIndices = mapToArray(map$$1[i], true); + dataIndices.length && result.push({ + seriesId: i, + dataIndex: dataIndices + }); + } + } + } + return result; + } + } + + /** + * @param {module:echarts/data/List} data + * @param {Object} payload Contains dataIndex (means rawIndex) / dataIndexInside / name + * each of which can be Array or primary type. + * @return {number|Array.} dataIndex If not found, return undefined/null. + */ + function queryDataIndex(data, payload) { + if (payload.dataIndexInside != null) { + return payload.dataIndexInside; + } else if (payload.dataIndex != null) { + return isArray(payload.dataIndex) ? + map(payload.dataIndex, function(value) { + return data.indexOfRawIndex(value); + }) : + data.indexOfRawIndex(payload.dataIndex); + } else if (payload.name != null) { + return isArray(payload.name) ? + map(payload.name, function(value) { + return data.indexOfName(value); + }) : + data.indexOfName(payload.name); + } + } + + /** + * Enable property storage to any host object. + * Notice: Serialization is not supported. + * + * For example: + * var inner = zrUitl.makeInner(); + * + * function some1(hostObj) { + * inner(hostObj).someProperty = 1212; + * ... + * } + * function some2() { + * var fields = inner(this); + * fields.someProperty1 = 1212; + * fields.someProperty2 = 'xx'; + * ... + * } + * + * @return {Function} + */ + function makeInner() { + // Consider different scope by es module import. + var key = '__\0ec_inner_' + innerUniqueIndex++ + '_' + Math.random().toFixed(5); + return function(hostObj) { + return hostObj[key] || (hostObj[key] = {}); + }; + } + var innerUniqueIndex = 0; + + /** + * @param {module:echarts/model/Global} ecModel + * @param {string|Object} finder + * If string, e.g., 'geo', means {geoIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex, seriesId, seriesName, + * geoIndex, geoId, geoName, + * bmapIndex, bmapId, bmapName, + * xAxisIndex, xAxisId, xAxisName, + * yAxisIndex, yAxisId, yAxisName, + * gridIndex, gridId, gridName, + * ... (can be extended) + * } + * Each properties can be number|string|Array.|Array. + * For example, a finder could be + * { + * seriesIndex: 3, + * geoId: ['aa', 'cc'], + * gridName: ['xx', 'rr'] + * } + * xxxIndex can be set as 'all' (means all xxx) or 'none' (means not specify) + * If nothing or null/undefined specified, return nothing. + * @param {Object} [opt] + * @param {string} [opt.defaultMainType] + * @param {Array.} [opt.includeMainTypes] + * @return {Object} result like: + * { + * seriesModels: [seriesModel1, seriesModel2], + * seriesModel: seriesModel1, // The first model + * geoModels: [geoModel1, geoModel2], + * geoModel: geoModel1, // The first model + * ... + * } + */ + function parseFinder(ecModel, finder, opt) { + if (isString(finder)) { + var obj = {}; + obj[finder + 'Index'] = 0; + finder = obj; + } + + var defaultMainType = opt && opt.defaultMainType; + if (defaultMainType && + !has(finder, defaultMainType + 'Index') && + !has(finder, defaultMainType + 'Id') && + !has(finder, defaultMainType + 'Name') + ) { + finder[defaultMainType + 'Index'] = 0; + } + + var result = {}; + + each$2(finder, function(value, key) { + var value = finder[key]; + + // Exclude 'dataIndex' and other illgal keys. + if (key === 'dataIndex' || key === 'dataIndexInside') { + result[key] = value; + return; + } + + var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || []; + var mainType = parsedKey[1]; + var queryType = (parsedKey[2] || '').toLowerCase(); + + if (!mainType || + !queryType || + value == null || + (queryType === 'index' && value === 'none') || + (opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0) + ) { + return; + } + + var queryParam = { + mainType: mainType + }; + if (queryType !== 'index' || value !== 'all') { + queryParam[queryType] = value; + } + + var models = ecModel.queryComponents(queryParam); + result[mainType + 'Models'] = models; + result[mainType + 'Model'] = models[0]; + }); + + return result; + } + + function has(obj, prop) { + return obj && obj.hasOwnProperty(prop); + } + + function setAttribute(dom, key, value) { + dom.setAttribute ? + dom.setAttribute(key, value) : + (dom[key] = value); + } + + function getAttribute(dom, key) { + return dom.getAttribute ? + dom.getAttribute(key) : + dom[key]; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var TYPE_DELIMITER = '.'; + var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___'; + + /** + * Notice, parseClassType('') should returns {main: '', sub: ''} + * @public + */ + function parseClassType$1(componentType) { + var ret = { + main: '', + sub: '' + }; + if (componentType) { + componentType = componentType.split(TYPE_DELIMITER); + ret.main = componentType[0] || ''; + ret.sub = componentType[1] || ''; + } + return ret; + } + + /** + * @public + */ + function checkClassType(componentType) { + assert$1( + /^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), + 'componentType "' + componentType + '" illegal' + ); + } + + /** + * @public + */ + function enableClassExtend(RootClass, mandatoryMethods) { + + RootClass.$constructor = RootClass; + RootClass.extend = function(proto) { + + if (__DEV__) { + each$1(mandatoryMethods, function(method) { + if (!proto[method]) { + console.warn( + 'Method `' + method + '` should be implemented' + + (proto.type ? ' in ' + proto.type : '') + '.' + ); + } + }); + } + + var superClass = this; + var ExtendedClass = function() { + if (!proto.$constructor) { + superClass.apply(this, arguments); + } else { + proto.$constructor.apply(this, arguments); + } + }; + + extend(ExtendedClass.prototype, proto); + + ExtendedClass.extend = this.extend; + ExtendedClass.superCall = superCall; + ExtendedClass.superApply = superApply; + inherits(ExtendedClass, this); + ExtendedClass.superClass = superClass; + + return ExtendedClass; + }; + } + + var classBase = 0; + + /** + * Can not use instanceof, consider different scope by + * cross domain or es module import in ec extensions. + * Mount a method "isInstance()" to Clz. + */ + function enableClassCheck(Clz) { + var classAttr = ['__\0is_clz', classBase++, Math.random().toFixed(3)].join('_'); + Clz.prototype[classAttr] = true; + + if (__DEV__) { + assert$1(!Clz.isInstance, 'The method "is" can not be defined.'); + } + + Clz.isInstance = function(obj) { + return !!(obj && obj[classAttr]); + }; + } + + // superCall should have class info, which can not be fetch from 'this'. + // Consider this case: + // class A has method f, + // class B inherits class A, overrides method f, f call superApply('f'), + // class C inherits class B, do not overrides method f, + // then when method of class C is called, dead loop occured. + function superCall(context, methodName) { + var args = slice(arguments, 2); + return this.superClass.prototype[methodName].apply(context, args); + } + + function superApply(context, methodName, args) { + return this.superClass.prototype[methodName].apply(context, args); + } + + /** + * @param {Object} entity + * @param {Object} options + * @param {boolean} [options.registerWhenExtend] + * @public + */ + function enableClassManagement(entity, options) { + options = options || {}; + + /** + * Component model classes + * key: componentType, + * value: + * componentClass, when componentType is 'xxx' + * or Object., when componentType is 'xxx.yy' + * @type {Object} + */ + var storage = {}; + + entity.registerClass = function(Clazz, componentType) { + if (componentType) { + checkClassType(componentType); + componentType = parseClassType$1(componentType); + + if (!componentType.sub) { + if (__DEV__) { + if (storage[componentType.main]) { + console.warn(componentType.main + ' exists.'); + } + } + storage[componentType.main] = Clazz; + } else if (componentType.sub !== IS_CONTAINER) { + var container = makeContainer(componentType); + container[componentType.sub] = Clazz; + } + } + return Clazz; + }; + + entity.getClass = function(componentMainType, subType, throwWhenNotFound) { + var Clazz = storage[componentMainType]; + + if (Clazz && Clazz[IS_CONTAINER]) { + Clazz = subType ? Clazz[subType] : null; + } + + if (throwWhenNotFound && !Clazz) { + throw new Error( + !subType ? + componentMainType + '.' + 'type should be specified.' : + 'Component ' + componentMainType + '.' + (subType || '') + ' not exists. Load it first.' + ); + } + + return Clazz; + }; + + entity.getClassesByMainType = function(componentType) { + componentType = parseClassType$1(componentType); + + var result = []; + var obj = storage[componentType.main]; + + if (obj && obj[IS_CONTAINER]) { + each$1(obj, function(o, type) { + type !== IS_CONTAINER && result.push(o); + }); + } else { + result.push(obj); + } + + return result; + }; + + entity.hasClass = function(componentType) { + // Just consider componentType.main. + componentType = parseClassType$1(componentType); + return !!storage[componentType.main]; + }; + + /** + * @return {Array.} Like ['aa', 'bb'], but can not be ['aa.xx'] + */ + entity.getAllClassMainTypes = function() { + var types = []; + each$1(storage, function(obj, type) { + types.push(type); + }); + return types; + }; + + /** + * If a main type is container and has sub types + * @param {string} mainType + * @return {boolean} + */ + entity.hasSubTypes = function(componentType) { + componentType = parseClassType$1(componentType); + var obj = storage[componentType.main]; + return obj && obj[IS_CONTAINER]; + }; + + entity.parseClassType = parseClassType$1; + + function makeContainer(componentType) { + var container = storage[componentType.main]; + if (!container || !container[IS_CONTAINER]) { + container = storage[componentType.main] = {}; + container[IS_CONTAINER] = true; + } + return container; + } + + if (options.registerWhenExtend) { + var originalExtend = entity.extend; + if (originalExtend) { + entity.extend = function(proto) { + var ExtendedClass = originalExtend.call(this, proto); + return entity.registerClass(ExtendedClass, proto.type); + }; + } + } + + return entity; + } + + /** + * @param {string|Array.} properties + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO Parse shadow style + // TODO Only shallow path support + var makeStyleMapper = function(properties) { + // Normalize + for (var i = 0; i < properties.length; i++) { + if (!properties[i][1]) { + properties[i][1] = properties[i][0]; + } + } + return function(model, excludes, includes) { + var style = {}; + for (var i = 0; i < properties.length; i++) { + var propName = properties[i][1]; + if ((excludes && indexOf(excludes, propName) >= 0) || + (includes && indexOf(includes, propName) < 0) + ) { + continue; + } + var val = model.getShallow(propName); + if (val != null) { + style[properties[i][0]] = val; + } + } + return style; + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var getLineStyle = makeStyleMapper( + [ + ['lineWidth', 'width'], + ['stroke', 'color'], + ['opacity'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ] + ); + + var lineStyleMixin = { + getLineStyle: function(excludes) { + var style = getLineStyle(this, excludes); + var lineDash = this.getLineDash(style.lineWidth); + lineDash && (style.lineDash = lineDash); + return style; + }, + + getLineDash: function(lineWidth) { + if (lineWidth == null) { + lineWidth = 1; + } + var lineType = this.get('type'); + var dotSize = Math.max(lineWidth, 2); + var dashSize = lineWidth * 4; + return (lineType === 'solid' || lineType == null) ? null : + (lineType === 'dashed' ? [dashSize, dashSize] : [dotSize, dotSize]); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var getAreaStyle = makeStyleMapper( + [ + ['fill', 'color'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['opacity'], + ['shadowColor'] + ] + ); + + var areaStyleMixin = { + getAreaStyle: function(excludes, includes) { + return getAreaStyle(this, excludes, includes); + } + }; + + /** + * 曲线辅助模块 + * @module zrender/core/curve + * @author pissang(https://www.github.com/pissang) + */ + + var mathPow = Math.pow; + var mathSqrt$2 = Math.sqrt; + + var EPSILON$1 = 1e-8; + var EPSILON_NUMERIC = 1e-4; + + var THREE_SQRT = mathSqrt$2(3); + var ONE_THIRD = 1 / 3; + + // 临时变量 + var _v0 = create(); + var _v1 = create(); + var _v2 = create(); + + function isAroundZero(val) { + return val > -EPSILON$1 && val < EPSILON$1; + } + + function isNotAroundZero$1(val) { + return val > EPSILON$1 || val < -EPSILON$1; + } + /** + * 计算三次贝塞尔值 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * @return {number} + */ + function cubicAt(p0, p1, p2, p3, t) { + var onet = 1 - t; + return onet * onet * (onet * p0 + 3 * t * p1) + + t * t * (t * p3 + 3 * onet * p2); + } + + /** + * 计算三次贝塞尔导数值 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * @return {number} + */ + function cubicDerivativeAt(p0, p1, p2, p3, t) { + var onet = 1 - t; + return 3 * ( + ((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet + + (p3 - p2) * t * t + ); + } + + /** + * 计算三次贝塞尔方程根,使用盛金公式 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} val + * @param {Array.} roots + * @return {number} 有效根数目 + */ + function cubicRootAt(p0, p1, p2, p3, val, roots) { + // Evaluate roots of cubic functions + var a = p3 + 3 * (p1 - p2) - p0; + var b = 3 * (p2 - p1 * 2 + p0); + var c = 3 * (p1 - p0); + var d = p0 - val; + + var A = b * b - 3 * a * c; + var B = b * c - 9 * a * d; + var C = c * c - 3 * b * d; + + var n = 0; + + if (isAroundZero(A) && isAroundZero(B)) { + if (isAroundZero(b)) { + roots[0] = 0; + } else { + var t1 = -c / b; //t1, t2, t3, b is not zero + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + } else { + var disc = B * B - 4 * A * C; + + if (isAroundZero(disc)) { + var K = B / A; + var t1 = -b / a + K; // t1, a is not zero + var t2 = -K / 2; // t2, t3 + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + } else if (disc > 0) { + var discSqrt = mathSqrt$2(disc); + var Y1 = A * b + 1.5 * a * (-B + discSqrt); + var Y2 = A * b + 1.5 * a * (-B - discSqrt); + if (Y1 < 0) { + Y1 = -mathPow(-Y1, ONE_THIRD); + } else { + Y1 = mathPow(Y1, ONE_THIRD); + } + if (Y2 < 0) { + Y2 = -mathPow(-Y2, ONE_THIRD); + } else { + Y2 = mathPow(Y2, ONE_THIRD); + } + var t1 = (-b - (Y1 + Y2)) / (3 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } else { + var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt$2(A * A * A)); + var theta = Math.acos(T) / 3; + var ASqrt = mathSqrt$2(A); + var tmp = Math.cos(theta); + + var t1 = (-b - 2 * ASqrt * tmp) / (3 * a); + var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a); + var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + if (t3 >= 0 && t3 <= 1) { + roots[n++] = t3; + } + } + } + return n; + } + + /** + * 计算三次贝塞尔方程极限值的位置 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {Array.} extrema + * @return {number} 有效数目 + */ + function cubicExtrema(p0, p1, p2, p3, extrema) { + var b = 6 * p2 - 12 * p1 + 6 * p0; + var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2; + var c = 3 * p1 - 3 * p0; + + var n = 0; + if (isAroundZero(a)) { + if (isNotAroundZero$1(b)) { + var t1 = -c / b; + if (t1 >= 0 && t1 <= 1) { + extrema[n++] = t1; + } + } + } else { + var disc = b * b - 4 * a * c; + if (isAroundZero(disc)) { + extrema[0] = -b / (2 * a); + } else if (disc > 0) { + var discSqrt = mathSqrt$2(disc); + var t1 = (-b + discSqrt) / (2 * a); + var t2 = (-b - discSqrt) / (2 * a); + if (t1 >= 0 && t1 <= 1) { + extrema[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + extrema[n++] = t2; + } + } + } + return n; + } + + /** + * 细分三次贝塞尔曲线 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * @param {Array.} out + */ + function cubicSubdivide(p0, p1, p2, p3, t, out) { + var p01 = (p1 - p0) * t + p0; + var p12 = (p2 - p1) * t + p1; + var p23 = (p3 - p2) * t + p2; + + var p012 = (p12 - p01) * t + p01; + var p123 = (p23 - p12) * t + p12; + + var p0123 = (p123 - p012) * t + p012; + // Seg0 + out[0] = p0; + out[1] = p01; + out[2] = p012; + out[3] = p0123; + // Seg1 + out[4] = p0123; + out[5] = p123; + out[6] = p23; + out[7] = p3; + } + + /** + * 投射点到三次贝塞尔曲线上,返回投射距离。 + * 投射点有可能会有一个或者多个,这里只返回其中距离最短的一个。 + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x3 + * @param {number} y3 + * @param {number} x + * @param {number} y + * @param {Array.} [out] 投射点 + * @return {number} + */ + function cubicProjectPoint( + x0, y0, x1, y1, x2, y2, x3, y3, + x, y, out + ) { + // http://pomax.github.io/bezierinfo/#projections + var t; + var interval = 0.005; + var d = Infinity; + var prev; + var next; + var d1; + var d2; + + _v0[0] = x; + _v0[1] = y; + + // 先粗略估计一下可能的最小距离的 t 值 + // PENDING + for (var _t = 0; _t < 1; _t += 0.05) { + _v1[0] = cubicAt(x0, x1, x2, x3, _t); + _v1[1] = cubicAt(y0, y1, y2, y3, _t); + d1 = distSquare(_v0, _v1); + if (d1 < d) { + t = _t; + d = d1; + } + } + d = Infinity; + + // At most 32 iteration + for (var i = 0; i < 32; i++) { + if (interval < EPSILON_NUMERIC) { + break; + } + prev = t - interval; + next = t + interval; + // t - interval + _v1[0] = cubicAt(x0, x1, x2, x3, prev); + _v1[1] = cubicAt(y0, y1, y2, y3, prev); + + d1 = distSquare(_v1, _v0); + + if (prev >= 0 && d1 < d) { + t = prev; + d = d1; + } else { + // t + interval + _v2[0] = cubicAt(x0, x1, x2, x3, next); + _v2[1] = cubicAt(y0, y1, y2, y3, next); + d2 = distSquare(_v2, _v0); + + if (next <= 1 && d2 < d) { + t = next; + d = d2; + } else { + interval *= 0.5; + } + } + } + // t + if (out) { + out[0] = cubicAt(x0, x1, x2, x3, t); + out[1] = cubicAt(y0, y1, y2, y3, t); + } + // console.log(interval, i); + return mathSqrt$2(d); + } + + /** + * 计算二次方贝塞尔值 + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} t + * @return {number} + */ + function quadraticAt(p0, p1, p2, t) { + var onet = 1 - t; + return onet * (onet * p0 + 2 * t * p1) + t * t * p2; + } + + /** + * 计算二次方贝塞尔导数值 + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} t + * @return {number} + */ + function quadraticDerivativeAt(p0, p1, p2, t) { + return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1)); + } + + /** + * 计算二次方贝塞尔方程根 + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} t + * @param {Array.} roots + * @return {number} 有效根数目 + */ + function quadraticRootAt(p0, p1, p2, val, roots) { + var a = p0 - 2 * p1 + p2; + var b = 2 * (p1 - p0); + var c = p0 - val; + + var n = 0; + if (isAroundZero(a)) { + if (isNotAroundZero$1(b)) { + var t1 = -c / b; + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + } else { + var disc = b * b - 4 * a * c; + if (isAroundZero(disc)) { + var t1 = -b / (2 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } else if (disc > 0) { + var discSqrt = mathSqrt$2(disc); + var t1 = (-b + discSqrt) / (2 * a); + var t2 = (-b - discSqrt) / (2 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + } + } + return n; + } + + /** + * 计算二次贝塞尔方程极限值 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @return {number} + */ + function quadraticExtremum(p0, p1, p2) { + var divider = p0 + p2 - 2 * p1; + if (divider === 0) { + // p1 is center of p0 and p2 + return 0.5; + } else { + return (p0 - p1) / divider; + } + } + + /** + * 细分二次贝塞尔曲线 + * @memberOf module:zrender/core/curve + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} t + * @param {Array.} out + */ + function quadraticSubdivide(p0, p1, p2, t, out) { + var p01 = (p1 - p0) * t + p0; + var p12 = (p2 - p1) * t + p1; + var p012 = (p12 - p01) * t + p01; + + // Seg0 + out[0] = p0; + out[1] = p01; + out[2] = p012; + + // Seg1 + out[3] = p012; + out[4] = p12; + out[5] = p2; + } + + /** + * 投射点到二次贝塞尔曲线上,返回投射距离。 + * 投射点有可能会有一个或者多个,这里只返回其中距离最短的一个。 + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x + * @param {number} y + * @param {Array.} out 投射点 + * @return {number} + */ + function quadraticProjectPoint( + x0, y0, x1, y1, x2, y2, + x, y, out + ) { + // http://pomax.github.io/bezierinfo/#projections + var t; + var interval = 0.005; + var d = Infinity; + + _v0[0] = x; + _v0[1] = y; + + // 先粗略估计一下可能的最小距离的 t 值 + // PENDING + for (var _t = 0; _t < 1; _t += 0.05) { + _v1[0] = quadraticAt(x0, x1, x2, _t); + _v1[1] = quadraticAt(y0, y1, y2, _t); + var d1 = distSquare(_v0, _v1); + if (d1 < d) { + t = _t; + d = d1; + } + } + d = Infinity; + + // At most 32 iteration + for (var i = 0; i < 32; i++) { + if (interval < EPSILON_NUMERIC) { + break; + } + var prev = t - interval; + var next = t + interval; + // t - interval + _v1[0] = quadraticAt(x0, x1, x2, prev); + _v1[1] = quadraticAt(y0, y1, y2, prev); + + var d1 = distSquare(_v1, _v0); + + if (prev >= 0 && d1 < d) { + t = prev; + d = d1; + } else { + // t + interval + _v2[0] = quadraticAt(x0, x1, x2, next); + _v2[1] = quadraticAt(y0, y1, y2, next); + var d2 = distSquare(_v2, _v0); + if (next <= 1 && d2 < d) { + t = next; + d = d2; + } else { + interval *= 0.5; + } + } + } + // t + if (out) { + out[0] = quadraticAt(x0, x1, x2, t); + out[1] = quadraticAt(y0, y1, y2, t); + } + // console.log(interval, i); + return mathSqrt$2(d); + } + + /** + * @author Yi Shen(https://github.com/pissang) + */ + + var mathMin$3 = Math.min; + var mathMax$3 = Math.max; + var mathSin$2 = Math.sin; + var mathCos$2 = Math.cos; + var PI2 = Math.PI * 2; + + var start = create(); + var end = create(); + var extremity = create(); + + /** + * 从顶点数组中计算出最小包围盒,写入`min`和`max`中 + * @module zrender/core/bbox + * @param {Array} points 顶点数组 + * @param {number} min + * @param {number} max + */ + function fromPoints(points, min$$1, max$$1) { + if (points.length === 0) { + return; + } + var p = points[0]; + var left = p[0]; + var right = p[0]; + var top = p[1]; + var bottom = p[1]; + var i; + + for (i = 1; i < points.length; i++) { + p = points[i]; + left = mathMin$3(left, p[0]); + right = mathMax$3(right, p[0]); + top = mathMin$3(top, p[1]); + bottom = mathMax$3(bottom, p[1]); + } + + min$$1[0] = left; + min$$1[1] = top; + max$$1[0] = right; + max$$1[1] = bottom; + } + + /** + * @memberOf module:zrender/core/bbox + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {Array.} min + * @param {Array.} max + */ + function fromLine(x0, y0, x1, y1, min$$1, max$$1) { + min$$1[0] = mathMin$3(x0, x1); + min$$1[1] = mathMin$3(y0, y1); + max$$1[0] = mathMax$3(x0, x1); + max$$1[1] = mathMax$3(y0, y1); + } + + var xDim = []; + var yDim = []; + /** + * 从三阶贝塞尔曲线(p0, p1, p2, p3)中计算出最小包围盒,写入`min`和`max`中 + * @memberOf module:zrender/core/bbox + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x3 + * @param {number} y3 + * @param {Array.} min + * @param {Array.} max + */ + function fromCubic( + x0, y0, x1, y1, x2, y2, x3, y3, min$$1, max$$1 + ) { + var cubicExtrema$$1 = cubicExtrema; + var cubicAt$$1 = cubicAt; + var i; + var n = cubicExtrema$$1(x0, x1, x2, x3, xDim); + min$$1[0] = Infinity; + min$$1[1] = Infinity; + max$$1[0] = -Infinity; + max$$1[1] = -Infinity; + + for (i = 0; i < n; i++) { + var x = cubicAt$$1(x0, x1, x2, x3, xDim[i]); + min$$1[0] = mathMin$3(x, min$$1[0]); + max$$1[0] = mathMax$3(x, max$$1[0]); + } + n = cubicExtrema$$1(y0, y1, y2, y3, yDim); + for (i = 0; i < n; i++) { + var y = cubicAt$$1(y0, y1, y2, y3, yDim[i]); + min$$1[1] = mathMin$3(y, min$$1[1]); + max$$1[1] = mathMax$3(y, max$$1[1]); + } + + min$$1[0] = mathMin$3(x0, min$$1[0]); + max$$1[0] = mathMax$3(x0, max$$1[0]); + min$$1[0] = mathMin$3(x3, min$$1[0]); + max$$1[0] = mathMax$3(x3, max$$1[0]); + + min$$1[1] = mathMin$3(y0, min$$1[1]); + max$$1[1] = mathMax$3(y0, max$$1[1]); + min$$1[1] = mathMin$3(y3, min$$1[1]); + max$$1[1] = mathMax$3(y3, max$$1[1]); + } + + /** + * 从二阶贝塞尔曲线(p0, p1, p2)中计算出最小包围盒,写入`min`和`max`中 + * @memberOf module:zrender/core/bbox + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {Array.} min + * @param {Array.} max + */ + function fromQuadratic(x0, y0, x1, y1, x2, y2, min$$1, max$$1) { + var quadraticExtremum$$1 = quadraticExtremum; + var quadraticAt$$1 = quadraticAt; + // Find extremities, where derivative in x dim or y dim is zero + var tx = + mathMax$3( + mathMin$3(quadraticExtremum$$1(x0, x1, x2), 1), 0 + ); + var ty = + mathMax$3( + mathMin$3(quadraticExtremum$$1(y0, y1, y2), 1), 0 + ); + + var x = quadraticAt$$1(x0, x1, x2, tx); + var y = quadraticAt$$1(y0, y1, y2, ty); + + min$$1[0] = mathMin$3(x0, x2, x); + min$$1[1] = mathMin$3(y0, y2, y); + max$$1[0] = mathMax$3(x0, x2, x); + max$$1[1] = mathMax$3(y0, y2, y); + } + + /** + * 从圆弧中计算出最小包围盒,写入`min`和`max`中 + * @method + * @memberOf module:zrender/core/bbox + * @param {number} x + * @param {number} y + * @param {number} rx + * @param {number} ry + * @param {number} startAngle + * @param {number} endAngle + * @param {number} anticlockwise + * @param {Array.} min + * @param {Array.} max + */ + function fromArc( + x, y, rx, ry, startAngle, endAngle, anticlockwise, min$$1, max$$1 + ) { + var vec2Min = min; + var vec2Max = max; + + var diff = Math.abs(startAngle - endAngle); + + + if (diff % PI2 < 1e-4 && diff > 1e-4) { + // Is a circle + min$$1[0] = x - rx; + min$$1[1] = y - ry; + max$$1[0] = x + rx; + max$$1[1] = y + ry; + return; + } + + start[0] = mathCos$2(startAngle) * rx + x; + start[1] = mathSin$2(startAngle) * ry + y; + + end[0] = mathCos$2(endAngle) * rx + x; + end[1] = mathSin$2(endAngle) * ry + y; + + vec2Min(min$$1, start, end); + vec2Max(max$$1, start, end); + + // Thresh to [0, Math.PI * 2] + startAngle = startAngle % (PI2); + if (startAngle < 0) { + startAngle = startAngle + PI2; + } + endAngle = endAngle % (PI2); + if (endAngle < 0) { + endAngle = endAngle + PI2; + } + + if (startAngle > endAngle && !anticlockwise) { + endAngle += PI2; + } else if (startAngle < endAngle && anticlockwise) { + startAngle += PI2; + } + if (anticlockwise) { + var tmp = endAngle; + endAngle = startAngle; + startAngle = tmp; + } + + // var number = 0; + // var step = (anticlockwise ? -Math.PI : Math.PI) / 2; + for (var angle = 0; angle < endAngle; angle += Math.PI / 2) { + if (angle > startAngle) { + extremity[0] = mathCos$2(angle) * rx + x; + extremity[1] = mathSin$2(angle) * ry + y; + + vec2Min(min$$1, extremity, min$$1); + vec2Max(max$$1, extremity, max$$1); + } + } + } + + /** + * Path 代理,可以在`buildPath`中用于替代`ctx`, 会保存每个path操作的命令到pathCommands属性中 + * 可以用于 isInsidePath 判断以及获取boundingRect + * + * @module zrender/core/PathProxy + * @author Yi Shen (http://www.github.com/pissang) + */ + + // TODO getTotalLength, getPointAtLength + + var CMD = { + M: 1, + L: 2, + C: 3, + Q: 4, + A: 5, + Z: 6, + // Rect + R: 7 + }; + + // var CMD_MEM_SIZE = { + // M: 3, + // L: 3, + // C: 7, + // Q: 5, + // A: 9, + // R: 5, + // Z: 1 + // }; + + var min$1 = []; + var max$1 = []; + var min2 = []; + var max2 = []; + var mathMin$2 = Math.min; + var mathMax$2 = Math.max; + var mathCos$1 = Math.cos; + var mathSin$1 = Math.sin; + var mathSqrt$1 = Math.sqrt; + var mathAbs = Math.abs; + + var hasTypedArray = typeof Float32Array != 'undefined'; + + /** + * @alias module:zrender/core/PathProxy + * @constructor + */ + var PathProxy = function(notSaveData) { + + this._saveData = !(notSaveData || false); + + if (this._saveData) { + /** + * Path data. Stored as flat array + * @type {Array.} + */ + this.data = []; + } + + this._ctx = null; + }; + + /** + * 快速计算Path包围盒(并不是最小包围盒) + * @return {Object} + */ + PathProxy.prototype = { + + constructor: PathProxy, + + _xi: 0, + _yi: 0, + + _x0: 0, + _y0: 0, + // Unit x, Unit y. Provide for avoiding drawing that too short line segment + _ux: 0, + _uy: 0, + + _len: 0, + + _lineDash: null, + + _dashOffset: 0, + + _dashIdx: 0, + + _dashSum: 0, + + /** + * @readOnly + */ + setScale: function(sx, sy) { + this._ux = mathAbs(1 / devicePixelRatio / sx) || 0; + this._uy = mathAbs(1 / devicePixelRatio / sy) || 0; + }, + + getContext: function() { + return this._ctx; + }, + + /** + * @param {CanvasRenderingContext2D} ctx + * @return {module:zrender/core/PathProxy} + */ + beginPath: function(ctx) { + + this._ctx = ctx; + + ctx && ctx.beginPath(); + + ctx && (this.dpr = ctx.dpr); + + // Reset + if (this._saveData) { + this._len = 0; + } + + if (this._lineDash) { + this._lineDash = null; + + this._dashOffset = 0; + } + + return this; + }, + + /** + * @param {number} x + * @param {number} y + * @return {module:zrender/core/PathProxy} + */ + moveTo: function(x, y) { + this.addData(CMD.M, x, y); + this._ctx && this._ctx.moveTo(x, y); + + // x0, y0, xi, yi 是记录在 _dashedXXXXTo 方法中使用 + // xi, yi 记录当前点, x0, y0 在 closePath 的时候回到起始点。 + // 有可能在 beginPath 之后直接调用 lineTo,这时候 x0, y0 需要 + // 在 lineTo 方法中记录,这里先不考虑这种情况,dashed line 也只在 IE10- 中不支持 + this._x0 = x; + this._y0 = y; + + this._xi = x; + this._yi = y; + + return this; + }, + + /** + * @param {number} x + * @param {number} y + * @return {module:zrender/core/PathProxy} + */ + lineTo: function(x, y) { + var exceedUnit = mathAbs(x - this._xi) > this._ux || + mathAbs(y - this._yi) > this._uy + // Force draw the first segment + || + this._len < 5; + + this.addData(CMD.L, x, y); + + if (this._ctx && exceedUnit) { + this._needsDash() ? this._dashedLineTo(x, y) : + this._ctx.lineTo(x, y); + } + if (exceedUnit) { + this._xi = x; + this._yi = y; + } + + return this; + }, + + /** + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x3 + * @param {number} y3 + * @return {module:zrender/core/PathProxy} + */ + bezierCurveTo: function(x1, y1, x2, y2, x3, y3) { + this.addData(CMD.C, x1, y1, x2, y2, x3, y3); + if (this._ctx) { + this._needsDash() ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3) : + this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); + } + this._xi = x3; + this._yi = y3; + return this; + }, + + /** + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @return {module:zrender/core/PathProxy} + */ + quadraticCurveTo: function(x1, y1, x2, y2) { + this.addData(CMD.Q, x1, y1, x2, y2); + if (this._ctx) { + this._needsDash() ? this._dashedQuadraticTo(x1, y1, x2, y2) : + this._ctx.quadraticCurveTo(x1, y1, x2, y2); + } + this._xi = x2; + this._yi = y2; + return this; + }, + + /** + * @param {number} cx + * @param {number} cy + * @param {number} r + * @param {number} startAngle + * @param {number} endAngle + * @param {boolean} anticlockwise + * @return {module:zrender/core/PathProxy} + */ + arc: function(cx, cy, r, startAngle, endAngle, anticlockwise) { + this.addData( + CMD.A, cx, cy, r, r, startAngle, endAngle - startAngle, 0, anticlockwise ? 0 : 1 + ); + this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise); + + this._xi = mathCos$1(endAngle) * r + cx; + this._yi = mathSin$1(endAngle) * r + cx; + return this; + }, + + // TODO + arcTo: function(x1, y1, x2, y2, radius) { + if (this._ctx) { + this._ctx.arcTo(x1, y1, x2, y2, radius); + } + return this; + }, + + // TODO + rect: function(x, y, w, h) { + this._ctx && this._ctx.rect(x, y, w, h); + this.addData(CMD.R, x, y, w, h); + return this; + }, + + /** + * @return {module:zrender/core/PathProxy} + */ + closePath: function() { + this.addData(CMD.Z); + + var ctx = this._ctx; + var x0 = this._x0; + var y0 = this._y0; + if (ctx) { + this._needsDash() && this._dashedLineTo(x0, y0); + ctx.closePath(); + } + + this._xi = x0; + this._yi = y0; + return this; + }, + + /** + * Context 从外部传入,因为有可能是 rebuildPath 完之后再 fill。 + * stroke 同样 + * @param {CanvasRenderingContext2D} ctx + * @return {module:zrender/core/PathProxy} + */ + fill: function(ctx) { + ctx && ctx.fill(); + this.toStatic(); + }, + + /** + * @param {CanvasRenderingContext2D} ctx + * @return {module:zrender/core/PathProxy} + */ + stroke: function(ctx) { + ctx && ctx.stroke(); + this.toStatic(); + }, + + /** + * 必须在其它绘制命令前调用 + * Must be invoked before all other path drawing methods + * @return {module:zrender/core/PathProxy} + */ + setLineDash: function(lineDash) { + if (lineDash instanceof Array) { + this._lineDash = lineDash; + + this._dashIdx = 0; + + var lineDashSum = 0; + for (var i = 0; i < lineDash.length; i++) { + lineDashSum += lineDash[i]; + } + this._dashSum = lineDashSum; + } + return this; + }, + + /** + * 必须在其它绘制命令前调用 + * Must be invoked before all other path drawing methods + * @return {module:zrender/core/PathProxy} + */ + setLineDashOffset: function(offset) { + this._dashOffset = offset; + return this; + }, + + /** + * + * @return {boolean} + */ + len: function() { + return this._len; + }, + + /** + * 直接设置 Path 数据 + */ + setData: function(data) { + + var len$$1 = data.length; + + if (!(this.data && this.data.length == len$$1) && hasTypedArray) { + this.data = new Float32Array(len$$1); + } + + for (var i = 0; i < len$$1; i++) { + this.data[i] = data[i]; + } + + this._len = len$$1; + }, + + /** + * 添加子路径 + * @param {module:zrender/core/PathProxy|Array.} path + */ + appendPath: function(path) { + if (!(path instanceof Array)) { + path = [path]; + } + var len$$1 = path.length; + var appendSize = 0; + var offset = this._len; + for (var i = 0; i < len$$1; i++) { + appendSize += path[i].len(); + } + if (hasTypedArray && (this.data instanceof Float32Array)) { + this.data = new Float32Array(offset + appendSize); + } + for (var i = 0; i < len$$1; i++) { + var appendPathData = path[i].data; + for (var k = 0; k < appendPathData.length; k++) { + this.data[offset++] = appendPathData[k]; + } + } + this._len = offset; + }, + + /** + * 填充 Path 数据。 + * 尽量复用而不申明新的数组。大部分图形重绘的指令数据长度都是不变的。 + */ + addData: function(cmd) { + if (!this._saveData) { + return; + } + + var data = this.data; + if (this._len + arguments.length > data.length) { + // 因为之前的数组已经转换成静态的 Float32Array + // 所以不够用时需要扩展一个新的动态数组 + this._expandData(); + data = this.data; + } + for (var i = 0; i < arguments.length; i++) { + data[this._len++] = arguments[i]; + } + + this._prevCmd = cmd; + }, + + _expandData: function() { + // Only if data is Float32Array + if (!(this.data instanceof Array)) { + var newData = []; + for (var i = 0; i < this._len; i++) { + newData[i] = this.data[i]; + } + this.data = newData; + } + }, + + /** + * If needs js implemented dashed line + * @return {boolean} + * @private + */ + _needsDash: function() { + return this._lineDash; + }, + + _dashedLineTo: function(x1, y1) { + var dashSum = this._dashSum; + var offset = this._dashOffset; + var lineDash = this._lineDash; + var ctx = this._ctx; + + var x0 = this._xi; + var y0 = this._yi; + var dx = x1 - x0; + var dy = y1 - y0; + var dist$$1 = mathSqrt$1(dx * dx + dy * dy); + var x = x0; + var y = y0; + var dash; + var nDash = lineDash.length; + var idx; + dx /= dist$$1; + dy /= dist$$1; + + if (offset < 0) { + // Convert to positive offset + offset = dashSum + offset; + } + offset %= dashSum; + x -= offset * dx; + y -= offset * dy; + + while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1) || + (dx == 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) { + idx = this._dashIdx; + dash = lineDash[idx]; + x += dx * dash; + y += dy * dash; + this._dashIdx = (idx + 1) % nDash; + // Skip positive offset + if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) { + continue; + } + ctx[idx % 2 ? 'moveTo' : 'lineTo']( + dx >= 0 ? mathMin$2(x, x1) : mathMax$2(x, x1), + dy >= 0 ? mathMin$2(y, y1) : mathMax$2(y, y1) + ); + } + // Offset for next lineTo + dx = x - x1; + dy = y - y1; + this._dashOffset = -mathSqrt$1(dx * dx + dy * dy); + }, + + // Not accurate dashed line to + _dashedBezierTo: function(x1, y1, x2, y2, x3, y3) { + var dashSum = this._dashSum; + var offset = this._dashOffset; + var lineDash = this._lineDash; + var ctx = this._ctx; + + var x0 = this._xi; + var y0 = this._yi; + var t; + var dx; + var dy; + var cubicAt$$1 = cubicAt; + var bezierLen = 0; + var idx = this._dashIdx; + var nDash = lineDash.length; + + var x; + var y; + + var tmpLen = 0; + + if (offset < 0) { + // Convert to positive offset + offset = dashSum + offset; + } + offset %= dashSum; + // Bezier approx length + for (t = 0; t < 1; t += 0.1) { + dx = cubicAt$$1(x0, x1, x2, x3, t + 0.1) - + cubicAt$$1(x0, x1, x2, x3, t); + dy = cubicAt$$1(y0, y1, y2, y3, t + 0.1) - + cubicAt$$1(y0, y1, y2, y3, t); + bezierLen += mathSqrt$1(dx * dx + dy * dy); + } + + // Find idx after add offset + for (; idx < nDash; idx++) { + tmpLen += lineDash[idx]; + if (tmpLen > offset) { + break; + } + } + t = (tmpLen - offset) / bezierLen; + + while (t <= 1) { + + x = cubicAt$$1(x0, x1, x2, x3, t); + y = cubicAt$$1(y0, y1, y2, y3, t); + + // Use line to approximate dashed bezier + // Bad result if dash is long + idx % 2 ? ctx.moveTo(x, y) : + ctx.lineTo(x, y); + + t += lineDash[idx] / bezierLen; + + idx = (idx + 1) % nDash; + } + + // Finish the last segment and calculate the new offset + (idx % 2 !== 0) && ctx.lineTo(x3, y3); + dx = x3 - x; + dy = y3 - y; + this._dashOffset = -mathSqrt$1(dx * dx + dy * dy); + }, + + _dashedQuadraticTo: function(x1, y1, x2, y2) { + // Convert quadratic to cubic using degree elevation + var x3 = x2; + var y3 = y2; + x2 = (x2 + 2 * x1) / 3; + y2 = (y2 + 2 * y1) / 3; + x1 = (this._xi + 2 * x1) / 3; + y1 = (this._yi + 2 * y1) / 3; + + this._dashedBezierTo(x1, y1, x2, y2, x3, y3); + }, + + /** + * 转成静态的 Float32Array 减少堆内存占用 + * Convert dynamic array to static Float32Array + */ + toStatic: function() { + var data = this.data; + if (data instanceof Array) { + data.length = this._len; + if (hasTypedArray) { + this.data = new Float32Array(data); + } + } + }, + + /** + * @return {module:zrender/core/BoundingRect} + */ + getBoundingRect: function() { + min$1[0] = min$1[1] = min2[0] = min2[1] = Number.MAX_VALUE; + max$1[0] = max$1[1] = max2[0] = max2[1] = -Number.MAX_VALUE; + + var data = this.data; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + + for (var i = 0; i < data.length;) { + var cmd = data[i++]; + + if (i == 1) { + // 如果第一个命令是 L, C, Q + // 则 previous point 同绘制命令的第一个 point + // + // 第一个命令为 Arc 的情况下会在后面特殊处理 + xi = data[i]; + yi = data[i + 1]; + + x0 = xi; + y0 = yi; + } + + switch (cmd) { + case CMD.M: + // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点 + // 在 closePath 的时候使用 + x0 = data[i++]; + y0 = data[i++]; + xi = x0; + yi = y0; + min2[0] = x0; + min2[1] = y0; + max2[0] = x0; + max2[1] = y0; + break; + case CMD.L: + fromLine(xi, yi, data[i], data[i + 1], min2, max2); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.C: + fromCubic( + xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], + min2, max2 + ); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.Q: + fromQuadratic( + xi, yi, data[i++], data[i++], data[i], data[i + 1], + min2, max2 + ); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.A: + // TODO Arc 判断的开销比较大 + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var startAngle = data[i++]; + var endAngle = data[i++] + startAngle; + // TODO Arc 旋转 + var psi = data[i++]; + var anticlockwise = 1 - data[i++]; + + if (i == 1) { + // 直接使用 arc 命令 + // 第一个命令起点还未定义 + x0 = mathCos$1(startAngle) * rx + cx; + y0 = mathSin$1(startAngle) * ry + cy; + } + + fromArc( + cx, cy, rx, ry, startAngle, endAngle, + anticlockwise, min2, max2 + ); + + xi = mathCos$1(endAngle) * rx + cx; + yi = mathSin$1(endAngle) * ry + cy; + break; + case CMD.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + // Use fromLine + fromLine(x0, y0, x0 + width, y0 + height, min2, max2); + break; + case CMD.Z: + xi = x0; + yi = y0; + break; + } + + // Union + min(min$1, min$1, min2); + max(max$1, max$1, max2); + } + + // No data + if (i === 0) { + min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0; + } + + return new BoundingRect( + min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1] + ); + }, + + /** + * Rebuild path from current data + * Rebuild path will not consider javascript implemented line dash. + * @param {CanvasRenderingContext2D} ctx + */ + rebuildPath: function(ctx) { + var d = this.data; + var x0, y0; + var xi, yi; + var x, y; + var ux = this._ux; + var uy = this._uy; + var len$$1 = this._len; + for (var i = 0; i < len$$1;) { + var cmd = d[i++]; + + if (i == 1) { + // 如果第一个命令是 L, C, Q + // 则 previous point 同绘制命令的第一个 point + // + // 第一个命令为 Arc 的情况下会在后面特殊处理 + xi = d[i]; + yi = d[i + 1]; + + x0 = xi; + y0 = yi; + } + switch (cmd) { + case CMD.M: + x0 = xi = d[i++]; + y0 = yi = d[i++]; + ctx.moveTo(xi, yi); + break; + case CMD.L: + x = d[i++]; + y = d[i++]; + // Not draw too small seg between + if (mathAbs(x - xi) > ux || mathAbs(y - yi) > uy || i === len$$1 - 1) { + ctx.lineTo(x, y); + xi = x; + yi = y; + } + break; + case CMD.C: + ctx.bezierCurveTo( + d[i++], d[i++], d[i++], d[i++], d[i++], d[i++] + ); + xi = d[i - 2]; + yi = d[i - 1]; + break; + case CMD.Q: + ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]); + xi = d[i - 2]; + yi = d[i - 1]; + break; + case CMD.A: + var cx = d[i++]; + var cy = d[i++]; + var rx = d[i++]; + var ry = d[i++]; + var theta = d[i++]; + var dTheta = d[i++]; + var psi = d[i++]; + var fs = d[i++]; + var r = (rx > ry) ? rx : ry; + var scaleX = (rx > ry) ? 1 : rx / ry; + var scaleY = (rx > ry) ? ry / rx : 1; + var isEllipse = Math.abs(rx - ry) > 1e-3; + var endAngle = theta + dTheta; + if (isEllipse) { + ctx.translate(cx, cy); + ctx.rotate(psi); + ctx.scale(scaleX, scaleY); + ctx.arc(0, 0, r, theta, endAngle, 1 - fs); + ctx.scale(1 / scaleX, 1 / scaleY); + ctx.rotate(-psi); + ctx.translate(-cx, -cy); + } else { + ctx.arc(cx, cy, r, theta, endAngle, 1 - fs); + } + + if (i == 1) { + // 直接使用 arc 命令 + // 第一个命令起点还未定义 + x0 = mathCos$1(theta) * rx + cx; + y0 = mathSin$1(theta) * ry + cy; + } + xi = mathCos$1(endAngle) * rx + cx; + yi = mathSin$1(endAngle) * ry + cy; + break; + case CMD.R: + x0 = xi = d[i]; + y0 = yi = d[i + 1]; + ctx.rect(d[i++], d[i++], d[i++], d[i++]); + break; + case CMD.Z: + ctx.closePath(); + xi = x0; + yi = y0; + } + } + } + }; + + PathProxy.CMD = CMD; + + /** + * 线段包含判断 + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} lineWidth + * @param {number} x + * @param {number} y + * @return {boolean} + */ + function containStroke$1(x0, y0, x1, y1, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + var _a = 0; + var _b = x0; + // Quick reject + if ( + (y > y0 + _l && y > y1 + _l) || + (y < y0 - _l && y < y1 - _l) || + (x > x0 + _l && x > x1 + _l) || + (x < x0 - _l && x < x1 - _l) + ) { + return false; + } + + if (x0 !== x1) { + _a = (y0 - y1) / (x0 - x1); + _b = (x0 * y1 - x1 * y0) / (x0 - x1); + } else { + return Math.abs(x - x0) <= _l / 2; + } + var tmp = _a * x - y + _b; + var _s = tmp * tmp / (_a * _a + 1); + return _s <= _l / 2 * _l / 2; + } + + /** + * 三次贝塞尔曲线描边包含判断 + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x3 + * @param {number} y3 + * @param {number} lineWidth + * @param {number} x + * @param {number} y + * @return {boolean} + */ + function containStroke$2(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + // Quick reject + if ( + (y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l) || + (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l) || + (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l) || + (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l) + ) { + return false; + } + var d = cubicProjectPoint( + x0, y0, x1, y1, x2, y2, x3, y3, + x, y, null + ); + return d <= _l / 2; + } + + /** + * 二次贝塞尔曲线描边包含判断 + * @param {number} x0 + * @param {number} y0 + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} lineWidth + * @param {number} x + * @param {number} y + * @return {boolean} + */ + function containStroke$3(x0, y0, x1, y1, x2, y2, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + // Quick reject + if ( + (y > y0 + _l && y > y1 + _l && y > y2 + _l) || + (y < y0 - _l && y < y1 - _l && y < y2 - _l) || + (x > x0 + _l && x > x1 + _l && x > x2 + _l) || + (x < x0 - _l && x < x1 - _l && x < x2 - _l) + ) { + return false; + } + var d = quadraticProjectPoint( + x0, y0, x1, y1, x2, y2, + x, y, null + ); + return d <= _l / 2; + } + + var PI2$3 = Math.PI * 2; + + function normalizeRadian(angle) { + angle %= PI2$3; + if (angle < 0) { + angle += PI2$3; + } + return angle; + } + + var PI2$2 = Math.PI * 2; + + /** + * 圆弧描边包含判断 + * @param {number} cx + * @param {number} cy + * @param {number} r + * @param {number} startAngle + * @param {number} endAngle + * @param {boolean} anticlockwise + * @param {number} lineWidth + * @param {number} x + * @param {number} y + * @return {Boolean} + */ + function containStroke$4( + cx, cy, r, startAngle, endAngle, anticlockwise, + lineWidth, x, y + ) { + + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + + x -= cx; + y -= cy; + var d = Math.sqrt(x * x + y * y); + + if ((d - _l > r) || (d + _l < r)) { + return false; + } + if (Math.abs(startAngle - endAngle) % PI2$2 < 1e-4) { + // Is a circle + return true; + } + if (anticlockwise) { + var tmp = startAngle; + startAngle = normalizeRadian(endAngle); + endAngle = normalizeRadian(tmp); + } else { + startAngle = normalizeRadian(startAngle); + endAngle = normalizeRadian(endAngle); + } + if (startAngle > endAngle) { + endAngle += PI2$2; + } + + var angle = Math.atan2(y, x); + if (angle < 0) { + angle += PI2$2; + } + return (angle >= startAngle && angle <= endAngle) || + (angle + PI2$2 >= startAngle && angle + PI2$2 <= endAngle); + } + + function windingLine(x0, y0, x1, y1, x, y) { + if ((y > y0 && y > y1) || (y < y0 && y < y1)) { + return 0; + } + // Ignore horizontal line + if (y1 === y0) { + return 0; + } + var dir = y1 < y0 ? 1 : -1; + var t = (y - y0) / (y1 - y0); + + // Avoid winding error when intersection point is the connect point of two line of polygon + if (t === 1 || t === 0) { + dir = y1 < y0 ? 0.5 : -0.5; + } + + var x_ = t * (x1 - x0) + x0; + + // If (x, y) on the line, considered as "contain". + return x_ === x ? Infinity : x_ > x ? dir : 0; + } + + var CMD$1 = PathProxy.CMD; + var PI2$1 = Math.PI * 2; + + var EPSILON$2 = 1e-4; + + function isAroundEqual(a, b) { + return Math.abs(a - b) < EPSILON$2; + } + + // 临时数组 + var roots = [-1, -1, -1]; + var extrema = [-1, -1]; + + function swapExtrema() { + var tmp = extrema[0]; + extrema[0] = extrema[1]; + extrema[1] = tmp; + } + + function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) { + // Quick reject + if ( + (y > y0 && y > y1 && y > y2 && y > y3) || + (y < y0 && y < y1 && y < y2 && y < y3) + ) { + return 0; + } + var nRoots = cubicRootAt(y0, y1, y2, y3, y, roots); + if (nRoots === 0) { + return 0; + } else { + var w = 0; + var nExtrema = -1; + var y0_, y1_; + for (var i = 0; i < nRoots; i++) { + var t = roots[i]; + + // Avoid winding error when intersection point is the connect point of two line of polygon + var unit = (t === 0 || t === 1) ? 0.5 : 1; + + var x_ = cubicAt(x0, x1, x2, x3, t); + if (x_ < x) { // Quick reject + continue; + } + if (nExtrema < 0) { + nExtrema = cubicExtrema(y0, y1, y2, y3, extrema); + if (extrema[1] < extrema[0] && nExtrema > 1) { + swapExtrema(); + } + y0_ = cubicAt(y0, y1, y2, y3, extrema[0]); + if (nExtrema > 1) { + y1_ = cubicAt(y0, y1, y2, y3, extrema[1]); + } + } + if (nExtrema == 2) { + // 分成三段单调函数 + if (t < extrema[0]) { + w += y0_ < y0 ? unit : -unit; + } else if (t < extrema[1]) { + w += y1_ < y0_ ? unit : -unit; + } else { + w += y3 < y1_ ? unit : -unit; + } + } else { + // 分成两段单调函数 + if (t < extrema[0]) { + w += y0_ < y0 ? unit : -unit; + } else { + w += y3 < y0_ ? unit : -unit; + } + } + } + return w; + } + } + + function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) { + // Quick reject + if ( + (y > y0 && y > y1 && y > y2) || + (y < y0 && y < y1 && y < y2) + ) { + return 0; + } + var nRoots = quadraticRootAt(y0, y1, y2, y, roots); + if (nRoots === 0) { + return 0; + } else { + var t = quadraticExtremum(y0, y1, y2); + if (t >= 0 && t <= 1) { + var w = 0; + var y_ = quadraticAt(y0, y1, y2, t); + for (var i = 0; i < nRoots; i++) { + // Remove one endpoint. + var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1; + + var x_ = quadraticAt(x0, x1, x2, roots[i]); + if (x_ < x) { // Quick reject + continue; + } + if (roots[i] < t) { + w += y_ < y0 ? unit : -unit; + } else { + w += y2 < y_ ? unit : -unit; + } + } + return w; + } else { + // Remove one endpoint. + var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1; + + var x_ = quadraticAt(x0, x1, x2, roots[0]); + if (x_ < x) { // Quick reject + return 0; + } + return y2 < y0 ? unit : -unit; + } + } + } + + // TODO + // Arc 旋转 + function windingArc( + cx, cy, r, startAngle, endAngle, anticlockwise, x, y + ) { + y -= cy; + if (y > r || y < -r) { + return 0; + } + var tmp = Math.sqrt(r * r - y * y); + roots[0] = -tmp; + roots[1] = tmp; + + var diff = Math.abs(startAngle - endAngle); + if (diff < 1e-4) { + return 0; + } + if (diff % PI2$1 < 1e-4) { + // Is a circle + startAngle = 0; + endAngle = PI2$1; + var dir = anticlockwise ? 1 : -1; + if (x >= roots[0] + cx && x <= roots[1] + cx) { + return dir; + } else { + return 0; + } + } + + if (anticlockwise) { + var tmp = startAngle; + startAngle = normalizeRadian(endAngle); + endAngle = normalizeRadian(tmp); + } else { + startAngle = normalizeRadian(startAngle); + endAngle = normalizeRadian(endAngle); + } + if (startAngle > endAngle) { + endAngle += PI2$1; + } + + var w = 0; + for (var i = 0; i < 2; i++) { + var x_ = roots[i]; + if (x_ + cx > x) { + var angle = Math.atan2(y, x_); + var dir = anticlockwise ? 1 : -1; + if (angle < 0) { + angle = PI2$1 + angle; + } + if ( + (angle >= startAngle && angle <= endAngle) || + (angle + PI2$1 >= startAngle && angle + PI2$1 <= endAngle) + ) { + if (angle > Math.PI / 2 && angle < Math.PI * 1.5) { + dir = -dir; + } + w += dir; + } + } + } + return w; + } + + function containPath(data, lineWidth, isStroke, x, y) { + var w = 0; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + + for (var i = 0; i < data.length;) { + var cmd = data[i++]; + // Begin a new subpath + if (cmd === CMD$1.M && i > 1) { + // Close previous subpath + if (!isStroke) { + w += windingLine(xi, yi, x0, y0, x, y); + } + // 如果被任何一个 subpath 包含 + // if (w !== 0) { + // return true; + // } + } + + if (i == 1) { + // 如果第一个命令是 L, C, Q + // 则 previous point 同绘制命令的第一个 point + // + // 第一个命令为 Arc 的情况下会在后面特殊处理 + xi = data[i]; + yi = data[i + 1]; + + x0 = xi; + y0 = yi; + } + + switch (cmd) { + case CMD$1.M: + // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点 + // 在 closePath 的时候使用 + x0 = data[i++]; + y0 = data[i++]; + xi = x0; + yi = y0; + break; + case CMD$1.L: + if (isStroke) { + if (containStroke$1(xi, yi, data[i], data[i + 1], lineWidth, x, y)) { + return true; + } + } else { + // NOTE 在第一个命令为 L, C, Q 的时候会计算出 NaN + w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.C: + if (isStroke) { + if (containStroke$2(xi, yi, + data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], + lineWidth, x, y + )) { + return true; + } + } else { + w += windingCubic( + xi, yi, + data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], + x, y + ) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.Q: + if (isStroke) { + if (containStroke$3(xi, yi, + data[i++], data[i++], data[i], data[i + 1], + lineWidth, x, y + )) { + return true; + } + } else { + w += windingQuadratic( + xi, yi, + data[i++], data[i++], data[i], data[i + 1], + x, y + ) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.A: + // TODO Arc 判断的开销比较大 + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var theta = data[i++]; + var dTheta = data[i++]; + // TODO Arc 旋转 + var psi = data[i++]; + var anticlockwise = 1 - data[i++]; + var x1 = Math.cos(theta) * rx + cx; + var y1 = Math.sin(theta) * ry + cy; + // 不是直接使用 arc 命令 + if (i > 1) { + w += windingLine(xi, yi, x1, y1, x, y); + } else { + // 第一个命令起点还未定义 + x0 = x1; + y0 = y1; + } + // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放 + var _x = (x - cx) * ry / rx + cx; + if (isStroke) { + if (containStroke$4( + cx, cy, ry, theta, theta + dTheta, anticlockwise, + lineWidth, _x, y + )) { + return true; + } + } else { + w += windingArc( + cx, cy, ry, theta, theta + dTheta, anticlockwise, + _x, y + ); + } + xi = Math.cos(theta + dTheta) * rx + cx; + yi = Math.sin(theta + dTheta) * ry + cy; + break; + case CMD$1.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + var x1 = x0 + width; + var y1 = y0 + height; + if (isStroke) { + if (containStroke$1(x0, y0, x1, y0, lineWidth, x, y) || + containStroke$1(x1, y0, x1, y1, lineWidth, x, y) || + containStroke$1(x1, y1, x0, y1, lineWidth, x, y) || + containStroke$1(x0, y1, x0, y0, lineWidth, x, y) + ) { + return true; + } + } else { + // FIXME Clockwise ? + w += windingLine(x1, y0, x1, y1, x, y); + w += windingLine(x0, y1, x0, y0, x, y); + } + break; + case CMD$1.Z: + if (isStroke) { + if (containStroke$1( + xi, yi, x0, y0, lineWidth, x, y + )) { + return true; + } + } else { + // Close a subpath + w += windingLine(xi, yi, x0, y0, x, y); + // 如果被任何一个 subpath 包含 + // FIXME subpaths may overlap + // if (w !== 0) { + // return true; + // } + } + xi = x0; + yi = y0; + break; + } + } + if (!isStroke && !isAroundEqual(yi, y0)) { + w += windingLine(xi, yi, x0, y0, x, y) || 0; + } + return w !== 0; + } + + function contain(pathData, x, y) { + return containPath(pathData, 0, false, x, y); + } + + function containStroke(pathData, lineWidth, x, y) { + return containPath(pathData, lineWidth, true, x, y); + } + + var getCanvasPattern = Pattern.prototype.getCanvasPattern; + + var abs = Math.abs; + + var pathProxyForDraw = new PathProxy(true); + /** + * @alias module:zrender/graphic/Path + * @extends module:zrender/graphic/Displayable + * @constructor + * @param {Object} opts + */ + function Path(opts) { + Displayable.call(this, opts); + + /** + * @type {module:zrender/core/PathProxy} + * @readOnly + */ + this.path = null; + } + + Path.prototype = { + + constructor: Path, + + type: 'path', + + __dirtyPath: true, + + strokeContainThreshold: 5, + + brush: function(ctx, prevEl) { + var style = this.style; + var path = this.path || pathProxyForDraw; + var hasStroke = style.hasStroke(); + var hasFill = style.hasFill(); + var fill = style.fill; + var stroke = style.stroke; + var hasFillGradient = hasFill && !!(fill.colorStops); + var hasStrokeGradient = hasStroke && !!(stroke.colorStops); + var hasFillPattern = hasFill && !!(fill.image); + var hasStrokePattern = hasStroke && !!(stroke.image); + + style.bind(ctx, this, prevEl); + this.setTransform(ctx); + + if (this.__dirty) { + var rect; + // Update gradient because bounding rect may changed + if (hasFillGradient) { + rect = rect || this.getBoundingRect(); + this._fillGradient = style.getGradient(ctx, fill, rect); + } + if (hasStrokeGradient) { + rect = rect || this.getBoundingRect(); + this._strokeGradient = style.getGradient(ctx, stroke, rect); + } + } + // Use the gradient or pattern + if (hasFillGradient) { + // PENDING If may have affect the state + ctx.fillStyle = this._fillGradient; + } else if (hasFillPattern) { + ctx.fillStyle = getCanvasPattern.call(fill, ctx); + } + if (hasStrokeGradient) { + ctx.strokeStyle = this._strokeGradient; + } else if (hasStrokePattern) { + ctx.strokeStyle = getCanvasPattern.call(stroke, ctx); + } + + var lineDash = style.lineDash; + var lineDashOffset = style.lineDashOffset; + + var ctxLineDash = !!ctx.setLineDash; + + // Update path sx, sy + var scale = this.getGlobalScale(); + path.setScale(scale[0], scale[1]); + + // Proxy context + // Rebuild path in following 2 cases + // 1. Path is dirty + // 2. Path needs javascript implemented lineDash stroking. + // In this case, lineDash information will not be saved in PathProxy + if (this.__dirtyPath || + (lineDash && !ctxLineDash && hasStroke) + ) { + path.beginPath(ctx); + + // Setting line dash before build path + if (lineDash && !ctxLineDash) { + path.setLineDash(lineDash); + path.setLineDashOffset(lineDashOffset); + } + + this.buildPath(path, this.shape, false); + + // Clear path dirty flag + if (this.path) { + this.__dirtyPath = false; + } + } else { + // Replay path building + ctx.beginPath(); + this.path.rebuildPath(ctx); + } + + hasFill && path.fill(ctx); + + if (lineDash && ctxLineDash) { + ctx.setLineDash(lineDash); + ctx.lineDashOffset = lineDashOffset; + } + + hasStroke && path.stroke(ctx); + + if (lineDash && ctxLineDash) { + // PENDING + // Remove lineDash + ctx.setLineDash([]); + } + + // Draw rect text + if (style.text != null) { + // Only restore transform when needs draw text. + this.restoreTransform(ctx); + this.drawRectText(ctx, this.getBoundingRect()); + } + }, + + // When bundling path, some shape may decide if use moveTo to begin a new subpath or closePath + // Like in circle + buildPath: function(ctx, shapeCfg, inBundle) {}, + + createPathProxy: function() { + this.path = new PathProxy(); + }, + + getBoundingRect: function() { + var rect = this._rect; + var style = this.style; + var needsUpdateRect = !rect; + if (needsUpdateRect) { + var path = this.path; + if (!path) { + // Create path on demand. + path = this.path = new PathProxy(); + } + if (this.__dirtyPath) { + path.beginPath(); + this.buildPath(path, this.shape, false); + } + rect = path.getBoundingRect(); + } + this._rect = rect; + + if (style.hasStroke()) { + // Needs update rect with stroke lineWidth when + // 1. Element changes scale or lineWidth + // 2. Shape is changed + var rectWithStroke = this._rectWithStroke || (this._rectWithStroke = rect.clone()); + if (this.__dirty || needsUpdateRect) { + rectWithStroke.copy(rect); + // FIXME Must after updateTransform + var w = style.lineWidth; + // PENDING, Min line width is needed when line is horizontal or vertical + var lineScale = style.strokeNoScale ? this.getLineScale() : 1; + + // Only add extra hover lineWidth when there are no fill + if (!style.hasFill()) { + w = Math.max(w, this.strokeContainThreshold || 4); + } + // Consider line width + // Line scale can't be 0; + if (lineScale > 1e-10) { + rectWithStroke.width += w / lineScale; + rectWithStroke.height += w / lineScale; + rectWithStroke.x -= w / lineScale / 2; + rectWithStroke.y -= w / lineScale / 2; + } + } + + // Return rect with stroke + return rectWithStroke; + } + + return rect; + }, + + contain: function(x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + var style = this.style; + x = localPos[0]; + y = localPos[1]; + + if (rect.contain(x, y)) { + var pathData = this.path.data; + if (style.hasStroke()) { + var lineWidth = style.lineWidth; + var lineScale = style.strokeNoScale ? this.getLineScale() : 1; + // Line scale can't be 0; + if (lineScale > 1e-10) { + // Only add extra hover lineWidth when there are no fill + if (!style.hasFill()) { + lineWidth = Math.max(lineWidth, this.strokeContainThreshold); + } + if (containStroke( + pathData, lineWidth / lineScale, x, y + )) { + return true; + } + } + } + if (style.hasFill()) { + return contain(pathData, x, y); + } + } + return false; + }, + + /** + * @param {boolean} dirtyPath + */ + dirty: function(dirtyPath) { + if (dirtyPath == null) { + dirtyPath = true; + } + // Only mark dirty, not mark clean + if (dirtyPath) { + this.__dirtyPath = dirtyPath; + this._rect = null; + } + + this.__dirty = true; + + this.__zr && this.__zr.refresh(); + + // Used as a clipping path + if (this.__clipTarget) { + this.__clipTarget.dirty(); + } + }, + + /** + * Alias for animate('shape') + * @param {boolean} loop + */ + animateShape: function(loop) { + return this.animate('shape', loop); + }, + + // Overwrite attrKV + attrKV: function(key, value) { + // FIXME + if (key === 'shape') { + this.setShape(value); + this.__dirtyPath = true; + this._rect = null; + } else { + Displayable.prototype.attrKV.call(this, key, value); + } + }, + + /** + * @param {Object|string} key + * @param {*} value + */ + setShape: function(key, value) { + var shape = this.shape; + // Path from string may not have shape + if (shape) { + if (isObject$1(key)) { + for (var name in key) { + if (key.hasOwnProperty(name)) { + shape[name] = key[name]; + } + } + } else { + shape[key] = value; + } + this.dirty(true); + } + return this; + }, + + getLineScale: function() { + var m = this.transform; + // Get the line scale. + // Determinant of `m` means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10 ? + Math.sqrt(abs(m[0] * m[3] - m[2] * m[1])) : + 1; + } + }; + + /** + * 扩展一个 Path element, 比如星形,圆等。 + * Extend a path element + * @param {Object} props + * @param {string} props.type Path type + * @param {Function} props.init Initialize + * @param {Function} props.buildPath Overwrite buildPath method + * @param {Object} [props.style] Extended default style config + * @param {Object} [props.shape] Extended default shape config + */ + Path.extend = function(defaults$$1) { + var Sub = function(opts) { + Path.call(this, opts); + + if (defaults$$1.style) { + // Extend default style + this.style.extendFrom(defaults$$1.style, false); + } + + // Extend default shape + var defaultShape = defaults$$1.shape; + if (defaultShape) { + this.shape = this.shape || {}; + var thisShape = this.shape; + for (var name in defaultShape) { + if ( + !thisShape.hasOwnProperty(name) && + defaultShape.hasOwnProperty(name) + ) { + thisShape[name] = defaultShape[name]; + } + } + } + + defaults$$1.init && defaults$$1.init.call(this, opts); + }; + + inherits(Sub, Path); + + // FIXME 不能 extend position, rotation 等引用对象 + for (var name in defaults$$1) { + // Extending prototype values and methods + if (name !== 'style' && name !== 'shape') { + Sub.prototype[name] = defaults$$1[name]; + } + } + + return Sub; + }; + + inherits(Path, Displayable); + + var CMD$2 = PathProxy.CMD; + + var points = [ + [], + [], + [] + ]; + var mathSqrt$3 = Math.sqrt; + var mathAtan2 = Math.atan2; + + var transformPath = function(path, m) { + var data = path.data; + var cmd; + var nPoint; + var i; + var j; + var k; + var p; + + var M = CMD$2.M; + var C = CMD$2.C; + var L = CMD$2.L; + var R = CMD$2.R; + var A = CMD$2.A; + var Q = CMD$2.Q; + + for (i = 0, j = 0; i < data.length;) { + cmd = data[i++]; + j = i; + nPoint = 0; + + switch (cmd) { + case M: + nPoint = 1; + break; + case L: + nPoint = 1; + break; + case C: + nPoint = 3; + break; + case Q: + nPoint = 2; + break; + case A: + var x = m[4]; + var y = m[5]; + var sx = mathSqrt$3(m[0] * m[0] + m[1] * m[1]); + var sy = mathSqrt$3(m[2] * m[2] + m[3] * m[3]); + var angle = mathAtan2(-m[1] / sy, m[0] / sx); + // cx + data[i] *= sx; + data[i++] += x; + // cy + data[i] *= sy; + data[i++] += y; + // Scale rx and ry + // FIXME Assume psi is 0 here + data[i++] *= sx; + data[i++] *= sy; + + // Start angle + data[i++] += angle; + // end angle + data[i++] += angle; + // FIXME psi + i += 2; + j = i; + break; + case R: + // x0, y0 + p[0] = data[i++]; + p[1] = data[i++]; + applyTransform(p, p, m); + data[j++] = p[0]; + data[j++] = p[1]; + // x1, y1 + p[0] += data[i++]; + p[1] += data[i++]; + applyTransform(p, p, m); + data[j++] = p[0]; + data[j++] = p[1]; + } + + for (k = 0; k < nPoint; k++) { + var p = points[k]; + p[0] = data[i++]; + p[1] = data[i++]; + + applyTransform(p, p, m); + // Write back + data[j++] = p[0]; + data[j++] = p[1]; + } + } + }; + + // command chars + var cc = [ + 'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z', + 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A' + ]; + + var mathSqrt = Math.sqrt; + var mathSin = Math.sin; + var mathCos = Math.cos; + var PI = Math.PI; + + var vMag = function(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1]); + }; + var vRatio = function(u, v) { + return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)); + }; + var vAngle = function(u, v) { + return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * + Math.acos(vRatio(u, v)); + }; + + function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) { + var psi = psiDeg * (PI / 180.0); + var xp = mathCos(psi) * (x1 - x2) / 2.0 + + mathSin(psi) * (y1 - y2) / 2.0; + var yp = -1 * mathSin(psi) * (x1 - x2) / 2.0 + + mathCos(psi) * (y1 - y2) / 2.0; + + var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); + + if (lambda > 1) { + rx *= mathSqrt(lambda); + ry *= mathSqrt(lambda); + } + + var f = (fa === fs ? -1 : 1) * + mathSqrt((((rx * rx) * (ry * ry)) - + ((rx * rx) * (yp * yp)) - + ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp) + + (ry * ry) * (xp * xp))) || 0; + + var cxp = f * rx * yp / ry; + var cyp = f * -ry * xp / rx; + + var cx = (x1 + x2) / 2.0 + + mathCos(psi) * cxp - + mathSin(psi) * cyp; + var cy = (y1 + y2) / 2.0 + + mathSin(psi) * cxp + + mathCos(psi) * cyp; + + var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]); + var u = [(xp - cxp) / rx, (yp - cyp) / ry]; + var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; + var dTheta = vAngle(u, v); + + if (vRatio(u, v) <= -1) { + dTheta = PI; + } + if (vRatio(u, v) >= 1) { + dTheta = 0; + } + if (fs === 0 && dTheta > 0) { + dTheta = dTheta - 2 * PI; + } + if (fs === 1 && dTheta < 0) { + dTheta = dTheta + 2 * PI; + } + + path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs); + } + + function createPathProxyFromString(data) { + if (!data) { + return []; + } + + // command string + var cs = data.replace(/-/g, ' -') + .replace(/ /g, ' ') + .replace(/ /g, ',') + .replace(/,,/g, ','); + + var n; + // create pipes so that we can split the data + for (n = 0; n < cc.length; n++) { + cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]); + } + + // create array + var arr = cs.split('|'); + // init context point + var cpx = 0; + var cpy = 0; + + var path = new PathProxy(); + var CMD = PathProxy.CMD; + + var prevCmd; + for (n = 1; n < arr.length; n++) { + var str = arr[n]; + var c = str.charAt(0); + var off = 0; + var p = str.slice(1).replace(/e,-/g, 'e-').split(','); + var cmd; + + if (p.length > 0 && p[0] === '') { + p.shift(); + } + + for (var i = 0; i < p.length; i++) { + p[i] = parseFloat(p[i]); + } + while (off < p.length && !isNaN(p[off])) { + if (isNaN(p[0])) { + break; + } + var ctlPtx; + var ctlPty; + + var rx; + var ry; + var psi; + var fa; + var fs; + + var x1 = cpx; + var y1 = cpy; + + // convert l, H, h, V, and v to L + switch (c) { + case 'l': + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'L': + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'm': + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.M; + path.addData(cmd, cpx, cpy); + c = 'l'; + break; + case 'M': + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.M; + path.addData(cmd, cpx, cpy); + c = 'L'; + break; + case 'h': + cpx += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'H': + cpx = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'v': + cpy += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'V': + cpy = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'C': + cmd = CMD.C; + path.addData( + cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++] + ); + cpx = p[off - 2]; + cpy = p[off - 1]; + break; + case 'c': + cmd = CMD.C; + path.addData( + cmd, + p[off++] + cpx, p[off++] + cpy, + p[off++] + cpx, p[off++] + cpy, + p[off++] + cpx, p[off++] + cpy + ); + cpx += p[off - 2]; + cpy += p[off - 1]; + break; + case 'S': + ctlPtx = cpx; + ctlPty = cpy; + var len = path.len(); + var pathData = path.data; + if (prevCmd === CMD.C) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cmd = CMD.C; + x1 = p[off++]; + y1 = p[off++]; + cpx = p[off++]; + cpy = p[off++]; + path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy); + break; + case 's': + ctlPtx = cpx; + ctlPty = cpy; + var len = path.len(); + var pathData = path.data; + if (prevCmd === CMD.C) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cmd = CMD.C; + x1 = cpx + p[off++]; + y1 = cpy + p[off++]; + cpx += p[off++]; + cpy += p[off++]; + path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy); + break; + case 'Q': + x1 = p[off++]; + y1 = p[off++]; + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.Q; + path.addData(cmd, x1, y1, cpx, cpy); + break; + case 'q': + x1 = p[off++] + cpx; + y1 = p[off++] + cpy; + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.Q; + path.addData(cmd, x1, y1, cpx, cpy); + break; + case 'T': + ctlPtx = cpx; + ctlPty = cpy; + var len = path.len(); + var pathData = path.data; + if (prevCmd === CMD.Q) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.Q; + path.addData(cmd, ctlPtx, ctlPty, cpx, cpy); + break; + case 't': + ctlPtx = cpx; + ctlPty = cpy; + var len = path.len(); + var pathData = path.data; + if (prevCmd === CMD.Q) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.Q; + path.addData(cmd, ctlPtx, ctlPty, cpx, cpy); + break; + case 'A': + rx = p[off++]; + ry = p[off++]; + psi = p[off++]; + fa = p[off++]; + fs = p[off++]; + + x1 = cpx, y1 = cpy; + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.A; + processArc( + x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path + ); + break; + case 'a': + rx = p[off++]; + ry = p[off++]; + psi = p[off++]; + fa = p[off++]; + fs = p[off++]; + + x1 = cpx, y1 = cpy; + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.A; + processArc( + x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path + ); + break; + } + } + + if (c === 'z' || c === 'Z') { + cmd = CMD.Z; + path.addData(cmd); + } + + prevCmd = cmd; + } + + path.toStatic(); + + return path; + } + + // TODO Optimize double memory cost problem + function createPathOptions(str, opts) { + var pathProxy = createPathProxyFromString(str); + opts = opts || {}; + opts.buildPath = function(path) { + if (path.setData) { + path.setData(pathProxy.data); + // Svg and vml renderer don't have context + var ctx = path.getContext(); + if (ctx) { + path.rebuildPath(ctx); + } + } else { + var ctx = path; + pathProxy.rebuildPath(ctx); + } + }; + + opts.applyTransform = function(m) { + transformPath(pathProxy, m); + this.dirty(true); + }; + + return opts; + } + + /** + * Create a Path object from path string data + * http://www.w3.org/TR/SVG/paths.html#PathData + * @param {Object} opts Other options + */ + function createFromString(str, opts) { + return new Path(createPathOptions(str, opts)); + } + + /** + * Create a Path class from path string data + * @param {string} str + * @param {Object} opts Other options + */ + function extendFromString(str, opts) { + return Path.extend(createPathOptions(str, opts)); + } + + /** + * Merge multiple paths + */ + // TODO Apply transform + // TODO stroke dash + // TODO Optimize double memory cost problem + function mergePath$1(pathEls, opts) { + var pathList = []; + var len = pathEls.length; + for (var i = 0; i < len; i++) { + var pathEl = pathEls[i]; + if (!pathEl.path) { + pathEl.createPathProxy(); + } + if (pathEl.__dirtyPath) { + pathEl.buildPath(pathEl.path, pathEl.shape, true); + } + pathList.push(pathEl.path); + } + + var pathBundle = new Path(opts); + // Need path proxy. + pathBundle.createPathProxy(); + pathBundle.buildPath = function(path) { + path.appendPath(pathList); + // Svg and vml renderer don't have context + var ctx = path.getContext(); + if (ctx) { + path.rebuildPath(ctx); + } + }; + + return pathBundle; + } + + /** + * @alias zrender/graphic/Text + * @extends module:zrender/graphic/Displayable + * @constructor + * @param {Object} opts + */ + var Text = function(opts) { // jshint ignore:line + Displayable.call(this, opts); + }; + + Text.prototype = { + + constructor: Text, + + type: 'text', + + brush: function(ctx, prevEl) { + var style = this.style; + + // Optimize, avoid normalize every time. + this.__dirty && normalizeTextStyle(style, true); + + // Use props with prefix 'text'. + style.fill = style.stroke = style.shadowBlur = style.shadowColor = + style.shadowOffsetX = style.shadowOffsetY = null; + + var text = style.text; + // Convert to string + text != null && (text += ''); + + // Always bind style + style.bind(ctx, this, prevEl); + + if (!needDrawText(text, style)) { + return; + } + + this.setTransform(ctx); + + renderText(this, ctx, text, style); + + this.restoreTransform(ctx); + }, + + getBoundingRect: function() { + var style = this.style; + + // Optimize, avoid normalize every time. + this.__dirty && normalizeTextStyle(style, true); + + if (!this._rect) { + var text = style.text; + text != null ? (text += '') : (text = ''); + + var rect = getBoundingRect( + style.text + '', + style.font, + style.textAlign, + style.textVerticalAlign, + style.textPadding, + style.rich + ); + + rect.x += style.x || 0; + rect.y += style.y || 0; + + if (getStroke(style.textStroke, style.textStrokeWidth)) { + var w = style.textStrokeWidth; + rect.x -= w / 2; + rect.y -= w / 2; + rect.width += w; + rect.height += w; + } + + this._rect = rect; + } + + return this._rect; + } + }; + + inherits(Text, Displayable); + + /** + * 圆形 + * @module zrender/shape/Circle + */ + + var Circle = Path.extend({ + + type: 'circle', + + shape: { + cx: 0, + cy: 0, + r: 0 + }, + + + buildPath: function(ctx, shape, inBundle) { + // Better stroking in ShapeBundle + // Always do it may have performence issue ( fill may be 2x more cost) + if (inBundle) { + ctx.moveTo(shape.cx + shape.r, shape.cy); + } + // else { + // if (ctx.allocate && !ctx.data.length) { + // ctx.allocate(ctx.CMD_MEM_SIZE.A); + // } + // } + // Better stroking in ShapeBundle + // ctx.moveTo(shape.cx + shape.r, shape.cy); + ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true); + } + }); + + // Fix weird bug in some version of IE11 (like 11.0.9600.178**), + // where exception "unexpected call to method or property access" + // might be thrown when calling ctx.fill or ctx.stroke after a path + // whose area size is zero is drawn and ctx.clip() is called and + // shadowBlur is set. See #4572, #3112, #5777. + // (e.g., + // ctx.moveTo(10, 10); + // ctx.lineTo(20, 10); + // ctx.closePath(); + // ctx.clip(); + // ctx.shadowBlur = 10; + // ... + // ctx.fill(); + // ) + + var shadowTemp = [ + ['shadowBlur', 0], + ['shadowColor', '#000'], + ['shadowOffsetX', 0], + ['shadowOffsetY', 0] + ]; + + var fixClipWithShadow = function(orignalBrush) { + + // version string can be: '11.0' + return (env$1.browser.ie && env$1.browser.version >= 11) + + ? + function() { + var clipPaths = this.__clipPaths; + var style = this.style; + var modified; + + if (clipPaths) { + for (var i = 0; i < clipPaths.length; i++) { + var clipPath = clipPaths[i]; + var shape = clipPath && clipPath.shape; + var type = clipPath && clipPath.type; + + if (shape && ( + (type === 'sector' && shape.startAngle === shape.endAngle) || + (type === 'rect' && (!shape.width || !shape.height)) + )) { + for (var j = 0; j < shadowTemp.length; j++) { + // It is save to put shadowTemp static, because shadowTemp + // will be all modified each item brush called. + shadowTemp[j][2] = style[shadowTemp[j][0]]; + style[shadowTemp[j][0]] = shadowTemp[j][1]; + } + modified = true; + break; + } + } + } + + orignalBrush.apply(this, arguments); + + if (modified) { + for (var j = 0; j < shadowTemp.length; j++) { + style[shadowTemp[j][0]] = shadowTemp[j][2]; + } + } + } + + : + orignalBrush; + }; + + /** + * 扇形 + * @module zrender/graphic/shape/Sector + */ + + var Sector = Path.extend({ + + type: 'sector', + + shape: { + + cx: 0, + + cy: 0, + + r0: 0, + + r: 0, + + startAngle: 0, + + endAngle: Math.PI * 2, + + clockwise: true + }, + + brush: fixClipWithShadow(Path.prototype.brush), + + buildPath: function(ctx, shape) { + + var x = shape.cx; + var y = shape.cy; + var r0 = Math.max(shape.r0 || 0, 0); + var r = Math.max(shape.r, 0); + var startAngle = shape.startAngle; + var endAngle = shape.endAngle; + var clockwise = shape.clockwise; + + var unitX = Math.cos(startAngle); + var unitY = Math.sin(startAngle); + + ctx.moveTo(unitX * r0 + x, unitY * r0 + y); + + ctx.lineTo(unitX * r + x, unitY * r + y); + + ctx.arc(x, y, r, startAngle, endAngle, !clockwise); + + ctx.lineTo( + Math.cos(endAngle) * r0 + x, + Math.sin(endAngle) * r0 + y + ); + + if (r0 !== 0) { + ctx.arc(x, y, r0, endAngle, startAngle, clockwise); + } + + ctx.closePath(); + } + }); + + /** + * 圆环 + * @module zrender/graphic/shape/Ring + */ + + var Ring = Path.extend({ + + type: 'ring', + + shape: { + cx: 0, + cy: 0, + r: 0, + r0: 0 + }, + + buildPath: function(ctx, shape) { + var x = shape.cx; + var y = shape.cy; + var PI2 = Math.PI * 2; + ctx.moveTo(x + shape.r, y); + ctx.arc(x, y, shape.r, 0, PI2, false); + ctx.moveTo(x + shape.r0, y); + ctx.arc(x, y, shape.r0, 0, PI2, true); + } + }); + + /** + * Catmull-Rom spline 插值折线 + * @module zrender/shape/util/smoothSpline + * @author pissang (https://www.github.com/pissang) + * Kener (@Kener-林峰, kener.linfeng@gmail.com) + * errorrik (errorrik@gmail.com) + */ + + /** + * @inner + */ + function interpolate(p0, p1, p2, p3, t, t2, t3) { + var v0 = (p2 - p0) * 0.5; + var v1 = (p3 - p1) * 0.5; + return (2 * (p1 - p2) + v0 + v1) * t3 + + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + + v0 * t + p1; + } + + /** + * @alias module:zrender/shape/util/smoothSpline + * @param {Array} points 线段顶点数组 + * @param {boolean} isLoop + * @return {Array} + */ + var smoothSpline = function(points, isLoop) { + var len$$1 = points.length; + var ret = []; + + var distance$$1 = 0; + for (var i = 1; i < len$$1; i++) { + distance$$1 += distance(points[i - 1], points[i]); + } + + var segs = distance$$1 / 2; + segs = segs < len$$1 ? len$$1 : segs; + for (var i = 0; i < segs; i++) { + var pos = i / (segs - 1) * (isLoop ? len$$1 : len$$1 - 1); + var idx = Math.floor(pos); + + var w = pos - idx; + + var p0; + var p1 = points[idx % len$$1]; + var p2; + var p3; + if (!isLoop) { + p0 = points[idx === 0 ? idx : idx - 1]; + p2 = points[idx > len$$1 - 2 ? len$$1 - 1 : idx + 1]; + p3 = points[idx > len$$1 - 3 ? len$$1 - 1 : idx + 2]; + } else { + p0 = points[(idx - 1 + len$$1) % len$$1]; + p2 = points[(idx + 1) % len$$1]; + p3 = points[(idx + 2) % len$$1]; + } + + var w2 = w * w; + var w3 = w * w2; + + ret.push([ + interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3), + interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3) + ]); + } + return ret; + }; + + /** + * 贝塞尔平滑曲线 + * @module zrender/shape/util/smoothBezier + * @author pissang (https://www.github.com/pissang) + * Kener (@Kener-林峰, kener.linfeng@gmail.com) + * errorrik (errorrik@gmail.com) + */ + + /** + * 贝塞尔平滑曲线 + * @alias module:zrender/shape/util/smoothBezier + * @param {Array} points 线段顶点数组 + * @param {number} smooth 平滑等级, 0-1 + * @param {boolean} isLoop + * @param {Array} constraint 将计算出来的控制点约束在一个包围盒内 + * 比如 [[0, 0], [100, 100]], 这个包围盒会与 + * 整个折线的包围盒做一个并集用来约束控制点。 + * @param {Array} 计算出来的控制点数组 + */ + var smoothBezier = function(points, smooth, isLoop, constraint) { + var cps = []; + + var v = []; + var v1 = []; + var v2 = []; + var prevPoint; + var nextPoint; + + var min$$1, max$$1; + if (constraint) { + min$$1 = [Infinity, Infinity]; + max$$1 = [-Infinity, -Infinity]; + for (var i = 0, len$$1 = points.length; i < len$$1; i++) { + min(min$$1, min$$1, points[i]); + max(max$$1, max$$1, points[i]); + } + // 与指定的包围盒做并集 + min(min$$1, min$$1, constraint[0]); + max(max$$1, max$$1, constraint[1]); + } + + for (var i = 0, len$$1 = points.length; i < len$$1; i++) { + var point = points[i]; + + if (isLoop) { + prevPoint = points[i ? i - 1 : len$$1 - 1]; + nextPoint = points[(i + 1) % len$$1]; + } else { + if (i === 0 || i === len$$1 - 1) { + cps.push(clone$1(points[i])); + continue; + } else { + prevPoint = points[i - 1]; + nextPoint = points[i + 1]; + } + } + + sub(v, nextPoint, prevPoint); + + // use degree to scale the handle length + scale(v, v, smooth); + + var d0 = distance(point, prevPoint); + var d1 = distance(point, nextPoint); + var sum = d0 + d1; + if (sum !== 0) { + d0 /= sum; + d1 /= sum; + } + + scale(v1, v, -d0); + scale(v2, v, d1); + var cp0 = add([], point, v1); + var cp1 = add([], point, v2); + if (constraint) { + max(cp0, cp0, min$$1); + min(cp0, cp0, max$$1); + max(cp1, cp1, min$$1); + min(cp1, cp1, max$$1); + } + cps.push(cp0); + cps.push(cp1); + } + + if (isLoop) { + cps.push(cps.shift()); + } + + return cps; + }; + + function buildPath$1(ctx, shape, closePath) { + var points = shape.points; + var smooth = shape.smooth; + if (points && points.length >= 2) { + if (smooth && smooth !== 'spline') { + var controlPoints = smoothBezier( + points, smooth, closePath, shape.smoothConstraint + ); + + ctx.moveTo(points[0][0], points[0][1]); + var len = points.length; + for (var i = 0; i < (closePath ? len : len - 1); i++) { + var cp1 = controlPoints[i * 2]; + var cp2 = controlPoints[i * 2 + 1]; + var p = points[(i + 1) % len]; + ctx.bezierCurveTo( + cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1] + ); + } + } else { + if (smooth === 'spline') { + points = smoothSpline(points, closePath); + } + + ctx.moveTo(points[0][0], points[0][1]); + for (var i = 1, l = points.length; i < l; i++) { + ctx.lineTo(points[i][0], points[i][1]); + } + } + + closePath && ctx.closePath(); + } + } + + /** + * 多边形 + * @module zrender/shape/Polygon + */ + + var Polygon = Path.extend({ + + type: 'polygon', + + shape: { + points: null, + + smooth: false, + + smoothConstraint: null + }, + + buildPath: function(ctx, shape) { + buildPath$1(ctx, shape, true); + } + }); + + /** + * @module zrender/graphic/shape/Polyline + */ + + var Polyline = Path.extend({ + + type: 'polyline', + + shape: { + points: null, + + smooth: false, + + smoothConstraint: null + }, + + style: { + stroke: '#000', + + fill: null + }, + + buildPath: function(ctx, shape) { + buildPath$1(ctx, shape, false); + } + }); + + /** + * 矩形 + * @module zrender/graphic/shape/Rect + */ + + var Rect = Path.extend({ + + type: 'rect', + + shape: { + // 左上、右上、右下、左下角的半径依次为r1、r2、r3、r4 + // r缩写为1 相当于 [1, 1, 1, 1] + // r缩写为[1] 相当于 [1, 1, 1, 1] + // r缩写为[1, 2] 相当于 [1, 2, 1, 2] + // r缩写为[1, 2, 3] 相当于 [1, 2, 3, 2] + r: 0, + + x: 0, + y: 0, + width: 0, + height: 0 + }, + + buildPath: function(ctx, shape) { + var x = shape.x; + var y = shape.y; + var width = shape.width; + var height = shape.height; + if (!shape.r) { + ctx.rect(x, y, width, height); + } else { + buildPath(ctx, shape); + } + ctx.closePath(); + return; + } + }); + + /** + * 直线 + * @module zrender/graphic/shape/Line + */ + + var Line = Path.extend({ + + type: 'line', + + shape: { + // Start point + x1: 0, + y1: 0, + // End point + x2: 0, + y2: 0, + + percent: 1 + }, + + style: { + stroke: '#000', + fill: null + }, + + buildPath: function(ctx, shape) { + var x1 = shape.x1; + var y1 = shape.y1; + var x2 = shape.x2; + var y2 = shape.y2; + var percent = shape.percent; + + if (percent === 0) { + return; + } + + ctx.moveTo(x1, y1); + + if (percent < 1) { + x2 = x1 * (1 - percent) + x2 * percent; + y2 = y1 * (1 - percent) + y2 * percent; + } + ctx.lineTo(x2, y2); + }, + + /** + * Get point at percent + * @param {number} percent + * @return {Array.} + */ + pointAt: function(p) { + var shape = this.shape; + return [ + shape.x1 * (1 - p) + shape.x2 * p, + shape.y1 * (1 - p) + shape.y2 * p + ]; + } + }); + + /** + * 贝塞尔曲线 + * @module zrender/shape/BezierCurve + */ + + var out = []; + + function someVectorAt(shape, t, isTangent) { + var cpx2 = shape.cpx2; + var cpy2 = shape.cpy2; + if (cpx2 === null || cpy2 === null) { + return [ + (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t), + (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t) + ]; + } else { + return [ + (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t), + (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t) + ]; + } + } + + var BezierCurve = Path.extend({ + + type: 'bezier-curve', + + shape: { + x1: 0, + y1: 0, + x2: 0, + y2: 0, + cpx1: 0, + cpy1: 0, + // cpx2: 0, + // cpy2: 0 + + // Curve show percent, for animating + percent: 1 + }, + + style: { + stroke: '#000', + fill: null + }, + + buildPath: function(ctx, shape) { + var x1 = shape.x1; + var y1 = shape.y1; + var x2 = shape.x2; + var y2 = shape.y2; + var cpx1 = shape.cpx1; + var cpy1 = shape.cpy1; + var cpx2 = shape.cpx2; + var cpy2 = shape.cpy2; + var percent = shape.percent; + if (percent === 0) { + return; + } + + ctx.moveTo(x1, y1); + + if (cpx2 == null || cpy2 == null) { + if (percent < 1) { + quadraticSubdivide( + x1, cpx1, x2, percent, out + ); + cpx1 = out[1]; + x2 = out[2]; + quadraticSubdivide( + y1, cpy1, y2, percent, out + ); + cpy1 = out[1]; + y2 = out[2]; + } + + ctx.quadraticCurveTo( + cpx1, cpy1, + x2, y2 + ); + } else { + if (percent < 1) { + cubicSubdivide( + x1, cpx1, cpx2, x2, percent, out + ); + cpx1 = out[1]; + cpx2 = out[2]; + x2 = out[3]; + cubicSubdivide( + y1, cpy1, cpy2, y2, percent, out + ); + cpy1 = out[1]; + cpy2 = out[2]; + y2 = out[3]; + } + ctx.bezierCurveTo( + cpx1, cpy1, + cpx2, cpy2, + x2, y2 + ); + } + }, + + /** + * Get point at percent + * @param {number} t + * @return {Array.} + */ + pointAt: function(t) { + return someVectorAt(this.shape, t, false); + }, + + /** + * Get tangent at percent + * @param {number} t + * @return {Array.} + */ + tangentAt: function(t) { + var p = someVectorAt(this.shape, t, true); + return normalize(p, p); + } + }); + + /** + * 圆弧 + * @module zrender/graphic/shape/Arc + */ + + var Arc = Path.extend({ + + type: 'arc', + + shape: { + + cx: 0, + + cy: 0, + + r: 0, + + startAngle: 0, + + endAngle: Math.PI * 2, + + clockwise: true + }, + + style: { + + stroke: '#000', + + fill: null + }, + + buildPath: function(ctx, shape) { + + var x = shape.cx; + var y = shape.cy; + var r = Math.max(shape.r, 0); + var startAngle = shape.startAngle; + var endAngle = shape.endAngle; + var clockwise = shape.clockwise; + + var unitX = Math.cos(startAngle); + var unitY = Math.sin(startAngle); + + ctx.moveTo(unitX * r + x, unitY * r + y); + ctx.arc(x, y, r, startAngle, endAngle, !clockwise); + } + }); + + // CompoundPath to improve performance + + var CompoundPath = Path.extend({ + + type: 'compound', + + shape: { + + paths: null + }, + + _updatePathDirty: function() { + var dirtyPath = this.__dirtyPath; + var paths = this.shape.paths; + for (var i = 0; i < paths.length; i++) { + // Mark as dirty if any subpath is dirty + dirtyPath = dirtyPath || paths[i].__dirtyPath; + } + this.__dirtyPath = dirtyPath; + this.__dirty = this.__dirty || dirtyPath; + }, + + beforeBrush: function() { + this._updatePathDirty(); + var paths = this.shape.paths || []; + var scale = this.getGlobalScale(); + // Update path scale + for (var i = 0; i < paths.length; i++) { + if (!paths[i].path) { + paths[i].createPathProxy(); + } + paths[i].path.setScale(scale[0], scale[1]); + } + }, + + buildPath: function(ctx, shape) { + var paths = shape.paths || []; + for (var i = 0; i < paths.length; i++) { + paths[i].buildPath(ctx, paths[i].shape, true); + } + }, + + afterBrush: function() { + var paths = this.shape.paths || []; + for (var i = 0; i < paths.length; i++) { + paths[i].__dirtyPath = false; + } + }, + + getBoundingRect: function() { + this._updatePathDirty(); + return Path.prototype.getBoundingRect.call(this); + } + }); + + /** + * @param {Array.} colorStops + */ + var Gradient = function(colorStops) { + + this.colorStops = colorStops || []; + + }; + + Gradient.prototype = { + + constructor: Gradient, + + addColorStop: function(offset, color) { + this.colorStops.push({ + + offset: offset, + + color: color + }); + } + + }; + + /** + * x, y, x2, y2 are all percent from 0 to 1 + * @param {number} [x=0] + * @param {number} [y=0] + * @param {number} [x2=1] + * @param {number} [y2=0] + * @param {Array.} colorStops + * @param {boolean} [globalCoord=false] + */ + var LinearGradient = function(x, y, x2, y2, colorStops, globalCoord) { + // Should do nothing more in this constructor. Because gradient can be + // declard by `color: {type: 'linear', colorStops: ...}`, where + // this constructor will not be called. + + this.x = x == null ? 0 : x; + + this.y = y == null ? 0 : y; + + this.x2 = x2 == null ? 1 : x2; + + this.y2 = y2 == null ? 0 : y2; + + // Can be cloned + this.type = 'linear'; + + // If use global coord + this.global = globalCoord || false; + + Gradient.call(this, colorStops); + }; + + LinearGradient.prototype = { + + constructor: LinearGradient + }; + + inherits(LinearGradient, Gradient); + + /** + * x, y, r are all percent from 0 to 1 + * @param {number} [x=0.5] + * @param {number} [y=0.5] + * @param {number} [r=0.5] + * @param {Array.} [colorStops] + * @param {boolean} [globalCoord=false] + */ + var RadialGradient = function(x, y, r, colorStops, globalCoord) { + // Should do nothing more in this constructor. Because gradient can be + // declard by `color: {type: 'radial', colorStops: ...}`, where + // this constructor will not be called. + + this.x = x == null ? 0.5 : x; + + this.y = y == null ? 0.5 : y; + + this.r = r == null ? 0.5 : r; + + // Can be cloned + this.type = 'radial'; + + // If use global coord + this.global = globalCoord || false; + + Gradient.call(this, colorStops); + }; + + RadialGradient.prototype = { + + constructor: RadialGradient + }; + + inherits(RadialGradient, Gradient); + + /** + * Displayable for incremental rendering. It will be rendered in a separate layer + * IncrementalDisplay have too main methods. `clearDisplayables` and `addDisplayables` + * addDisplayables will render the added displayables incremetally. + * + * It use a not clearFlag to tell the painter don't clear the layer if it's the first element. + */ + // TODO Style override ? + function IncrementalDisplayble(opts) { + + Displayable.call(this, opts); + + this._displayables = []; + + this._temporaryDisplayables = []; + + this._cursor = 0; + + this.notClear = true; + } + + IncrementalDisplayble.prototype.incremental = true; + + IncrementalDisplayble.prototype.clearDisplaybles = function() { + this._displayables = []; + this._temporaryDisplayables = []; + this._cursor = 0; + this.dirty(); + + this.notClear = false; + }; + + IncrementalDisplayble.prototype.addDisplayable = function(displayable, notPersistent) { + if (notPersistent) { + this._temporaryDisplayables.push(displayable); + } else { + this._displayables.push(displayable); + } + this.dirty(); + }; + + IncrementalDisplayble.prototype.addDisplayables = function(displayables, notPersistent) { + notPersistent = notPersistent || false; + for (var i = 0; i < displayables.length; i++) { + this.addDisplayable(displayables[i], notPersistent); + } + }; + + IncrementalDisplayble.prototype.eachPendingDisplayable = function(cb) { + for (var i = this._cursor; i < this._displayables.length; i++) { + cb && cb(this._displayables[i]); + } + for (var i = 0; i < this._temporaryDisplayables.length; i++) { + cb && cb(this._temporaryDisplayables[i]); + } + }; + + IncrementalDisplayble.prototype.update = function() { + this.updateTransform(); + for (var i = this._cursor; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + // PENDING + displayable.parent = this; + displayable.update(); + displayable.parent = null; + } + for (var i = 0; i < this._temporaryDisplayables.length; i++) { + var displayable = this._temporaryDisplayables[i]; + // PENDING + displayable.parent = this; + displayable.update(); + displayable.parent = null; + } + }; + + IncrementalDisplayble.prototype.brush = function(ctx, prevEl) { + // Render persistant displayables. + for (var i = this._cursor; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + displayable.beforeBrush && displayable.beforeBrush(ctx); + displayable.brush(ctx, i === this._cursor ? null : this._displayables[i - 1]); + displayable.afterBrush && displayable.afterBrush(ctx); + } + this._cursor = i; + // Render temporary displayables. + for (var i = 0; i < this._temporaryDisplayables.length; i++) { + var displayable = this._temporaryDisplayables[i]; + displayable.beforeBrush && displayable.beforeBrush(ctx); + displayable.brush(ctx, i === 0 ? null : this._temporaryDisplayables[i - 1]); + displayable.afterBrush && displayable.afterBrush(ctx); + } + + this._temporaryDisplayables = []; + + this.notClear = true; + }; + + var m = []; + IncrementalDisplayble.prototype.getBoundingRect = function() { + if (!this._rect) { + var rect = new BoundingRect(Infinity, Infinity, -Infinity, -Infinity); + for (var i = 0; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + var childRect = displayable.getBoundingRect().clone(); + if (displayable.needLocalTransform()) { + childRect.applyTransform(displayable.getLocalTransform(m)); + } + rect.union(childRect); + } + this._rect = rect; + } + return this._rect; + }; + + IncrementalDisplayble.prototype.contain = function(x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + + if (rect.contain(localPos[0], localPos[1])) { + for (var i = 0; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + if (displayable.contain(x, y)) { + return true; + } + } + } + return false; + }; + + inherits(IncrementalDisplayble, Displayable); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var round = Math.round; + var mathMax$1 = Math.max; + var mathMin$1 = Math.min; + + var EMPTY_OBJ = {}; + + /** + * Extend shape with parameters + */ + function extendShape(opts) { + return Path.extend(opts); + } + + /** + * Extend path + */ + function extendPath(pathData, opts) { + return extendFromString(pathData, opts); + } + + /** + * Create a path element from path data string + * @param {string} pathData + * @param {Object} opts + * @param {module:zrender/core/BoundingRect} rect + * @param {string} [layout=cover] 'center' or 'cover' + */ + function makePath(pathData, opts, rect, layout) { + var path = createFromString(pathData, opts); + var boundingRect = path.getBoundingRect(); + if (rect) { + if (layout === 'center') { + rect = centerGraphic(rect, boundingRect); + } + + resizePath(path, rect); + } + return path; + } + + /** + * Create a image element from image url + * @param {string} imageUrl image url + * @param {Object} opts options + * @param {module:zrender/core/BoundingRect} rect constrain rect + * @param {string} [layout=cover] 'center' or 'cover' + */ + function makeImage(imageUrl, rect, layout) { + var path = new ZImage({ + style: { + image: imageUrl, + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + onload: function(img) { + if (layout === 'center') { + var boundingRect = { + width: img.width, + height: img.height + }; + path.setStyle(centerGraphic(rect, boundingRect)); + } + } + }); + return path; + } + + /** + * Get position of centered element in bounding box. + * + * @param {Object} rect element local bounding box + * @param {Object} boundingRect constraint bounding box + * @return {Object} element position containing x, y, width, and height + */ + function centerGraphic(rect, boundingRect) { + // Set rect to center, keep width / height ratio. + var aspect = boundingRect.width / boundingRect.height; + var width = rect.height * aspect; + var height; + if (width <= rect.width) { + height = rect.height; + } else { + width = rect.width; + height = width / aspect; + } + var cx = rect.x + rect.width / 2; + var cy = rect.y + rect.height / 2; + + return { + x: cx - width / 2, + y: cy - height / 2, + width: width, + height: height + }; + } + + var mergePath = mergePath$1; + + /** + * Resize a path to fit the rect + * @param {module:zrender/graphic/Path} path + * @param {Object} rect + */ + function resizePath(path, rect) { + if (!path.applyTransform) { + return; + } + + var pathRect = path.getBoundingRect(); + + var m = pathRect.calculateTransform(rect); + + path.applyTransform(m); + } + + /** + * Sub pixel optimize line for canvas + * + * @param {Object} param + * @param {Object} [param.shape] + * @param {number} [param.shape.x1] + * @param {number} [param.shape.y1] + * @param {number} [param.shape.x2] + * @param {number} [param.shape.y2] + * @param {Object} [param.style] + * @param {number} [param.style.lineWidth] + * @return {Object} Modified param + */ + function subPixelOptimizeLine(param) { + var shape = param.shape; + var lineWidth = param.style.lineWidth; + + if (round(shape.x1 * 2) === round(shape.x2 * 2)) { + shape.x1 = shape.x2 = subPixelOptimize(shape.x1, lineWidth, true); + } + if (round(shape.y1 * 2) === round(shape.y2 * 2)) { + shape.y1 = shape.y2 = subPixelOptimize(shape.y1, lineWidth, true); + } + return param; + } + + /** + * Sub pixel optimize rect for canvas + * + * @param {Object} param + * @param {Object} [param.shape] + * @param {number} [param.shape.x] + * @param {number} [param.shape.y] + * @param {number} [param.shape.width] + * @param {number} [param.shape.height] + * @param {Object} [param.style] + * @param {number} [param.style.lineWidth] + * @return {Object} Modified param + */ + function subPixelOptimizeRect(param) { + var shape = param.shape; + var lineWidth = param.style.lineWidth; + var originX = shape.x; + var originY = shape.y; + var originWidth = shape.width; + var originHeight = shape.height; + shape.x = subPixelOptimize(shape.x, lineWidth, true); + shape.y = subPixelOptimize(shape.y, lineWidth, true); + shape.width = Math.max( + subPixelOptimize(originX + originWidth, lineWidth, false) - shape.x, + originWidth === 0 ? 0 : 1 + ); + shape.height = Math.max( + subPixelOptimize(originY + originHeight, lineWidth, false) - shape.y, + originHeight === 0 ? 0 : 1 + ); + return param; + } + + /** + * Sub pixel optimize for canvas + * + * @param {number} position Coordinate, such as x, y + * @param {number} lineWidth Should be nonnegative integer. + * @param {boolean=} positiveOrNegative Default false (negative). + * @return {number} Optimized position. + */ + function subPixelOptimize(position, lineWidth, positiveOrNegative) { + // Assure that (position + lineWidth / 2) is near integer edge, + // otherwise line will be fuzzy in canvas. + var doubledPosition = round(position * 2); + return (doubledPosition + round(lineWidth)) % 2 === 0 ? + doubledPosition / 2 : + (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2; + } + + function hasFillOrStroke(fillOrStroke) { + return fillOrStroke != null && fillOrStroke != 'none'; + } + + function liftColor(color) { + return typeof color === 'string' ? lift(color, -0.1) : color; + } + + /** + * @private + */ + function cacheElementStl(el) { + if (el.__hoverStlDirty) { + var stroke = el.style.stroke; + var fill = el.style.fill; + + // Create hoverStyle on mouseover + var hoverStyle = el.__hoverStl; + hoverStyle.fill = hoverStyle.fill || + (hasFillOrStroke(fill) ? liftColor(fill) : null); + hoverStyle.stroke = hoverStyle.stroke || + (hasFillOrStroke(stroke) ? liftColor(stroke) : null); + + var normalStyle = {}; + for (var name in hoverStyle) { + // See comment in `doSingleEnterHover`. + if (hoverStyle[name] != null) { + normalStyle[name] = el.style[name]; + } + } + + el.__normalStl = normalStyle; + + el.__hoverStlDirty = false; + } + } + + /** + * @private + */ + function doSingleEnterHover(el) { + if (el.__isHover) { + return; + } + + cacheElementStl(el); + + if (el.useHoverLayer) { + el.__zr && el.__zr.addHover(el, el.__hoverStl); + } else { + var style = el.style; + var insideRollbackOpt = style.insideRollbackOpt; + + // Consider case: only `position: 'top'` is set on emphasis, then text + // color should be returned to `autoColor`, rather than remain '#fff'. + // So we should rollback then apply again after style merging. + insideRollbackOpt && rollbackInsideStyle(style); + + // styles can be: + // { + // label: { + // show: false, + // position: 'outside', + // fontSize: 18 + // }, + // emphasis: { + // label: { + // show: true + // } + // } + // }, + // where properties of `emphasis` may not appear in `normal`. We previously use + // module:echarts/util/model#defaultEmphasis to merge `normal` to `emphasis`. + // But consider rich text and setOption in merge mode, it is impossible to cover + // all properties in merge. So we use merge mode when setting style here, where + // only properties that is not `null/undefined` can be set. The disadventage: + // null/undefined can not be used to remove style any more in `emphasis`. + style.extendFrom(el.__hoverStl); + + // Do not save `insideRollback`. + if (insideRollbackOpt) { + applyInsideStyle(style, style.insideOriginalTextPosition, insideRollbackOpt); + + // textFill may be rollbacked to null. + if (style.textFill == null) { + style.textFill = insideRollbackOpt.autoColor; + } + } + + el.dirty(false); + el.z2 += 1; + } + + el.__isHover = true; + } + + /** + * @inner + */ + function doSingleLeaveHover(el) { + if (!el.__isHover) { + return; + } + + var normalStl = el.__normalStl; + if (el.useHoverLayer) { + el.__zr && el.__zr.removeHover(el); + } else { + // Consider null/undefined value, should use + // `setStyle` but not `extendFrom(stl, true)`. + normalStl && el.setStyle(normalStl); + el.z2 -= 1; + } + + el.__isHover = false; + } + + /** + * @inner + */ + function doEnterHover(el) { + el.type === 'group' ? + el.traverse(function(child) { + if (child.type !== 'group') { + doSingleEnterHover(child); + } + }) : + doSingleEnterHover(el); + } + + function doLeaveHover(el) { + el.type === 'group' ? + el.traverse(function(child) { + if (child.type !== 'group') { + doSingleLeaveHover(child); + } + }) : + doSingleLeaveHover(el); + } + + /** + * @inner + */ + function setElementHoverStl(el, hoverStl) { + // If element has sepcified hoverStyle, then use it instead of given hoverStyle + // Often used when item group has a label element and it's hoverStyle is different + el.__hoverStl = el.hoverStyle || hoverStl || {}; + el.__hoverStlDirty = true; + + if (el.__isHover) { + cacheElementStl(el); + } + } + + /** + * @inner + */ + function onElementMouseOver(e) { + if (this.__hoverSilentOnTouch && e.zrByTouch) { + return; + } + + // Only if element is not in emphasis status + !this.__isEmphasis && doEnterHover(this); + } + + /** + * @inner + */ + function onElementMouseOut(e) { + if (this.__hoverSilentOnTouch && e.zrByTouch) { + return; + } + + // Only if element is not in emphasis status + !this.__isEmphasis && doLeaveHover(this); + } + + /** + * @inner + */ + function enterEmphasis() { + this.__isEmphasis = true; + doEnterHover(this); + } + + /** + * @inner + */ + function leaveEmphasis() { + this.__isEmphasis = false; + doLeaveHover(this); + } + + /** + * Set hover style of element. + * This method can be called repeatly without side-effects. + * @param {module:zrender/Element} el + * @param {Object} [hoverStyle] + * @param {Object} [opt] + * @param {boolean} [opt.hoverSilentOnTouch=false] + * In touch device, mouseover event will be trigger on touchstart event + * (see module:zrender/dom/HandlerProxy). By this mechanism, we can + * conviniently use hoverStyle when tap on touch screen without additional + * code for compatibility. + * But if the chart/component has select feature, which usually also use + * hoverStyle, there might be conflict between 'select-highlight' and + * 'hover-highlight' especially when roam is enabled (see geo for example). + * In this case, hoverSilentOnTouch should be used to disable hover-highlight + * on touch device. + */ + function setHoverStyle(el, hoverStyle, opt) { + el.__hoverSilentOnTouch = opt && opt.hoverSilentOnTouch; + + el.type === 'group' ? + el.traverse(function(child) { + if (child.type !== 'group') { + setElementHoverStl(child, hoverStyle); + } + }) : + setElementHoverStl(el, hoverStyle); + + // Duplicated function will be auto-ignored, see Eventful.js. + el.on('mouseover', onElementMouseOver) + .on('mouseout', onElementMouseOut); + + // Emphasis, normal can be triggered manually + el.on('emphasis', enterEmphasis) + .on('normal', leaveEmphasis); + } + + /** + * @param {Object|module:zrender/graphic/Style} normalStyle + * @param {Object} emphasisStyle + * @param {module:echarts/model/Model} normalModel + * @param {module:echarts/model/Model} emphasisModel + * @param {Object} opt Check `opt` of `setTextStyleCommon` to find other props. + * @param {string|Function} [opt.defaultText] + * @param {module:echarts/model/Model} [opt.labelFetcher] Fetch text by + * `opt.labelFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex)` + * @param {module:echarts/model/Model} [opt.labelDataIndex] Fetch text by + * `opt.textFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex)` + * @param {module:echarts/model/Model} [opt.labelDimIndex] Fetch text by + * `opt.textFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex)` + * @param {Object} [normalSpecified] + * @param {Object} [emphasisSpecified] + */ + function setLabelStyle( + normalStyle, emphasisStyle, + normalModel, emphasisModel, + opt, + normalSpecified, emphasisSpecified + ) { + opt = opt || EMPTY_OBJ; + var labelFetcher = opt.labelFetcher; + var labelDataIndex = opt.labelDataIndex; + var labelDimIndex = opt.labelDimIndex; + + // This scenario, `label.normal.show = true; label.emphasis.show = false`, + // is not supported util someone requests. + + var showNormal = normalModel.getShallow('show'); + var showEmphasis = emphasisModel.getShallow('show'); + + // Consider performance, only fetch label when necessary. + // If `normal.show` is `false` and `emphasis.show` is `true` and `emphasis.formatter` is not set, + // label should be displayed, where text is fetched by `normal.formatter` or `opt.defaultText`. + var baseText; + if (showNormal || showEmphasis) { + if (labelFetcher) { + baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex); + } + if (baseText == null) { + baseText = isFunction$1(opt.defaultText) ? opt.defaultText(labelDataIndex, opt) : opt.defaultText; + } + } + var normalStyleText = showNormal ? baseText : null; + var emphasisStyleText = showEmphasis ? + retrieve2( + labelFetcher ? + labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex) : + null, + baseText + ) : + null; + + // Optimize: If style.text is null, text will not be drawn. + if (normalStyleText != null || emphasisStyleText != null) { + // Always set `textStyle` even if `normalStyle.text` is null, because default + // values have to be set on `normalStyle`. + // If we set default values on `emphasisStyle`, consider case: + // Firstly, `setOption(... label: {normal: {text: null}, emphasis: {show: true}} ...);` + // Secondly, `setOption(... label: {noraml: {show: true, text: 'abc', color: 'red'} ...);` + // Then the 'red' will not work on emphasis. + setTextStyle(normalStyle, normalModel, normalSpecified, opt); + setTextStyle(emphasisStyle, emphasisModel, emphasisSpecified, opt, true); + } + + normalStyle.text = normalStyleText; + emphasisStyle.text = emphasisStyleText; + } + + /** + * Set basic textStyle properties. + * @param {Object|module:zrender/graphic/Style} textStyle + * @param {module:echarts/model/Model} model + * @param {Object} [specifiedTextStyle] Can be overrided by settings in model. + * @param {Object} [opt] See `opt` of `setTextStyleCommon`. + * @param {boolean} [isEmphasis] + */ + function setTextStyle( + textStyle, textStyleModel, specifiedTextStyle, opt, isEmphasis + ) { + setTextStyleCommon(textStyle, textStyleModel, opt, isEmphasis); + specifiedTextStyle && extend(textStyle, specifiedTextStyle); + textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false); + + return textStyle; + } + + /** + * Set text option in the style. + * @deprecated + * @param {Object} textStyle + * @param {module:echarts/model/Model} labelModel + * @param {string|boolean} defaultColor Default text color. + * If set as false, it will be processed as a emphasis style. + */ + function setText(textStyle, labelModel, defaultColor) { + var opt = { + isRectText: true + }; + var isEmphasis; + + if (defaultColor === false) { + isEmphasis = true; + } else { + // Support setting color as 'auto' to get visual color. + opt.autoColor = defaultColor; + } + setTextStyleCommon(textStyle, labelModel, opt, isEmphasis); + textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false); + } + + /** + * { + * disableBox: boolean, Whether diable drawing box of block (outer most). + * isRectText: boolean, + * autoColor: string, specify a color when color is 'auto', + * for textFill, textStroke, textBackgroundColor, and textBorderColor. + * If autoColor specified, it is used as default textFill. + * useInsideStyle: + * `true`: Use inside style (textFill, textStroke, textStrokeWidth) + * if `textFill` is not specified. + * `false`: Do not use inside style. + * `null/undefined`: use inside style if `isRectText` is true and + * `textFill` is not specified and textPosition contains `'inside'`. + * forceRich: boolean + * } + */ + function setTextStyleCommon(textStyle, textStyleModel, opt, isEmphasis) { + // Consider there will be abnormal when merge hover style to normal style if given default value. + opt = opt || EMPTY_OBJ; + + if (opt.isRectText) { + var textPosition = textStyleModel.getShallow('position') || + (isEmphasis ? null : 'inside'); + // 'outside' is not a valid zr textPostion value, but used + // in bar series, and magric type should be considered. + textPosition === 'outside' && (textPosition = 'top'); + textStyle.textPosition = textPosition; + textStyle.textOffset = textStyleModel.getShallow('offset'); + var labelRotate = textStyleModel.getShallow('rotate'); + labelRotate != null && (labelRotate *= Math.PI / 180); + textStyle.textRotation = labelRotate; + textStyle.textDistance = retrieve2( + textStyleModel.getShallow('distance'), isEmphasis ? null : 5 + ); + } + + var ecModel = textStyleModel.ecModel; + var globalTextStyle = ecModel && ecModel.option.textStyle; + + // Consider case: + // { + // data: [{ + // value: 12, + // label: { + // rich: { + // // no 'a' here but using parent 'a'. + // } + // } + // }], + // rich: { + // a: { ... } + // } + // } + var richItemNames = getRichItemNames(textStyleModel); + var richResult; + if (richItemNames) { + richResult = {}; + for (var name in richItemNames) { + if (richItemNames.hasOwnProperty(name)) { + // Cascade is supported in rich. + var richTextStyle = textStyleModel.getModel(['rich', name]); + // In rich, never `disableBox`. + setTokenTextStyle(richResult[name] = {}, richTextStyle, globalTextStyle, opt, isEmphasis); + } + } + } + textStyle.rich = richResult; + + setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isEmphasis, true); + + if (opt.forceRich && !opt.textStyle) { + opt.textStyle = {}; + } + + return textStyle; + } + + // Consider case: + // { + // data: [{ + // value: 12, + // label: { + // rich: { + // // no 'a' here but using parent 'a'. + // } + // } + // }], + // rich: { + // a: { ... } + // } + // } + function getRichItemNames(textStyleModel) { + // Use object to remove duplicated names. + var richItemNameMap; + while (textStyleModel && textStyleModel !== textStyleModel.ecModel) { + var rich = (textStyleModel.option || EMPTY_OBJ).rich; + if (rich) { + richItemNameMap = richItemNameMap || {}; + for (var name in rich) { + if (rich.hasOwnProperty(name)) { + richItemNameMap[name] = 1; + } + } + } + textStyleModel = textStyleModel.parentModel; + } + return richItemNameMap; + } + + function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isEmphasis, isBlock) { + // In merge mode, default value should not be given. + globalTextStyle = !isEmphasis && globalTextStyle || EMPTY_OBJ; + + textStyle.textFill = getAutoColor(textStyleModel.getShallow('color'), opt) || + globalTextStyle.color; + textStyle.textStroke = getAutoColor(textStyleModel.getShallow('textBorderColor'), opt) || + globalTextStyle.textBorderColor; + textStyle.textStrokeWidth = retrieve2( + textStyleModel.getShallow('textBorderWidth'), + globalTextStyle.textBorderWidth + ); + + if (!isEmphasis) { + if (isBlock) { + // Always set `insideRollback`, for clearing previous. + var originalTextPosition = textStyle.textPosition; + textStyle.insideRollback = applyInsideStyle(textStyle, originalTextPosition, opt); + // Save original textPosition, because style.textPosition will be repalced by + // real location (like [10, 30]) in zrender. + textStyle.insideOriginalTextPosition = originalTextPosition; + textStyle.insideRollbackOpt = opt; + } + + // Set default finally. + if (textStyle.textFill == null) { + textStyle.textFill = opt.autoColor; + } + } + + // Do not use `getFont` here, because merge should be supported, where + // part of these properties may be changed in emphasis style, and the + // others should remain their original value got from normal style. + textStyle.fontStyle = textStyleModel.getShallow('fontStyle') || globalTextStyle.fontStyle; + textStyle.fontWeight = textStyleModel.getShallow('fontWeight') || globalTextStyle.fontWeight; + textStyle.fontSize = textStyleModel.getShallow('fontSize') || globalTextStyle.fontSize; + textStyle.fontFamily = textStyleModel.getShallow('fontFamily') || globalTextStyle.fontFamily; + + textStyle.textAlign = textStyleModel.getShallow('align'); + textStyle.textVerticalAlign = textStyleModel.getShallow('verticalAlign') || + textStyleModel.getShallow('baseline'); + + textStyle.textLineHeight = textStyleModel.getShallow('lineHeight'); + textStyle.textWidth = textStyleModel.getShallow('width'); + textStyle.textHeight = textStyleModel.getShallow('height'); + textStyle.textTag = textStyleModel.getShallow('tag'); + + if (!isBlock || !opt.disableBox) { + textStyle.textBackgroundColor = getAutoColor(textStyleModel.getShallow('backgroundColor'), opt); + textStyle.textPadding = textStyleModel.getShallow('padding'); + textStyle.textBorderColor = getAutoColor(textStyleModel.getShallow('borderColor'), opt); + textStyle.textBorderWidth = textStyleModel.getShallow('borderWidth'); + textStyle.textBorderRadius = textStyleModel.getShallow('borderRadius'); + + textStyle.textBoxShadowColor = textStyleModel.getShallow('shadowColor'); + textStyle.textBoxShadowBlur = textStyleModel.getShallow('shadowBlur'); + textStyle.textBoxShadowOffsetX = textStyleModel.getShallow('shadowOffsetX'); + textStyle.textBoxShadowOffsetY = textStyleModel.getShallow('shadowOffsetY'); + } + + textStyle.textShadowColor = textStyleModel.getShallow('textShadowColor') || + globalTextStyle.textShadowColor; + textStyle.textShadowBlur = textStyleModel.getShallow('textShadowBlur') || + globalTextStyle.textShadowBlur; + textStyle.textShadowOffsetX = textStyleModel.getShallow('textShadowOffsetX') || + globalTextStyle.textShadowOffsetX; + textStyle.textShadowOffsetY = textStyleModel.getShallow('textShadowOffsetY') || + globalTextStyle.textShadowOffsetY; + } + + function getAutoColor(color, opt) { + return color !== 'auto' ? color : (opt && opt.autoColor) ? opt.autoColor : null; + } + + function applyInsideStyle(textStyle, textPosition, opt) { + var useInsideStyle = opt.useInsideStyle; + var insideRollback; + + if (textStyle.textFill == null && + useInsideStyle !== false && + (useInsideStyle === true || + (opt.isRectText && + textPosition + // textPosition can be [10, 30] + && + typeof textPosition === 'string' && + textPosition.indexOf('inside') >= 0 + ) + ) + ) { + insideRollback = { + textFill: null, + textStroke: textStyle.textStroke, + textStrokeWidth: textStyle.textStrokeWidth + }; + textStyle.textFill = '#fff'; + // Consider text with #fff overflow its container. + if (textStyle.textStroke == null) { + textStyle.textStroke = opt.autoColor; + textStyle.textStrokeWidth == null && (textStyle.textStrokeWidth = 2); + } + } + + return insideRollback; + } + + function rollbackInsideStyle(style) { + var insideRollback = style.insideRollback; + if (insideRollback) { + style.textFill = insideRollback.textFill; + style.textStroke = insideRollback.textStroke; + style.textStrokeWidth = insideRollback.textStrokeWidth; + } + } + + function getFont(opt, ecModel) { + // ecModel or default text style model. + var gTextStyleModel = ecModel || ecModel.getModel('textStyle'); + return trim([ + // FIXME in node-canvas fontWeight is before fontStyle + opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', + opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', + (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', + opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif' + ].join(' ')); + } + + function animateOrSetProps(isUpdate, el, props, animatableModel, dataIndex, cb) { + if (typeof dataIndex === 'function') { + cb = dataIndex; + dataIndex = null; + } + // Do not check 'animation' property directly here. Consider this case: + // animation model is an `itemModel`, whose does not have `isAnimationEnabled` + // but its parent model (`seriesModel`) does. + var animationEnabled = animatableModel && animatableModel.isAnimationEnabled(); + + if (animationEnabled) { + var postfix = isUpdate ? 'Update' : ''; + var duration = animatableModel.getShallow('animationDuration' + postfix); + var animationEasing = animatableModel.getShallow('animationEasing' + postfix); + var animationDelay = animatableModel.getShallow('animationDelay' + postfix); + if (typeof animationDelay === 'function') { + animationDelay = animationDelay( + dataIndex, + animatableModel.getAnimationDelayParams ? + animatableModel.getAnimationDelayParams(el, dataIndex) : + null + ); + } + if (typeof duration === 'function') { + duration = duration(dataIndex); + } + + duration > 0 ? + el.animateTo(props, duration, animationDelay || 0, animationEasing, cb, !!cb) : + (el.stopAnimation(), el.attr(props), cb && cb()); + } else { + el.stopAnimation(); + el.attr(props); + cb && cb(); + } + } + + /** + * Update graphic element properties with or without animation according to the + * configuration in series. + * + * Caution: this method will stop previous animation. + * So if do not use this method to one element twice before + * animation starts, unless you know what you are doing. + * + * @param {module:zrender/Element} el + * @param {Object} props + * @param {module:echarts/model/Model} [animatableModel] + * @param {number} [dataIndex] + * @param {Function} [cb] + * @example + * graphic.updateProps(el, { + * position: [100, 100] + * }, seriesModel, dataIndex, function () { console.log('Animation done!'); }); + * // Or + * graphic.updateProps(el, { + * position: [100, 100] + * }, seriesModel, function () { console.log('Animation done!'); }); + */ + function updateProps(el, props, animatableModel, dataIndex, cb) { + animateOrSetProps(true, el, props, animatableModel, dataIndex, cb); + } + + /** + * Init graphic element properties with or without animation according to the + * configuration in series. + * + * Caution: this method will stop previous animation. + * So if do not use this method to one element twice before + * animation starts, unless you know what you are doing. + * + * @param {module:zrender/Element} el + * @param {Object} props + * @param {module:echarts/model/Model} [animatableModel] + * @param {number} [dataIndex] + * @param {Function} cb + */ + function initProps(el, props, animatableModel, dataIndex, cb) { + animateOrSetProps(false, el, props, animatableModel, dataIndex, cb); + } + + /** + * Get transform matrix of target (param target), + * in coordinate of its ancestor (param ancestor) + * + * @param {module:zrender/mixin/Transformable} target + * @param {module:zrender/mixin/Transformable} [ancestor] + */ + function getTransform(target, ancestor) { + var mat = identity([]); + + while (target && target !== ancestor) { + mul$1(mat, target.getLocalTransform(), mat); + target = target.parent; + } + + return mat; + } + + /** + * Apply transform to an vertex. + * @param {Array.} target [x, y] + * @param {Array.|TypedArray.|Object} transform Can be: + * + Transform matrix: like [1, 0, 0, 1, 0, 0] + * + {position, rotation, scale}, the same as `zrender/Transformable`. + * @param {boolean=} invert Whether use invert matrix. + * @return {Array.} [x, y] + */ + function applyTransform$1(target, transform, invert$$1) { + if (transform && !isArrayLike(transform)) { + transform = Transformable.getLocalTransform(transform); + } + + if (invert$$1) { + transform = invert([], transform); + } + return applyTransform([], target, transform); + } + + /** + * @param {string} direction 'left' 'right' 'top' 'bottom' + * @param {Array.} transform Transform matrix: like [1, 0, 0, 1, 0, 0] + * @param {boolean=} invert Whether use invert matrix. + * @return {string} Transformed direction. 'left' 'right' 'top' 'bottom' + */ + function transformDirection(direction, transform, invert$$1) { + + // Pick a base, ensure that transform result will not be (0, 0). + var hBase = (transform[4] === 0 || transform[5] === 0 || transform[0] === 0) ? + 1 : Math.abs(2 * transform[4] / transform[0]); + var vBase = (transform[4] === 0 || transform[5] === 0 || transform[2] === 0) ? + 1 : Math.abs(2 * transform[4] / transform[2]); + + var vertex = [ + direction === 'left' ? -hBase : direction === 'right' ? hBase : 0, + direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0 + ]; + + vertex = applyTransform$1(vertex, transform, invert$$1); + + return Math.abs(vertex[0]) > Math.abs(vertex[1]) ? + (vertex[0] > 0 ? 'right' : 'left') : + (vertex[1] > 0 ? 'bottom' : 'top'); + } + + /** + * Apply group transition animation from g1 to g2. + * If no animatableModel, no animation. + */ + function groupTransition(g1, g2, animatableModel, cb) { + if (!g1 || !g2) { + return; + } + + function getElMap(g) { + var elMap = {}; + g.traverse(function(el) { + if (!el.isGroup && el.anid) { + elMap[el.anid] = el; + } + }); + return elMap; + } + + function getAnimatableProps(el) { + var obj = { + position: clone$1(el.position), + rotation: el.rotation + }; + if (el.shape) { + obj.shape = extend({}, el.shape); + } + return obj; + } + var elMap1 = getElMap(g1); + + g2.traverse(function(el) { + if (!el.isGroup && el.anid) { + var oldEl = elMap1[el.anid]; + if (oldEl) { + var newProp = getAnimatableProps(el); + el.attr(getAnimatableProps(oldEl)); + updateProps(el, newProp, animatableModel, el.dataIndex); + } + // else { + // if (el.previousProps) { + // graphic.updateProps + // } + // } + } + }); + } + + /** + * @param {Array.>} points Like: [[23, 44], [53, 66], ...] + * @param {Object} rect {x, y, width, height} + * @return {Array.>} A new clipped points. + */ + function clipPointsByRect(points, rect) { + return map(points, function(point) { + var x = point[0]; + x = mathMax$1(x, rect.x); + x = mathMin$1(x, rect.x + rect.width); + var y = point[1]; + y = mathMax$1(y, rect.y); + y = mathMin$1(y, rect.y + rect.height); + return [x, y]; + }); + } + + /** + * @param {Object} targetRect {x, y, width, height} + * @param {Object} rect {x, y, width, height} + * @return {Object} A new clipped rect. If rect size are negative, return undefined. + */ + function clipRectByRect(targetRect, rect) { + var x = mathMax$1(targetRect.x, rect.x); + var x2 = mathMin$1(targetRect.x + targetRect.width, rect.x + rect.width); + var y = mathMax$1(targetRect.y, rect.y); + var y2 = mathMin$1(targetRect.y + targetRect.height, rect.y + rect.height); + + if (x2 >= x && y2 >= y) { + return { + x: x, + y: y, + width: x2 - x, + height: y2 - y + }; + } + } + + /** + * @param {string} iconStr Support 'image://' or 'path://' or direct svg path. + * @param {Object} [opt] Properties of `module:zrender/Element`, except `style`. + * @param {Object} [rect] {x, y, width, height} + * @return {module:zrender/Element} Icon path or image element. + */ + function createIcon(iconStr, opt, rect) { + opt = extend({ + rectHover: true + }, opt); + var style = opt.style = { + strokeNoScale: true + }; + rect = rect || { + x: -1, + y: -1, + width: 2, + height: 2 + }; + + if (iconStr) { + return iconStr.indexOf('image://') === 0 ? + ( + style.image = iconStr.slice(8), + defaults(style, rect), + new ZImage(opt) + ) : + ( + makePath( + iconStr.replace('path://', ''), + opt, + rect, + 'center' + ) + ); + } + } + + + + + var graphic = (Object.freeze || Object)({ + extendShape: extendShape, + extendPath: extendPath, + makePath: makePath, + makeImage: makeImage, + mergePath: mergePath, + resizePath: resizePath, + subPixelOptimizeLine: subPixelOptimizeLine, + subPixelOptimizeRect: subPixelOptimizeRect, + subPixelOptimize: subPixelOptimize, + setHoverStyle: setHoverStyle, + setLabelStyle: setLabelStyle, + setTextStyle: setTextStyle, + setText: setText, + getFont: getFont, + updateProps: updateProps, + initProps: initProps, + getTransform: getTransform, + applyTransform: applyTransform$1, + transformDirection: transformDirection, + groupTransition: groupTransition, + clipPointsByRect: clipPointsByRect, + clipRectByRect: clipRectByRect, + createIcon: createIcon, + Group: Group, + Image: ZImage, + Text: Text, + Circle: Circle, + Sector: Sector, + Ring: Ring, + Polygon: Polygon, + Polyline: Polyline, + Rect: Rect, + Line: Line, + BezierCurve: BezierCurve, + Arc: Arc, + IncrementalDisplayable: IncrementalDisplayble, + CompoundPath: CompoundPath, + LinearGradient: LinearGradient, + RadialGradient: RadialGradient, + BoundingRect: BoundingRect + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PATH_COLOR = ['textStyle', 'color']; + + var textStyleMixin = { + /** + * Get color property or get color from option.textStyle.color + * @param {boolean} [isEmphasis] + * @return {string} + */ + getTextColor: function(isEmphasis) { + var ecModel = this.ecModel; + return this.getShallow('color') || + ( + (!isEmphasis && ecModel) ? ecModel.get(PATH_COLOR) : null + ); + }, + + /** + * Create font string from fontStyle, fontWeight, fontSize, fontFamily + * @return {string} + */ + getFont: function() { + return getFont({ + fontStyle: this.getShallow('fontStyle'), + fontWeight: this.getShallow('fontWeight'), + fontSize: this.getShallow('fontSize'), + fontFamily: this.getShallow('fontFamily') + }, this.ecModel); + }, + + getTextRect: function(text) { + return getBoundingRect( + text, + this.getFont(), + this.getShallow('align'), + this.getShallow('verticalAlign') || this.getShallow('baseline'), + this.getShallow('padding'), + this.getShallow('rich'), + this.getShallow('truncateText') + ); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var getItemStyle = makeStyleMapper( + [ + ['fill', 'color'], + ['stroke', 'borderColor'], + ['lineWidth', 'borderWidth'], + ['opacity'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'], + ['textPosition'], + ['textAlign'] + ] + ); + + var itemStyleMixin = { + getItemStyle: function(excludes, includes) { + var style = getItemStyle(this, excludes, includes); + var lineDash = this.getBorderLineDash(); + lineDash && (style.lineDash = lineDash); + return style; + }, + + getBorderLineDash: function() { + var lineType = this.get('borderType'); + return (lineType === 'solid' || lineType == null) ? null : + (lineType === 'dashed' ? [5, 5] : [1, 1]); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/model/Model + */ + + var mixin$1 = mixin; + var inner = makeInner(); + + /** + * @alias module:echarts/model/Model + * @constructor + * @param {Object} option + * @param {module:echarts/model/Model} [parentModel] + * @param {module:echarts/model/Global} [ecModel] + */ + function Model(option, parentModel, ecModel) { + /** + * @type {module:echarts/model/Model} + * @readOnly + */ + this.parentModel = parentModel; + + /** + * @type {module:echarts/model/Global} + * @readOnly + */ + this.ecModel = ecModel; + + /** + * @type {Object} + * @protected + */ + this.option = option; + + // Simple optimization + // if (this.init) { + // if (arguments.length <= 4) { + // this.init(option, parentModel, ecModel, extraOpt); + // } + // else { + // this.init.apply(this, arguments); + // } + // } + } + + Model.prototype = { + + constructor: Model, + + /** + * Model 的初始化函数 + * @param {Object} option + */ + init: null, + + /** + * 从新的 Option merge + */ + mergeOption: function(option) { + merge(this.option, option, true); + }, + + /** + * @param {string|Array.} path + * @param {boolean} [ignoreParent=false] + * @return {*} + */ + get: function(path, ignoreParent) { + if (path == null) { + return this.option; + } + + return doGet( + this.option, + this.parsePath(path), + !ignoreParent && getParent(this, path) + ); + }, + + /** + * @param {string} key + * @param {boolean} [ignoreParent=false] + * @return {*} + */ + getShallow: function(key, ignoreParent) { + var option = this.option; + + var val = option == null ? option : option[key]; + var parentModel = !ignoreParent && getParent(this, key); + if (val == null && parentModel) { + val = parentModel.getShallow(key); + } + return val; + }, + + /** + * @param {string|Array.} [path] + * @param {module:echarts/model/Model} [parentModel] + * @return {module:echarts/model/Model} + */ + getModel: function(path, parentModel) { + var obj = path == null ? + this.option : + doGet(this.option, path = this.parsePath(path)); + + var thisParentModel; + parentModel = parentModel || ( + (thisParentModel = getParent(this, path)) && + thisParentModel.getModel(path) + ); + + return new Model(obj, parentModel, this.ecModel); + }, + + /** + * If model has option + */ + isEmpty: function() { + return this.option == null; + }, + + restoreData: function() {}, + + // Pending + clone: function() { + var Ctor = this.constructor; + return new Ctor(clone(this.option)); + }, + + setReadOnly: function(properties) { + // clazzUtil.setReadOnly(this, properties); + }, + + // If path is null/undefined, return null/undefined. + parsePath: function(path) { + if (typeof path === 'string') { + path = path.split('.'); + } + return path; + }, + + /** + * @param {Function} getParentMethod + * param {Array.|string} path + * return {module:echarts/model/Model} + */ + customizeGetParent: function(getParentMethod) { + inner(this).getParent = getParentMethod; + }, + + isAnimationEnabled: function() { + if (!env$1.node) { + if (this.option.animation != null) { + return !!this.option.animation; + } else if (this.parentModel) { + return this.parentModel.isAnimationEnabled(); + } + } + } + + }; + + function doGet(obj, pathArr, parentModel) { + for (var i = 0; i < pathArr.length; i++) { + // Ignore empty + if (!pathArr[i]) { + continue; + } + // obj could be number/string/... (like 0) + obj = (obj && typeof obj === 'object') ? obj[pathArr[i]] : null; + if (obj == null) { + break; + } + } + if (obj == null && parentModel) { + obj = parentModel.get(pathArr); + } + return obj; + } + + // `path` can be null/undefined + function getParent(model, path) { + var getParentMethod = inner(model).getParent; + return getParentMethod ? getParentMethod.call(model, path) : model.parentModel; + } + + // Enable Model.extend. + enableClassExtend(Model); + enableClassCheck(Model); + + mixin$1(Model, lineStyleMixin); + mixin$1(Model, areaStyleMixin); + mixin$1(Model, textStyleMixin); + mixin$1(Model, itemStyleMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var base = 0; + + /** + * @public + * @param {string} type + * @return {string} + */ + function getUID(type) { + // Considering the case of crossing js context, + // use Math.random to make id as unique as possible. + return [(type || ''), base++, Math.random().toFixed(5)].join('_'); + } + + /** + * @inner + */ + function enableSubTypeDefaulter(entity) { + + var subTypeDefaulters = {}; + + entity.registerSubTypeDefaulter = function(componentType, defaulter) { + componentType = parseClassType$1(componentType); + subTypeDefaulters[componentType.main] = defaulter; + }; + + entity.determineSubType = function(componentType, option) { + var type = option.type; + if (!type) { + var componentTypeMain = parseClassType$1(componentType).main; + if (entity.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) { + type = subTypeDefaulters[componentTypeMain](option); + } + } + return type; + }; + + return entity; + } + + /** + * Topological travel on Activity Network (Activity On Vertices). + * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis']. + * + * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology. + * + * If there is circle dependencey, Error will be thrown. + * + */ + function enableTopologicalTravel(entity, dependencyGetter) { + + /** + * @public + * @param {Array.} targetNameList Target Component type list. + * Can be ['aa', 'bb', 'aa.xx'] + * @param {Array.} fullNameList By which we can build dependency graph. + * @param {Function} callback Params: componentType, dependencies. + * @param {Object} context Scope of callback. + */ + entity.topologicalTravel = function(targetNameList, fullNameList, callback, context) { + if (!targetNameList.length) { + return; + } + + var result = makeDepndencyGraph(fullNameList); + var graph = result.graph; + var stack = result.noEntryList; + + var targetNameSet = {}; + each$1(targetNameList, function(name) { + targetNameSet[name] = true; + }); + + while (stack.length) { + var currComponentType = stack.pop(); + var currVertex = graph[currComponentType]; + var isInTargetNameSet = !!targetNameSet[currComponentType]; + if (isInTargetNameSet) { + callback.call(context, currComponentType, currVertex.originalDeps.slice()); + delete targetNameSet[currComponentType]; + } + each$1( + currVertex.successor, + isInTargetNameSet ? removeEdgeAndAdd : removeEdge + ); + } + + each$1(targetNameSet, function() { + throw new Error('Circle dependency may exists'); + }); + + function removeEdge(succComponentType) { + graph[succComponentType].entryCount--; + if (graph[succComponentType].entryCount === 0) { + stack.push(succComponentType); + } + } + + // Consider this case: legend depends on series, and we call + // chart.setOption({series: [...]}), where only series is in option. + // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will + // not be called, but only sereis.mergeOption is called. Thus legend + // have no chance to update its local record about series (like which + // name of series is available in legend). + function removeEdgeAndAdd(succComponentType) { + targetNameSet[succComponentType] = true; + removeEdge(succComponentType); + } + }; + + /** + * DepndencyGraph: {Object} + * key: conponentType, + * value: { + * successor: [conponentTypes...], + * originalDeps: [conponentTypes...], + * entryCount: {number} + * } + */ + function makeDepndencyGraph(fullNameList) { + var graph = {}; + var noEntryList = []; + + each$1(fullNameList, function(name) { + + var thisItem = createDependencyGraphItem(graph, name); + var originalDeps = thisItem.originalDeps = dependencyGetter(name); + + var availableDeps = getAvailableDependencies(originalDeps, fullNameList); + thisItem.entryCount = availableDeps.length; + if (thisItem.entryCount === 0) { + noEntryList.push(name); + } + + each$1(availableDeps, function(dependentName) { + if (indexOf(thisItem.predecessor, dependentName) < 0) { + thisItem.predecessor.push(dependentName); + } + var thatItem = createDependencyGraphItem(graph, dependentName); + if (indexOf(thatItem.successor, dependentName) < 0) { + thatItem.successor.push(name); + } + }); + }); + + return { + graph: graph, + noEntryList: noEntryList + }; + } + + function createDependencyGraphItem(graph, name) { + if (!graph[name]) { + graph[name] = { + predecessor: [], + successor: [] + }; + } + return graph[name]; + } + + function getAvailableDependencies(originalDeps, fullNameList) { + var availableDeps = []; + each$1(originalDeps, function(dep) { + indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep); + }); + return availableDeps; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var RADIAN_EPSILON = 1e-4; + + function _trim(str) { + return str.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + /** + * Linear mapping a value from domain to range + * @memberOf module:echarts/util/number + * @param {(number|Array.)} val + * @param {Array.} domain Domain extent domain[0] can be bigger than domain[1] + * @param {Array.} range Range extent range[0] can be bigger than range[1] + * @param {boolean} clamp + * @return {(number|Array.} + */ + function linearMap(val, domain, range, clamp) { + var subDomain = domain[1] - domain[0]; + var subRange = range[1] - range[0]; + + if (subDomain === 0) { + return subRange === 0 ? + range[0] : + (range[0] + range[1]) / 2; + } + + // Avoid accuracy problem in edge, such as + // 146.39 - 62.83 === 83.55999999999999. + // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError + // It is a little verbose for efficiency considering this method + // is a hotspot. + if (clamp) { + if (subDomain > 0) { + if (val <= domain[0]) { + return range[0]; + } else if (val >= domain[1]) { + return range[1]; + } + } else { + if (val >= domain[0]) { + return range[0]; + } else if (val <= domain[1]) { + return range[1]; + } + } + } else { + if (val === domain[0]) { + return range[0]; + } + if (val === domain[1]) { + return range[1]; + } + } + + return (val - domain[0]) / subDomain * subRange + range[0]; + } + + /** + * Convert a percent string to absolute number. + * Returns NaN if percent is not a valid string or number + * @memberOf module:echarts/util/number + * @param {string|number} percent + * @param {number} all + * @return {number} + */ + function parsePercent$1(percent, all) { + switch (percent) { + case 'center': + case 'middle': + percent = '50%'; + break; + case 'left': + case 'top': + percent = '0%'; + break; + case 'right': + case 'bottom': + percent = '100%'; + break; + } + if (typeof percent === 'string') { + if (_trim(percent).match(/%$/)) { + return parseFloat(percent) / 100 * all; + } + + return parseFloat(percent); + } + + return percent == null ? NaN : +percent; + } + + /** + * (1) Fix rounding error of float numbers. + * (2) Support return string to avoid scientific notation like '3.5e-7'. + * + * @param {number} x + * @param {number} [precision] + * @param {boolean} [returnStr] + * @return {number|string} + */ + function round$1(x, precision, returnStr) { + if (precision == null) { + precision = 10; + } + // Avoid range error + precision = Math.min(Math.max(0, precision), 20); + x = (+x).toFixed(precision); + return returnStr ? x : +x; + } + + function asc(arr) { + arr.sort(function(a, b) { + return a - b; + }); + return arr; + } + + /** + * Get precision + * @param {number} val + */ + function getPrecision(val) { + val = +val; + if (isNaN(val)) { + return 0; + } + // It is much faster than methods converting number to string as follows + // var tmp = val.toString(); + // return tmp.length - 1 - tmp.indexOf('.'); + // especially when precision is low + var e = 1; + var count = 0; + while (Math.round(val * e) / e !== val) { + e *= 10; + count++; + } + return count; + } + + /** + * @param {string|number} val + * @return {number} + */ + function getPrecisionSafe(val) { + var str = val.toString(); + + // Consider scientific notation: '3.4e-12' '3.4e+12' + var eIndex = str.indexOf('e'); + if (eIndex > 0) { + var precision = +str.slice(eIndex + 1); + return precision < 0 ? -precision : 0; + } else { + var dotIndex = str.indexOf('.'); + return dotIndex < 0 ? 0 : str.length - 1 - dotIndex; + } + } + + /** + * Minimal dicernible data precisioin according to a single pixel. + * + * @param {Array.} dataExtent + * @param {Array.} pixelExtent + * @return {number} precision + */ + function getPixelPrecision(dataExtent, pixelExtent) { + var log = Math.log; + var LN10 = Math.LN10; + var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10); + var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); + // toFixed() digits argument must be between 0 and 20. + var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20); + return !isFinite(precision) ? 20 : precision; + } + + /** + * Get a data of given precision, assuring the sum of percentages + * in valueList is 1. + * The largest remainer method is used. + * https://en.wikipedia.org/wiki/Largest_remainder_method + * + * @param {Array.} valueList a list of all data + * @param {number} idx index of the data to be processed in valueList + * @param {number} precision integer number showing digits of precision + * @return {number} percent ranging from 0 to 100 + */ + function getPercentWithPrecision(valueList, idx, precision) { + if (!valueList[idx]) { + return 0; + } + + var sum = reduce(valueList, function(acc, val) { + return acc + (isNaN(val) ? 0 : val); + }, 0); + if (sum === 0) { + return 0; + } + + var digits = Math.pow(10, precision); + var votesPerQuota = map(valueList, function(val) { + return (isNaN(val) ? 0 : val) / sum * digits * 100; + }); + var targetSeats = digits * 100; + + var seats = map(votesPerQuota, function(votes) { + // Assign automatic seats. + return Math.floor(votes); + }); + var currentSum = reduce(seats, function(acc, val) { + return acc + val; + }, 0); + + var remainder = map(votesPerQuota, function(votes, idx) { + return votes - seats[idx]; + }); + + // Has remainding votes. + while (currentSum < targetSeats) { + // Find next largest remainder. + var max = Number.NEGATIVE_INFINITY; + var maxId = null; + for (var i = 0, len = remainder.length; i < len; ++i) { + if (remainder[i] > max) { + max = remainder[i]; + maxId = i; + } + } + + // Add a vote to max remainder. + ++seats[maxId]; + remainder[maxId] = 0; + ++currentSum; + } + + return seats[idx] / digits; + } + + // Number.MAX_SAFE_INTEGER, ie do not support. + var MAX_SAFE_INTEGER = 9007199254740991; + + /** + * To 0 - 2 * PI, considering negative radian. + * @param {number} radian + * @return {number} + */ + function remRadian(radian) { + var pi2 = Math.PI * 2; + return (radian % pi2 + pi2) % pi2; + } + + /** + * @param {type} radian + * @return {boolean} + */ + function isRadianAroundZero(val) { + return val > -RADIAN_EPSILON && val < RADIAN_EPSILON; + } + + var TIME_REG = + /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line + + /** + * @param {string|Date|number} value These values can be accepted: + * + An instance of Date, represent a time in its own time zone. + * + Or string in a subset of ISO 8601, only including: + * + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06', + * + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123', + * + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00', + * all of which will be treated as local time if time zone is not specified + * (see ). + * + Or other string format, including (all of which will be treated as loacal time): + * '2012', '2012-3-1', '2012/3/1', '2012/03/01', + * '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123' + * + a timestamp, which represent a time in UTC. + * @return {Date} date + */ + function parseDate(value) { + if (value instanceof Date) { + return value; + } else if (typeof value === 'string') { + // Different browsers parse date in different way, so we parse it manually. + // Some other issues: + // new Date('1970-01-01') is UTC, + // new Date('1970/01/01') and new Date('1970-1-01') is local. + // See issue #3623 + var match = TIME_REG.exec(value); + + if (!match) { + // return Invalid Date. + return new Date(NaN); + } + + // Use local time when no timezone offset specifed. + if (!match[8]) { + // match[n] can only be string or undefined. + // But take care of '12' + 1 => '121'. + return new Date( + +match[1], + +(match[2] || 1) - 1, + +match[3] || 1, + +match[4] || 0, + +(match[5] || 0), + +match[6] || 0, + +match[7] || 0 + ); + } + // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time, + // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment). + // For example, system timezone is set as "Time Zone: America/Toronto", + // then these code will get different result: + // `new Date(1478411999999).getTimezoneOffset(); // get 240` + // `new Date(1478412000000).getTimezoneOffset(); // get 300` + // So we should not use `new Date`, but use `Date.UTC`. + else { + var hour = +match[4] || 0; + if (match[8].toUpperCase() !== 'Z') { + hour -= match[8].slice(0, 3); + } + return new Date(Date.UTC( + +match[1], + +(match[2] || 1) - 1, + +match[3] || 1, + hour, + +(match[5] || 0), + +match[6] || 0, + +match[7] || 0 + )); + } + } else if (value == null) { + return new Date(NaN); + } + + return new Date(Math.round(value)); + } + + /** + * Quantity of a number. e.g. 0.1, 1, 10, 100 + * + * @param {number} val + * @return {number} + */ + function quantity(val) { + return Math.pow(10, quantityExponent(val)); + } + + function quantityExponent(val) { + return Math.floor(Math.log(val) / Math.LN10); + } + + /** + * find a “nice” number approximately equal to x. Round the number if round = true, + * take ceiling if round = false. The primary observation is that the “nicest” + * numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers. + * + * See "Nice Numbers for Graph Labels" of Graphic Gems. + * + * @param {number} val Non-negative value. + * @param {boolean} round + * @return {number} + */ + function nice(val, round) { + var exponent = quantityExponent(val); + var exp10 = Math.pow(10, exponent); + var f = val / exp10; // 1 <= f < 10 + var nf; + if (round) { + if (f < 1.5) { + nf = 1; + } else if (f < 2.5) { + nf = 2; + } else if (f < 4) { + nf = 3; + } else if (f < 7) { + nf = 5; + } else { + nf = 10; + } + } else { + if (f < 1) { + nf = 1; + } else if (f < 2) { + nf = 2; + } else if (f < 3) { + nf = 3; + } else if (f < 5) { + nf = 5; + } else { + nf = 10; + } + } + val = nf * exp10; + + // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754). + // 20 is the uppper bound of toFixed. + return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val; + } + + /** + * BSD 3-Clause + * + * Copyright (c) 2010-2015, Michael Bostock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * The name Michael Bostock may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /** + * @see + * @see + * @param {Array.} ascArr + */ + function quantile(ascArr, p) { + var H = (ascArr.length - 1) * p + 1; + var h = Math.floor(H); + var v = +ascArr[h - 1]; + var e = H - h; + return e ? v + e * (ascArr[h] - v) : v; + } + + /** + * Order intervals asc, and split them when overlap. + * expect(numberUtil.reformIntervals([ + * {interval: [18, 62], close: [1, 1]}, + * {interval: [-Infinity, -70], close: [0, 0]}, + * {interval: [-70, -26], close: [1, 1]}, + * {interval: [-26, 18], close: [1, 1]}, + * {interval: [62, 150], close: [1, 1]}, + * {interval: [106, 150], close: [1, 1]}, + * {interval: [150, Infinity], close: [0, 0]} + * ])).toEqual([ + * {interval: [-Infinity, -70], close: [0, 0]}, + * {interval: [-70, -26], close: [1, 1]}, + * {interval: [-26, 18], close: [0, 1]}, + * {interval: [18, 62], close: [0, 1]}, + * {interval: [62, 150], close: [0, 1]}, + * {interval: [150, Infinity], close: [0, 0]} + * ]); + * @param {Array.} list, where `close` mean open or close + * of the interval, and Infinity can be used. + * @return {Array.} The origin list, which has been reformed. + */ + function reformIntervals(list) { + list.sort(function(a, b) { + return littleThan(a, b, 0) ? -1 : 1; + }); + + var curr = -Infinity; + var currClose = 1; + for (var i = 0; i < list.length;) { + var interval = list[i].interval; + var close = list[i].close; + + for (var lg = 0; lg < 2; lg++) { + if (interval[lg] <= curr) { + interval[lg] = curr; + close[lg] = !lg ? 1 - currClose : 1; + } + curr = interval[lg]; + currClose = close[lg]; + } + + if (interval[0] === interval[1] && close[0] * close[1] !== 1) { + list.splice(i, 1); + } else { + i++; + } + } + + return list; + + function littleThan(a, b, lg) { + return a.interval[lg] < b.interval[lg] || + ( + a.interval[lg] === b.interval[lg] && + ( + (a.close[lg] - b.close[lg] === (!lg ? 1 : -1)) || + (!lg && littleThan(a, b, 1)) + ) + ); + } + } + + /** + * parseFloat NaNs numeric-cast false positives (null|true|false|"") + * ...but misinterprets leading-number strings, particularly hex literals ("0x...") + * subtraction forces infinities to NaN + * + * @param {*} v + * @return {boolean} + */ + function isNumeric(v) { + return v - parseFloat(v) >= 0; + } + + + var number = (Object.freeze || Object)({ + linearMap: linearMap, + parsePercent: parsePercent$1, + round: round$1, + asc: asc, + getPrecision: getPrecision, + getPrecisionSafe: getPrecisionSafe, + getPixelPrecision: getPixelPrecision, + getPercentWithPrecision: getPercentWithPrecision, + MAX_SAFE_INTEGER: MAX_SAFE_INTEGER, + remRadian: remRadian, + isRadianAroundZero: isRadianAroundZero, + parseDate: parseDate, + quantity: quantity, + nice: nice, + quantile: quantile, + reformIntervals: reformIntervals, + isNumeric: isNumeric + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * 每三位默认加,格式化 + * @param {string|number} x + * @return {string} + */ + function addCommas(x) { + if (isNaN(x)) { + return '-'; + } + x = (x + '').split('.'); + return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + + (x.length > 1 ? ('.' + x[1]) : ''); + } + + /** + * @param {string} str + * @param {boolean} [upperCaseFirst=false] + * @return {string} str + */ + function toCamelCase(str, upperCaseFirst) { + str = (str || '').toLowerCase().replace(/-(.)/g, function(match, group1) { + return group1.toUpperCase(); + }); + + if (upperCaseFirst && str) { + str = str.charAt(0).toUpperCase() + str.slice(1); + } + + return str; + } + + var normalizeCssArray$1 = normalizeCssArray; + + + var replaceReg = /([&<>"'])/g; + var replaceMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''' + }; + + function encodeHTML(source) { + return source == null ? + '' : + (source + '').replace(replaceReg, function(str, c) { + return replaceMap[c]; + }); + } + + var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; + + var wrapVar = function(varName, seriesIdx) { + return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}'; + }; + + /** + * Template formatter + * @param {string} tpl + * @param {Array.|Object} paramsList + * @param {boolean} [encode=false] + * @return {string} + */ + function formatTpl(tpl, paramsList, encode) { + if (!isArray(paramsList)) { + paramsList = [paramsList]; + } + var seriesLen = paramsList.length; + if (!seriesLen) { + return ''; + } + + var $vars = paramsList[0].$vars || []; + for (var i = 0; i < $vars.length; i++) { + var alias = TPL_VAR_ALIAS[i]; + tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0)); + } + for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) { + for (var k = 0; k < $vars.length; k++) { + var val = paramsList[seriesIdx][$vars[k]]; + tpl = tpl.replace( + wrapVar(TPL_VAR_ALIAS[k], seriesIdx), + encode ? encodeHTML(val) : val + ); + } + } + + return tpl; + } + + /** + * simple Template formatter + * + * @param {string} tpl + * @param {Object} param + * @param {boolean} [encode=false] + * @return {string} + */ + function formatTplSimple(tpl, param, encode) { + each$1(param, function(value, key) { + tpl = tpl.replace( + '{' + key + '}', + encode ? encodeHTML(value) : value + ); + }); + return tpl; + } + + /** + * @param {Object|string} [opt] If string, means color. + * @param {string} [opt.color] + * @param {string} [opt.extraCssText] + * @param {string} [opt.type='item'] 'item' or 'subItem' + * @return {string} + */ + function getTooltipMarker(opt, extraCssText) { + opt = isString(opt) ? { + color: opt, + extraCssText: extraCssText + } : (opt || {}); + var color = opt.color; + var type = opt.type; + var extraCssText = opt.extraCssText; + + if (!color) { + return ''; + } + + return type === 'subItem' ? + '' : + ''; + } + + function pad(str, len) { + str += ''; + return '0000'.substr(0, len - str.length) + str; + } + + + /** + * ISO Date format + * @param {string} tpl + * @param {number} value + * @param {boolean} [isUTC=false] Default in local time. + * see `module:echarts/scale/Time` + * and `module:echarts/util/number#parseDate`. + * @inner + */ + function formatTime(tpl, value, isUTC) { + if (tpl === 'week' || + tpl === 'month' || + tpl === 'quarter' || + tpl === 'half-year' || + tpl === 'year' + ) { + tpl = 'MM-dd\nyyyy'; + } + + var date = parseDate(value); + var utc = isUTC ? 'UTC' : ''; + var y = date['get' + utc + 'FullYear'](); + var M = date['get' + utc + 'Month']() + 1; + var d = date['get' + utc + 'Date'](); + var h = date['get' + utc + 'Hours'](); + var m = date['get' + utc + 'Minutes'](); + var s = date['get' + utc + 'Seconds'](); + var S = date['get' + utc + 'Milliseconds'](); + + tpl = tpl.replace('MM', pad(M, 2)) + .replace('M', M) + .replace('yyyy', y) + .replace('yy', y % 100) + .replace('dd', pad(d, 2)) + .replace('d', d) + .replace('hh', pad(h, 2)) + .replace('h', h) + .replace('mm', pad(m, 2)) + .replace('m', m) + .replace('ss', pad(s, 2)) + .replace('s', s) + .replace('SSS', pad(S, 3)); + + return tpl; + } + + /** + * Capital first + * @param {string} str + * @return {string} + */ + function capitalFirst(str) { + return str ? str.charAt(0).toUpperCase() + str.substr(1) : str; + } + + var truncateText$1 = truncateText; + + var getTextRect = getBoundingRect; + + + var format = (Object.freeze || Object)({ + addCommas: addCommas, + toCamelCase: toCamelCase, + normalizeCssArray: normalizeCssArray$1, + encodeHTML: encodeHTML, + formatTpl: formatTpl, + formatTplSimple: formatTplSimple, + getTooltipMarker: getTooltipMarker, + formatTime: formatTime, + capitalFirst: capitalFirst, + truncateText: truncateText$1, + getTextRect: getTextRect + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Layout helpers for each component positioning + + var each$3 = each$1; + + /** + * @public + */ + var LOCATION_PARAMS = [ + 'left', 'right', 'top', 'bottom', 'width', 'height' + ]; + + /** + * @public + */ + var HV_NAMES = [ + ['width', 'left', 'right'], + ['height', 'top', 'bottom'] + ]; + + function boxLayout(orient, group, gap, maxWidth, maxHeight) { + var x = 0; + var y = 0; + + if (maxWidth == null) { + maxWidth = Infinity; + } + if (maxHeight == null) { + maxHeight = Infinity; + } + var currentLineMaxSize = 0; + + group.eachChild(function(child, idx) { + var position = child.position; + var rect = child.getBoundingRect(); + var nextChild = group.childAt(idx + 1); + var nextChildRect = nextChild && nextChild.getBoundingRect(); + var nextX; + var nextY; + + if (orient === 'horizontal') { + var moveX = rect.width + (nextChildRect ? (-nextChildRect.x + rect.x) : 0); + nextX = x + moveX; + // Wrap when width exceeds maxWidth or meet a `newline` group + // FIXME compare before adding gap? + if (nextX > maxWidth || child.newline) { + x = 0; + nextX = moveX; + y += currentLineMaxSize + gap; + currentLineMaxSize = rect.height; + } else { + // FIXME: consider rect.y is not `0`? + currentLineMaxSize = Math.max(currentLineMaxSize, rect.height); + } + } else { + var moveY = rect.height + (nextChildRect ? (-nextChildRect.y + rect.y) : 0); + nextY = y + moveY; + // Wrap when width exceeds maxHeight or meet a `newline` group + if (nextY > maxHeight || child.newline) { + x += currentLineMaxSize + gap; + y = 0; + nextY = moveY; + currentLineMaxSize = rect.width; + } else { + currentLineMaxSize = Math.max(currentLineMaxSize, rect.width); + } + } + + if (child.newline) { + return; + } + + position[0] = x; + position[1] = y; + + orient === 'horizontal' ? + (x = nextX + gap) : + (y = nextY + gap); + }); + } + + /** + * VBox or HBox layouting + * @param {string} orient + * @param {module:zrender/container/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var box = boxLayout; + + /** + * VBox layouting + * @param {module:zrender/container/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var vbox = curry(boxLayout, 'vertical'); + + /** + * HBox layouting + * @param {module:zrender/container/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var hbox = curry(boxLayout, 'horizontal'); + + /** + * If x or x2 is not specified or 'center' 'left' 'right', + * the width would be as long as possible. + * If y or y2 is not specified or 'middle' 'top' 'bottom', + * the height would be as long as possible. + * + * @param {Object} positionInfo + * @param {number|string} [positionInfo.x] + * @param {number|string} [positionInfo.y] + * @param {number|string} [positionInfo.x2] + * @param {number|string} [positionInfo.y2] + * @param {Object} containerRect {width, height} + * @param {string|number} margin + * @return {Object} {width, height} + */ + function getAvailableSize(positionInfo, containerRect, margin) { + var containerWidth = containerRect.width; + var containerHeight = containerRect.height; + + var x = parsePercent$1(positionInfo.x, containerWidth); + var y = parsePercent$1(positionInfo.y, containerHeight); + var x2 = parsePercent$1(positionInfo.x2, containerWidth); + var y2 = parsePercent$1(positionInfo.y2, containerHeight); + + (isNaN(x) || isNaN(parseFloat(positionInfo.x))) && (x = 0); + (isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) && (x2 = containerWidth); + (isNaN(y) || isNaN(parseFloat(positionInfo.y))) && (y = 0); + (isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) && (y2 = containerHeight); + + margin = normalizeCssArray$1(margin || 0); + + return { + width: Math.max(x2 - x - margin[1] - margin[3], 0), + height: Math.max(y2 - y - margin[0] - margin[2], 0) + }; + } + + /** + * Parse position info. + * + * @param {Object} positionInfo + * @param {number|string} [positionInfo.left] + * @param {number|string} [positionInfo.top] + * @param {number|string} [positionInfo.right] + * @param {number|string} [positionInfo.bottom] + * @param {number|string} [positionInfo.width] + * @param {number|string} [positionInfo.height] + * @param {number|string} [positionInfo.aspect] Aspect is width / height + * @param {Object} containerRect + * @param {string|number} [margin] + * + * @return {module:zrender/core/BoundingRect} + */ + function getLayoutRect( + positionInfo, containerRect, margin + ) { + margin = normalizeCssArray$1(margin || 0); + + var containerWidth = containerRect.width; + var containerHeight = containerRect.height; + + var left = parsePercent$1(positionInfo.left, containerWidth); + var top = parsePercent$1(positionInfo.top, containerHeight); + var right = parsePercent$1(positionInfo.right, containerWidth); + var bottom = parsePercent$1(positionInfo.bottom, containerHeight); + var width = parsePercent$1(positionInfo.width, containerWidth); + var height = parsePercent$1(positionInfo.height, containerHeight); + + var verticalMargin = margin[2] + margin[0]; + var horizontalMargin = margin[1] + margin[3]; + var aspect = positionInfo.aspect; + + // If width is not specified, calculate width from left and right + if (isNaN(width)) { + width = containerWidth - right - horizontalMargin - left; + } + if (isNaN(height)) { + height = containerHeight - bottom - verticalMargin - top; + } + + if (aspect != null) { + // If width and height are not given + // 1. Graph should not exceeds the container + // 2. Aspect must be keeped + // 3. Graph should take the space as more as possible + // FIXME + // Margin is not considered, because there is no case that both + // using margin and aspect so far. + if (isNaN(width) && isNaN(height)) { + if (aspect > containerWidth / containerHeight) { + width = containerWidth * 0.8; + } else { + height = containerHeight * 0.8; + } + } + + // Calculate width or height with given aspect + if (isNaN(width)) { + width = aspect * height; + } + if (isNaN(height)) { + height = width / aspect; + } + } + + // If left is not specified, calculate left from right and width + if (isNaN(left)) { + left = containerWidth - right - width - horizontalMargin; + } + if (isNaN(top)) { + top = containerHeight - bottom - height - verticalMargin; + } + + // Align left and top + switch (positionInfo.left || positionInfo.right) { + case 'center': + left = containerWidth / 2 - width / 2 - margin[3]; + break; + case 'right': + left = containerWidth - width - horizontalMargin; + break; + } + switch (positionInfo.top || positionInfo.bottom) { + case 'middle': + case 'center': + top = containerHeight / 2 - height / 2 - margin[0]; + break; + case 'bottom': + top = containerHeight - height - verticalMargin; + break; + } + // If something is wrong and left, top, width, height are calculated as NaN + left = left || 0; + top = top || 0; + if (isNaN(width)) { + // Width may be NaN if only one value is given except width + width = containerWidth - horizontalMargin - left - (right || 0); + } + if (isNaN(height)) { + // Height may be NaN if only one value is given except height + height = containerHeight - verticalMargin - top - (bottom || 0); + } + + var rect = new BoundingRect(left + margin[3], top + margin[0], width, height); + rect.margin = margin; + return rect; + } + + + /** + * Position a zr element in viewport + * Group position is specified by either + * {left, top}, {right, bottom} + * If all properties exists, right and bottom will be igonred. + * + * Logic: + * 1. Scale (against origin point in parent coord) + * 2. Rotate (against origin point in parent coord) + * 3. Traslate (with el.position by this method) + * So this method only fixes the last step 'Traslate', which does not affect + * scaling and rotating. + * + * If be called repeatly with the same input el, the same result will be gotten. + * + * @param {module:zrender/Element} el Should have `getBoundingRect` method. + * @param {Object} positionInfo + * @param {number|string} [positionInfo.left] + * @param {number|string} [positionInfo.top] + * @param {number|string} [positionInfo.right] + * @param {number|string} [positionInfo.bottom] + * @param {number|string} [positionInfo.width] Only for opt.boundingModel: 'raw' + * @param {number|string} [positionInfo.height] Only for opt.boundingModel: 'raw' + * @param {Object} containerRect + * @param {string|number} margin + * @param {Object} [opt] + * @param {Array.} [opt.hv=[1,1]] Only horizontal or only vertical. + * @param {Array.} [opt.boundingMode='all'] + * Specify how to calculate boundingRect when locating. + * 'all': Position the boundingRect that is transformed and uioned + * both itself and its descendants. + * This mode simplies confine the elements in the bounding + * of their container (e.g., using 'right: 0'). + * 'raw': Position the boundingRect that is not transformed and only itself. + * This mode is useful when you want a element can overflow its + * container. (Consider a rotated circle needs to be located in a corner.) + * In this mode positionInfo.width/height can only be number. + */ + function positionElement(el, positionInfo, containerRect, margin, opt) { + var h = !opt || !opt.hv || opt.hv[0]; + var v = !opt || !opt.hv || opt.hv[1]; + var boundingMode = opt && opt.boundingMode || 'all'; + + if (!h && !v) { + return; + } + + var rect; + if (boundingMode === 'raw') { + rect = el.type === 'group' ? + new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : + el.getBoundingRect(); + } else { + rect = el.getBoundingRect(); + if (el.needLocalTransform()) { + var transform = el.getLocalTransform(); + // Notice: raw rect may be inner object of el, + // which should not be modified. + rect = rect.clone(); + rect.applyTransform(transform); + } + } + + // The real width and height can not be specified but calculated by the given el. + positionInfo = getLayoutRect( + defaults({ + width: rect.width, + height: rect.height + }, + positionInfo + ), + containerRect, + margin + ); + + // Because 'tranlate' is the last step in transform + // (see zrender/core/Transformable#getLocalTransform), + // we can just only modify el.position to get final result. + var elPos = el.position; + var dx = h ? positionInfo.x - rect.x : 0; + var dy = v ? positionInfo.y - rect.y : 0; + + el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]); + } + + /** + * @param {Object} option Contains some of the properties in HV_NAMES. + * @param {number} hvIdx 0: horizontal; 1: vertical. + */ + function sizeCalculable(option, hvIdx) { + return option[HV_NAMES[hvIdx][0]] != null || + (option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null); + } + + /** + * Consider Case: + * When defulat option has {left: 0, width: 100}, and we set {right: 0} + * through setOption or media query, using normal zrUtil.merge will cause + * {right: 0} does not take effect. + * + * @example + * ComponentModel.extend({ + * init: function () { + * ... + * var inputPositionParams = layout.getLayoutParams(option); + * this.mergeOption(inputPositionParams); + * }, + * mergeOption: function (newOption) { + * newOption && zrUtil.merge(thisOption, newOption, true); + * layout.mergeLayoutParam(thisOption, newOption); + * } + * }); + * + * @param {Object} targetOption + * @param {Object} newOption + * @param {Object|string} [opt] + * @param {boolean|Array.} [opt.ignoreSize=false] Used for the components + * that width (or height) should not be calculated by left and right (or top and bottom). + */ + function mergeLayoutParam(targetOption, newOption, opt) { + !isObject$1(opt) && (opt = {}); + + var ignoreSize = opt.ignoreSize; + !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]); + + var hResult = merge$$1(HV_NAMES[0], 0); + var vResult = merge$$1(HV_NAMES[1], 1); + + copy(HV_NAMES[0], targetOption, hResult); + copy(HV_NAMES[1], targetOption, vResult); + + function merge$$1(names, hvIdx) { + var newParams = {}; + var newValueCount = 0; + var merged = {}; + var mergedValueCount = 0; + var enoughParamNumber = 2; + + each$3(names, function(name) { + merged[name] = targetOption[name]; + }); + each$3(names, function(name) { + // Consider case: newOption.width is null, which is + // set by user for removing width setting. + hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]); + hasValue(newParams, name) && newValueCount++; + hasValue(merged, name) && mergedValueCount++; + }); + + if (ignoreSize[hvIdx]) { + // Only one of left/right is premitted to exist. + if (hasValue(newOption, names[1])) { + merged[names[2]] = null; + } else if (hasValue(newOption, names[2])) { + merged[names[1]] = null; + } + return merged; + } + + // Case: newOption: {width: ..., right: ...}, + // or targetOption: {right: ...} and newOption: {width: ...}, + // There is no conflict when merged only has params count + // little than enoughParamNumber. + if (mergedValueCount === enoughParamNumber || !newValueCount) { + return merged; + } + // Case: newOption: {width: ..., right: ...}, + // Than we can make sure user only want those two, and ignore + // all origin params in targetOption. + else if (newValueCount >= enoughParamNumber) { + return newParams; + } else { + // Chose another param from targetOption by priority. + for (var i = 0; i < names.length; i++) { + var name = names[i]; + if (!hasProp(newParams, name) && hasProp(targetOption, name)) { + newParams[name] = targetOption[name]; + break; + } + } + return newParams; + } + } + + function hasProp(obj, name) { + return obj.hasOwnProperty(name); + } + + function hasValue(obj, name) { + return obj[name] != null && obj[name] !== 'auto'; + } + + function copy(names, target, source) { + each$3(names, function(name) { + target[name] = source[name]; + }); + } + } + + /** + * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object. + * @param {Object} source + * @return {Object} Result contains those props. + */ + function getLayoutParams(source) { + return copyLayoutParams({}, source); + } + + /** + * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object. + * @param {Object} source + * @return {Object} Result contains those props. + */ + function copyLayoutParams(target, source) { + source && target && each$3(LOCATION_PARAMS, function(name) { + source.hasOwnProperty(name) && (target[name] = source[name]); + }); + return target; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var boxLayoutMixin = { + getBoxLayoutParams: function() { + return { + left: this.get('left'), + top: this.get('top'), + right: this.get('right'), + bottom: this.get('bottom'), + width: this.get('width'), + height: this.get('height') + }; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Component model + * + * @module echarts/model/Component + */ + + var inner$1 = makeInner(); + + /** + * @alias module:echarts/model/Component + * @constructor + * @param {Object} option + * @param {module:echarts/model/Model} parentModel + * @param {module:echarts/model/Model} ecModel + */ + var ComponentModel = Model.extend({ + + type: 'component', + + /** + * @readOnly + * @type {string} + */ + id: '', + + /** + * Because simplified concept is probably better, series.name (or component.name) + * has been having too many resposibilities: + * (1) Generating id (which requires name in option should not be modified). + * (2) As an index to mapping series when merging option or calling API (a name + * can refer to more then one components, which is convinient is some case). + * (3) Display. + * @readOnly + */ + name: '', + + /** + * @readOnly + * @type {string} + */ + mainType: '', + + /** + * @readOnly + * @type {string} + */ + subType: '', + + /** + * @readOnly + * @type {number} + */ + componentIndex: 0, + + /** + * @type {Object} + * @protected + */ + defaultOption: null, + + /** + * @type {module:echarts/model/Global} + * @readOnly + */ + ecModel: null, + + /** + * key: componentType + * value: Component model list, can not be null. + * @type {Object.>} + * @readOnly + */ + dependentModels: [], + + /** + * @type {string} + * @readOnly + */ + uid: null, + + /** + * Support merge layout params. + * Only support 'box' now (left/right/top/bottom/width/height). + * @type {string|Object} Object can be {ignoreSize: true} + * @readOnly + */ + layoutMode: null, + + $constructor: function(option, parentModel, ecModel, extraOpt) { + Model.call(this, option, parentModel, ecModel, extraOpt); + + this.uid = getUID('ec_cpt_model'); + }, + + init: function(option, parentModel, ecModel, extraOpt) { + this.mergeDefaultAndTheme(option, ecModel); + }, + + mergeDefaultAndTheme: function(option, ecModel) { + var layoutMode = this.layoutMode; + var inputPositionParams = layoutMode ? + getLayoutParams(option) : {}; + + var themeModel = ecModel.getTheme(); + merge(option, themeModel.get(this.mainType)); + merge(option, this.getDefaultOption()); + + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }, + + mergeOption: function(option, extraOpt) { + merge(this.option, option, true); + + var layoutMode = this.layoutMode; + if (layoutMode) { + mergeLayoutParam(this.option, option, layoutMode); + } + }, + + // Hooker after init or mergeOption + optionUpdated: function(newCptOption, isInit) {}, + + getDefaultOption: function() { + var fields = inner$1(this); + if (!fields.defaultOption) { + var optList = []; + var Class = this.constructor; + while (Class) { + var opt = Class.prototype.defaultOption; + opt && optList.push(opt); + Class = Class.superClass; + } + + var defaultOption = {}; + for (var i = optList.length - 1; i >= 0; i--) { + defaultOption = merge(defaultOption, optList[i], true); + } + fields.defaultOption = defaultOption; + } + return fields.defaultOption; + }, + + getReferringComponents: function(mainType) { + return this.ecModel.queryComponents({ + mainType: mainType, + index: this.get(mainType + 'Index', true), + id: this.get(mainType + 'Id', true) + }); + } + + }); + + // Reset ComponentModel.extend, add preConstruct. + // clazzUtil.enableClassExtend( + // ComponentModel, + // function (option, parentModel, ecModel, extraOpt) { + // // Set dependentModels, componentIndex, name, id, mainType, subType. + // zrUtil.extend(this, extraOpt); + + // this.uid = componentUtil.getUID('componentModel'); + + // // this.setReadOnly([ + // // 'type', 'id', 'uid', 'name', 'mainType', 'subType', + // // 'dependentModels', 'componentIndex' + // // ]); + // } + // ); + + // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on. + enableClassManagement( + ComponentModel, { + registerWhenExtend: true + } + ); + enableSubTypeDefaulter(ComponentModel); + + // Add capability of ComponentModel.topologicalTravel. + enableTopologicalTravel(ComponentModel, getDependencies); + + function getDependencies(componentType) { + var deps = []; + each$1(ComponentModel.getClassesByMainType(componentType), function(Clazz) { + deps = deps.concat(Clazz.prototype.dependencies || []); + }); + + // Ensure main type. + deps = map(deps, function(type) { + return parseClassType$1(type).main; + }); + + // Hack dataset for convenience. + if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) { + deps.unshift('dataset'); + } + + return deps; + } + + mixin(ComponentModel, boxLayoutMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var platform = ''; + // Navigator not exists in node + if (typeof navigator !== 'undefined') { + platform = navigator.platform || ''; + } + + var globalDefault = { + // backgroundColor: 'rgba(0,0,0,0)', + + // https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization + // color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c', '#dd4444', '#d4df5a', '#cd4870'], + // Light colors: + // color: ['#bcd3bb', '#e88f70', '#edc1a5', '#9dc5c8', '#e1e8c8', '#7b7c68', '#e5b5b5', '#f0b489', '#928ea8', '#bda29a'], + // color: ['#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'], + // Dark colors: + color: ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', + '#546570', '#c4ccd3' + ], + + gradientColor: ['#f6efa6', '#d88273', '#bf444c'], + + // If xAxis and yAxis declared, grid is created by default. + // grid: {}, + + textStyle: { + // color: '#000', + // decoration: 'none', + // PENDING + fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif', + // fontFamily: 'Arial, Verdana, sans-serif', + fontSize: 12, + fontStyle: 'normal', + fontWeight: 'normal' + }, + + // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/ + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation + // Default is source-over + blendMode: null, + + animation: 'auto', + animationDuration: 1000, + animationDurationUpdate: 300, + animationEasing: 'exponentialOut', + animationEasingUpdate: 'cubicOut', + + animationThreshold: 2000, + // Configuration for progressive/incremental rendering + progressiveThreshold: 3000, + progressive: 400, + + // Threshold of if use single hover layer to optimize. + // It is recommended that `hoverLayerThreshold` is equivalent to or less than + // `progressiveThreshold`, otherwise hover will cause restart of progressive, + // which is unexpected. + // see example . + hoverLayerThreshold: 3000, + + // See: module:echarts/scale/Time + useUTC: false + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$2 = makeInner(); + + function getNearestColorPalette(colors, requestColorNum) { + var paletteNum = colors.length; + // TODO colors must be in order + for (var i = 0; i < paletteNum; i++) { + if (colors[i].length > requestColorNum) { + return colors[i]; + } + } + return colors[paletteNum - 1]; + } + + var colorPaletteMixin = { + clearColorPalette: function() { + inner$2(this).colorIdx = 0; + inner$2(this).colorNameMap = {}; + }, + + /** + * @param {string} name MUST NOT be null/undefined. Otherwise call this function + * twise with the same parameters will get different result. + * @param {Object} [scope=this] + * @param {Object} [requestColorNum] + * @return {string} color string. + */ + getColorFromPalette: function(name, scope, requestColorNum) { + scope = scope || this; + var scopeFields = inner$2(scope); + var colorIdx = scopeFields.colorIdx || 0; + var colorNameMap = scopeFields.colorNameMap = scopeFields.colorNameMap || {}; + // Use `hasOwnProperty` to avoid conflict with Object.prototype. + if (colorNameMap.hasOwnProperty(name)) { + return colorNameMap[name]; + } + var defaultColorPalette = normalizeToArray(this.get('color', true)); + var layeredColorPalette = this.get('colorLayer', true); + var colorPalette = ((requestColorNum == null || !layeredColorPalette) ? + defaultColorPalette : getNearestColorPalette(layeredColorPalette, requestColorNum)); + + // In case can't find in layered color palette. + colorPalette = colorPalette || defaultColorPalette; + + if (!colorPalette || !colorPalette.length) { + return; + } + + var color = colorPalette[colorIdx]; + if (name) { + colorNameMap[name] = color; + } + scopeFields.colorIdx = (colorIdx + 1) % colorPalette.length; + + return color; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Helper for model references. + * There are many manners to refer axis/coordSys. + */ + + // TODO + // merge relevant logic to this file? + // check: "modelHelper" of tooltip and "BrushTargetManager". + + /** + * @return {Object} For example: + * { + * coordSysName: 'cartesian2d', + * coordSysDims: ['x', 'y', ...], + * axisMap: HashMap({ + * x: xAxisModel, + * y: yAxisModel + * }), + * categoryAxisMap: HashMap({ + * x: xAxisModel, + * y: undefined + * }), + * // It also indicate that whether there is category axis. + * firstCategoryDimIndex: 1, + * // To replace user specified encode. + * } + */ + function getCoordSysDefineBySeries(seriesModel) { + var coordSysName = seriesModel.get('coordinateSystem'); + var result = { + coordSysName: coordSysName, + coordSysDims: [], + axisMap: createHashMap(), + categoryAxisMap: createHashMap() + }; + var fetch = fetchers[coordSysName]; + if (fetch) { + fetch(seriesModel, result, result.axisMap, result.categoryAxisMap); + return result; + } + } + + var fetchers = { + + cartesian2d: function(seriesModel, result, axisMap, categoryAxisMap) { + var xAxisModel = seriesModel.getReferringComponents('xAxis')[0]; + var yAxisModel = seriesModel.getReferringComponents('yAxis')[0]; + + if (__DEV__) { + if (!xAxisModel) { + throw new Error('xAxis "' + retrieve( + seriesModel.get('xAxisIndex'), + seriesModel.get('xAxisId'), + 0 + ) + '" not found'); + } + if (!yAxisModel) { + throw new Error('yAxis "' + retrieve( + seriesModel.get('xAxisIndex'), + seriesModel.get('yAxisId'), + 0 + ) + '" not found'); + } + } + + result.coordSysDims = ['x', 'y']; + axisMap.set('x', xAxisModel); + axisMap.set('y', yAxisModel); + + if (isCategory(xAxisModel)) { + categoryAxisMap.set('x', xAxisModel); + result.firstCategoryDimIndex = 0; + } + if (isCategory(yAxisModel)) { + categoryAxisMap.set('y', yAxisModel); + result.firstCategoryDimIndex = 1; + } + }, + + singleAxis: function(seriesModel, result, axisMap, categoryAxisMap) { + var singleAxisModel = seriesModel.getReferringComponents('singleAxis')[0]; + + if (__DEV__) { + if (!singleAxisModel) { + throw new Error('singleAxis should be specified.'); + } + } + + result.coordSysDims = ['single']; + axisMap.set('single', singleAxisModel); + + if (isCategory(singleAxisModel)) { + categoryAxisMap.set('single', singleAxisModel); + result.firstCategoryDimIndex = 0; + } + }, + + polar: function(seriesModel, result, axisMap, categoryAxisMap) { + var polarModel = seriesModel.getReferringComponents('polar')[0]; + var radiusAxisModel = polarModel.findAxisModel('radiusAxis'); + var angleAxisModel = polarModel.findAxisModel('angleAxis'); + + if (__DEV__) { + if (!angleAxisModel) { + throw new Error('angleAxis option not found'); + } + if (!radiusAxisModel) { + throw new Error('radiusAxis option not found'); + } + } + + result.coordSysDims = ['radius', 'angle']; + axisMap.set('radius', radiusAxisModel); + axisMap.set('angle', angleAxisModel); + + if (isCategory(radiusAxisModel)) { + categoryAxisMap.set('radius', radiusAxisModel); + result.firstCategoryDimIndex = 0; + } + if (isCategory(angleAxisModel)) { + categoryAxisMap.set('angle', angleAxisModel); + result.firstCategoryDimIndex = 1; + } + }, + + geo: function(seriesModel, result, axisMap, categoryAxisMap) { + result.coordSysDims = ['lng', 'lat']; + }, + + parallel: function(seriesModel, result, axisMap, categoryAxisMap) { + var ecModel = seriesModel.ecModel; + var parallelModel = ecModel.getComponent( + 'parallel', seriesModel.get('parallelIndex') + ); + var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice(); + + each$1(parallelModel.parallelAxisIndex, function(axisIndex, index) { + var axisModel = ecModel.getComponent('parallelAxis', axisIndex); + var axisDim = coordSysDims[index]; + axisMap.set(axisDim, axisModel); + + if (isCategory(axisModel) && result.firstCategoryDimIndex == null) { + categoryAxisMap.set(axisDim, axisModel); + result.firstCategoryDimIndex = index; + } + }); + } + }; + + function isCategory(axisModel) { + return axisModel.get('type') === 'category'; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Avoid typo. + var SOURCE_FORMAT_ORIGINAL = 'original'; + var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows'; + var SOURCE_FORMAT_OBJECT_ROWS = 'objectRows'; + var SOURCE_FORMAT_KEYED_COLUMNS = 'keyedColumns'; + var SOURCE_FORMAT_UNKNOWN = 'unknown'; + // ??? CHANGE A NAME + var SOURCE_FORMAT_TYPED_ARRAY = 'typedArray'; + + var SERIES_LAYOUT_BY_COLUMN = 'column'; + var SERIES_LAYOUT_BY_ROW = 'row'; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * [sourceFormat] + * + * + "original": + * This format is only used in series.data, where + * itemStyle can be specified in data item. + * + * + "arrayRows": + * [ + * ['product', 'score', 'amount'], + * ['Matcha Latte', 89.3, 95.8], + * ['Milk Tea', 92.1, 89.4], + * ['Cheese Cocoa', 94.4, 91.2], + * ['Walnut Brownie', 85.4, 76.9] + * ] + * + * + "objectRows": + * [ + * {product: 'Matcha Latte', score: 89.3, amount: 95.8}, + * {product: 'Milk Tea', score: 92.1, amount: 89.4}, + * {product: 'Cheese Cocoa', score: 94.4, amount: 91.2}, + * {product: 'Walnut Brownie', score: 85.4, amount: 76.9} + * ] + * + * + "keyedColumns": + * { + * 'product': ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'], + * 'count': [823, 235, 1042, 988], + * 'score': [95.8, 81.4, 91.2, 76.9] + * } + * + * + "typedArray" + * + * + "unknown" + */ + + /** + * @constructor + * @param {Object} fields + * @param {string} fields.sourceFormat + * @param {Array|Object} fields.fromDataset + * @param {Array|Object} [fields.data] + * @param {string} [seriesLayoutBy='column'] + * @param {Array.} [dimensionsDefine] + * @param {Objet|HashMap} [encodeDefine] + * @param {number} [startIndex=0] + * @param {number} [dimensionsDetectCount] + */ + function Source(fields) { + + /** + * @type {boolean} + */ + this.fromDataset = fields.fromDataset; + + /** + * Not null/undefined. + * @type {Array|Object} + */ + this.data = fields.data || ( + fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : [] + ); + + /** + * See also "detectSourceFormat". + * Not null/undefined. + * @type {string} + */ + this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; + + /** + * 'row' or 'column' + * Not null/undefined. + * @type {string} seriesLayoutBy + */ + this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN; + + /** + * dimensions definition in option. + * can be null/undefined. + * @type {Array.} + */ + this.dimensionsDefine = fields.dimensionsDefine; + + /** + * encode definition in option. + * can be null/undefined. + * @type {Objet|HashMap} + */ + this.encodeDefine = fields.encodeDefine && createHashMap(fields.encodeDefine); + + /** + * Not null/undefined, uint. + * @type {number} + */ + this.startIndex = fields.startIndex || 0; + + /** + * Can be null/undefined (when unknown), uint. + * @type {number} + */ + this.dimensionsDetectCount = fields.dimensionsDetectCount; + } + + /** + * Wrap original series data for some compatibility cases. + */ + Source.seriesDataToSource = function(data) { + return new Source({ + data: data, + sourceFormat: isTypedArray(data) ? + SOURCE_FORMAT_TYPED_ARRAY : + SOURCE_FORMAT_ORIGINAL, + fromDataset: false + }); + }; + + enableClassCheck(Source); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$3 = makeInner(); + + /** + * @see {module:echarts/data/Source} + * @param {module:echarts/component/dataset/DatasetModel} datasetModel + * @return {string} sourceFormat + */ + function detectSourceFormat(datasetModel) { + var data = datasetModel.option.source; + var sourceFormat = SOURCE_FORMAT_UNKNOWN; + + if (isTypedArray(data)) { + sourceFormat = SOURCE_FORMAT_TYPED_ARRAY; + } else if (isArray(data)) { + // FIXME Whether tolerate null in top level array? + for (var i = 0, len = data.length; i < len; i++) { + var item = data[i]; + + if (item == null) { + continue; + } else if (isArray(item)) { + sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; + break; + } else if (isObject$1(item)) { + sourceFormat = SOURCE_FORMAT_OBJECT_ROWS; + break; + } + } + } else if (isObject$1(data)) { + for (var key in data) { + if (data.hasOwnProperty(key) && isArrayLike(data[key])) { + sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS; + break; + } + } + } else if (data != null) { + throw new Error('Invalid data'); + } + + inner$3(datasetModel).sourceFormat = sourceFormat; + } + + /** + * [Scenarios]: + * (1) Provide source data directly: + * series: { + * encode: {...}, + * dimensions: [...] + * seriesLayoutBy: 'row', + * data: [[...]] + * } + * (2) Refer to datasetModel. + * series: [{ + * encode: {...} + * // Ignore datasetIndex means `datasetIndex: 0` + * // and the dimensions defination in dataset is used + * }, { + * encode: {...}, + * seriesLayoutBy: 'column', + * datasetIndex: 1 + * }] + * + * Get data from series itself or datset. + * @return {module:echarts/data/Source} source + */ + function getSource(seriesModel) { + return inner$3(seriesModel).source; + } + + /** + * MUST be called before mergeOption of all series. + * @param {module:echarts/model/Global} ecModel + */ + function resetSourceDefaulter(ecModel) { + // `datasetMap` is used to make default encode. + inner$3(ecModel).datasetMap = createHashMap(); + } + + /** + * [Caution]: + * MUST be called after series option merged and + * before "series.getInitailData()" called. + * + * [The rule of making default encode]: + * Category axis (if exists) alway map to the first dimension. + * Each other axis occupies a subsequent dimension. + * + * [Why make default encode]: + * Simplify the typing of encode in option, avoiding the case like that: + * series: [{encode: {x: 0, y: 1}}, {encode: {x: 0, y: 2}}, {encode: {x: 0, y: 3}}], + * where the "y" have to be manually typed as "1, 2, 3, ...". + * + * @param {module:echarts/model/Series} seriesModel + */ + function prepareSource(seriesModel) { + var seriesOption = seriesModel.option; + + var data = seriesOption.data; + var sourceFormat = isTypedArray(data) ? + SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL; + var fromDataset = false; + + var seriesLayoutBy = seriesOption.seriesLayoutBy; + var sourceHeader = seriesOption.sourceHeader; + var dimensionsDefine = seriesOption.dimensions; + + var datasetModel = getDatasetModel(seriesModel); + if (datasetModel) { + var datasetOption = datasetModel.option; + + data = datasetOption.source; + sourceFormat = inner$3(datasetModel).sourceFormat; + fromDataset = true; + + // These settings from series has higher priority. + seriesLayoutBy = seriesLayoutBy || datasetOption.seriesLayoutBy; + sourceHeader == null && (sourceHeader = datasetOption.sourceHeader); + dimensionsDefine = dimensionsDefine || datasetOption.dimensions; + } + + var completeResult = completeBySourceData( + data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine + ); + + // Note: dataset option does not have `encode`. + var encodeDefine = seriesOption.encode; + if (!encodeDefine && datasetModel) { + encodeDefine = makeDefaultEncode( + seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult + ); + } + + inner$3(seriesModel).source = new Source({ + data: data, + fromDataset: fromDataset, + seriesLayoutBy: seriesLayoutBy, + sourceFormat: sourceFormat, + dimensionsDefine: completeResult.dimensionsDefine, + startIndex: completeResult.startIndex, + dimensionsDetectCount: completeResult.dimensionsDetectCount, + encodeDefine: encodeDefine + }); + } + + // return {startIndex, dimensionsDefine, dimensionsCount} + function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine) { + if (!data) { + return { + dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine) + }; + } + + var dimensionsDetectCount; + var startIndex; + var findPotentialName; + + if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { + // Rule: Most of the first line are string: it is header. + // Caution: consider a line with 5 string and 1 number, + // it still can not be sure it is a head, because the + // 5 string may be 5 values of category columns. + if (sourceHeader === 'auto' || sourceHeader == null) { + arrayRowsTravelFirst(function(val) { + // '-' is regarded as null/undefined. + if (val != null && val !== '-') { + if (isString(val)) { + startIndex == null && (startIndex = 1); + } else { + startIndex = 0; + } + } + // 10 is an experience number, avoid long loop. + }, seriesLayoutBy, data, 10); + } else { + startIndex = sourceHeader ? 1 : 0; + } + + if (!dimensionsDefine && startIndex === 1) { + dimensionsDefine = []; + arrayRowsTravelFirst(function(val, index) { + dimensionsDefine[index] = val != null ? val : ''; + }, seriesLayoutBy, data); + } + + dimensionsDetectCount = dimensionsDefine ? + dimensionsDefine.length : + seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? + data.length : + data[0] ? + data[0].length : + null; + } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { + if (!dimensionsDefine) { + dimensionsDefine = objectRowsCollectDimensions(data); + findPotentialName = true; + } + } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { + if (!dimensionsDefine) { + dimensionsDefine = []; + findPotentialName = true; + each$1(data, function(colArr, key) { + dimensionsDefine.push(key); + }); + } + } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { + var value0 = getDataItemValue(data[0]); + dimensionsDetectCount = isArray(value0) && value0.length || 1; + } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { + if (__DEV__) { + assert$1(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.'); + } + } + + var potentialNameDimIndex; + if (findPotentialName) { + each$1(dimensionsDefine, function(dim, idx) { + if ((isObject$1(dim) ? dim.name : dim) === 'name') { + potentialNameDimIndex = idx; + } + }); + } + + return { + startIndex: startIndex, + dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine), + dimensionsDetectCount: dimensionsDetectCount, + potentialNameDimIndex: potentialNameDimIndex + // TODO: potentialIdDimIdx + }; + } + + // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'], + // which is reasonable. But dimension name is duplicated. + // Returns undefined or an array contains only object without null/undefiend or string. + function normalizeDimensionsDefine(dimensionsDefine) { + if (!dimensionsDefine) { + // The meaning of null/undefined is different from empty array. + return; + } + var nameMap = createHashMap(); + return map(dimensionsDefine, function(item, index) { + item = extend({}, isObject$1(item) ? item : { + name: item + }); + + // User can set null in dimensions. + // We dont auto specify name, othewise a given name may + // cause it be refered unexpectedly. + if (item.name == null) { + return item; + } + + // Also consider number form like 2012. + item.name += ''; + // User may also specify displayName. + // displayName will always exists except user not + // specified or dim name is not specified or detected. + // (A auto generated dim name will not be used as + // displayName). + if (item.displayName == null) { + item.displayName = item.name; + } + + var exist = nameMap.get(item.name); + if (!exist) { + nameMap.set(item.name, { + count: 1 + }); + } else { + item.name += '-' + exist.count++; + } + + return item; + }); + } + + function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) { + maxLoop == null && (maxLoop = Infinity); + if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { + for (var i = 0; i < data.length && i < maxLoop; i++) { + cb(data[i] ? data[i][0] : null, i); + } + } else { + var value0 = data[0] || []; + for (var i = 0; i < value0.length && i < maxLoop; i++) { + cb(value0[i], i); + } + } + } + + function objectRowsCollectDimensions(data) { + var firstIndex = 0; + var obj; + while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line + if (obj) { + var dimensions = []; + each$1(obj, function(value, key) { + dimensions.push(key); + }); + return dimensions; + } + } + + // ??? TODO merge to completedimensions, where also has + // default encode making logic. And the default rule + // should depends on series? consider 'map'. + function makeDefaultEncode( + seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult + ) { + var coordSysDefine = getCoordSysDefineBySeries(seriesModel); + var encode = {}; + // var encodeTooltip = []; + // var encodeLabel = []; + var encodeItemName = []; + var encodeSeriesName = []; + var seriesType = seriesModel.subType; + + // ??? TODO refactor: provide by series itself. + // Consider the case: 'map' series is based on geo coordSys, + // 'graph', 'heatmap' can be based on cartesian. But can not + // give default rule simply here. + var nSeriesMap = createHashMap(['pie', 'map', 'funnel']); + var cSeriesMap = createHashMap([ + 'line', 'bar', 'pictorialBar', 'scatter', 'effectScatter', 'candlestick', 'boxplot' + ]); + + // Usually in this case series will use the first data + // dimension as the "value" dimension, or other default + // processes respectively. + if (coordSysDefine && cSeriesMap.get(seriesType) != null) { + var ecModel = seriesModel.ecModel; + var datasetMap = inner$3(ecModel).datasetMap; + var key = datasetModel.uid + '_' + seriesLayoutBy; + var datasetRecord = datasetMap.get(key) || + datasetMap.set(key, { + categoryWayDim: 1, + valueWayDim: 0 + }); + + // TODO + // Auto detect first time axis and do arrangement. + each$1(coordSysDefine.coordSysDims, function(coordDim) { + // In value way. + if (coordSysDefine.firstCategoryDimIndex == null) { + var dataDim = datasetRecord.valueWayDim++; + encode[coordDim] = dataDim; + + // ??? TODO give a better default series name rule? + // especially when encode x y specified. + // consider: when mutiple series share one dimension + // category axis, series name should better use + // the other dimsion name. On the other hand, use + // both dimensions name. + + encodeSeriesName.push(dataDim); + // encodeTooltip.push(dataDim); + // encodeLabel.push(dataDim); + } + // In category way, category axis. + else if (coordSysDefine.categoryAxisMap.get(coordDim)) { + encode[coordDim] = 0; + encodeItemName.push(0); + } + // In category way, non-category axis. + else { + var dataDim = datasetRecord.categoryWayDim++; + encode[coordDim] = dataDim; + // encodeTooltip.push(dataDim); + // encodeLabel.push(dataDim); + encodeSeriesName.push(dataDim); + } + }); + } + // Do not make a complex rule! Hard to code maintain and not necessary. + // ??? TODO refactor: provide by series itself. + // [{name: ..., value: ...}, ...] like: + else if (nSeriesMap.get(seriesType) != null) { + // Find the first not ordinal. (5 is an experience value) + var firstNotOrdinal; + for (var i = 0; i < 5 && firstNotOrdinal == null; i++) { + if (!doGuessOrdinal( + data, sourceFormat, seriesLayoutBy, + completeResult.dimensionsDefine, completeResult.startIndex, i + )) { + firstNotOrdinal = i; + } + } + if (firstNotOrdinal != null) { + encode.value = firstNotOrdinal; + var nameDimIndex = completeResult.potentialNameDimIndex || + Math.max(firstNotOrdinal - 1, 0); + // By default, label use itemName in charts. + // So we dont set encodeLabel here. + encodeSeriesName.push(nameDimIndex); + encodeItemName.push(nameDimIndex); + // encodeTooltip.push(firstNotOrdinal); + } + } + + // encodeTooltip.length && (encode.tooltip = encodeTooltip); + // encodeLabel.length && (encode.label = encodeLabel); + encodeItemName.length && (encode.itemName = encodeItemName); + encodeSeriesName.length && (encode.seriesName = encodeSeriesName); + + return encode; + } + + /** + * If return null/undefined, indicate that should not use datasetModel. + */ + function getDatasetModel(seriesModel) { + var option = seriesModel.option; + // Caution: consider the scenario: + // A dataset is declared and a series is not expected to use the dataset, + // and at the beginning `setOption({series: { noData })` (just prepare other + // option but no data), then `setOption({series: {data: [...]}); In this case, + // the user should set an empty array to avoid that dataset is used by default. + var thisData = option.data; + if (!thisData) { + return seriesModel.ecModel.getComponent('dataset', option.datasetIndex || 0); + } + } + + /** + * The rule should not be complex, otherwise user might not + * be able to known where the data is wrong. + * The code is ugly, but how to make it neat? + * + * @param {module:echars/data/Source} source + * @param {number} dimIndex + * @return {boolean} Whether ordinal. + */ + function guessOrdinal(source, dimIndex) { + return doGuessOrdinal( + source.data, + source.sourceFormat, + source.seriesLayoutBy, + source.dimensionsDefine, + source.startIndex, + dimIndex + ); + } + + // dimIndex may be overflow source data. + function doGuessOrdinal( + data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex + ) { + var result; + // Experience value. + var maxLoop = 5; + + if (isTypedArray(data)) { + return false; + } + + // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine + // always exists in source. + var dimName; + if (dimensionsDefine) { + dimName = dimensionsDefine[dimIndex]; + dimName = isObject$1(dimName) ? dimName.name : dimName; + } + + if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { + if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { + var sample = data[dimIndex]; + for (var i = 0; i < (sample || []).length && i < maxLoop; i++) { + if ((result = detectValue(sample[startIndex + i])) != null) { + return result; + } + } + } else { + for (var i = 0; i < data.length && i < maxLoop; i++) { + var row = data[startIndex + i]; + if (row && (result = detectValue(row[dimIndex])) != null) { + return result; + } + } + } + } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { + if (!dimName) { + return; + } + for (var i = 0; i < data.length && i < maxLoop; i++) { + var item = data[i]; + if (item && (result = detectValue(item[dimName])) != null) { + return result; + } + } + } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { + if (!dimName) { + return; + } + var sample = data[dimName]; + if (!sample || isTypedArray(sample)) { + return false; + } + for (var i = 0; i < sample.length && i < maxLoop; i++) { + if ((result = detectValue(sample[i])) != null) { + return result; + } + } + } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { + for (var i = 0; i < data.length && i < maxLoop; i++) { + var item = data[i]; + var val = getDataItemValue(item); + if (!isArray(val)) { + return false; + } + if ((result = detectValue(val[dimIndex])) != null) { + return result; + } + } + } + + function detectValue(val) { + // Consider usage convenience, '1', '2' will be treated as "number". + // `isFinit('')` get `true`. + if (val != null && isFinite(val) && val !== '') { + return false; + } else if (isString(val) && val !== '-') { + return true; + } + } + + return false; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * ECharts global model + * + * @module {echarts/model/Global} + */ + + + /** + * Caution: If the mechanism should be changed some day, these cases + * should be considered: + * + * (1) In `merge option` mode, if using the same option to call `setOption` + * many times, the result should be the same (try our best to ensure that). + * (2) In `merge option` mode, if a component has no id/name specified, it + * will be merged by index, and the result sequence of the components is + * consistent to the original sequence. + * (3) `reset` feature (in toolbox). Find detailed info in comments about + * `mergeOption` in module:echarts/model/OptionManager. + */ + + var OPTION_INNER_KEY = '\0_ec_inner'; + + /** + * @alias module:echarts/model/Global + * + * @param {Object} option + * @param {module:echarts/model/Model} parentModel + * @param {Object} theme + */ + var GlobalModel = Model.extend({ + + init: function(option, parentModel, theme, optionManager) { + theme = theme || {}; + + this.option = null; // Mark as not initialized. + + /** + * @type {module:echarts/model/Model} + * @private + */ + this._theme = new Model(theme); + + /** + * @type {module:echarts/model/OptionManager} + */ + this._optionManager = optionManager; + }, + + setOption: function(option, optionPreprocessorFuncs) { + assert$1( + !(OPTION_INNER_KEY in option), + 'please use chart.getOption()' + ); + + this._optionManager.setOption(option, optionPreprocessorFuncs); + + this.resetOption(null); + }, + + /** + * @param {string} type null/undefined: reset all. + * 'recreate': force recreate all. + * 'timeline': only reset timeline option + * 'media': only reset media query option + * @return {boolean} Whether option changed. + */ + resetOption: function(type) { + var optionChanged = false; + var optionManager = this._optionManager; + + if (!type || type === 'recreate') { + var baseOption = optionManager.mountOption(type === 'recreate'); + + if (!this.option || type === 'recreate') { + initBase.call(this, baseOption); + } else { + this.restoreData(); + this.mergeOption(baseOption); + } + optionChanged = true; + } + + if (type === 'timeline' || type === 'media') { + this.restoreData(); + } + + if (!type || type === 'recreate' || type === 'timeline') { + var timelineOption = optionManager.getTimelineOption(this); + timelineOption && (this.mergeOption(timelineOption), optionChanged = true); + } + + if (!type || type === 'recreate' || type === 'media') { + var mediaOptions = optionManager.getMediaOption(this, this._api); + if (mediaOptions.length) { + each$1(mediaOptions, function(mediaOption) { + this.mergeOption(mediaOption, optionChanged = true); + }, this); + } + } + + return optionChanged; + }, + + /** + * @protected + */ + mergeOption: function(newOption) { + var option = this.option; + var componentsMap = this._componentsMap; + var newCptTypes = []; + + resetSourceDefaulter(this); + + // If no component class, merge directly. + // For example: color, animaiton options, etc. + each$1(newOption, function(componentOption, mainType) { + if (componentOption == null) { + return; + } + + if (!ComponentModel.hasClass(mainType)) { + // globalSettingTask.dirty(); + option[mainType] = option[mainType] == null ? + clone(componentOption) : + merge(option[mainType], componentOption, true); + } else if (mainType) { + newCptTypes.push(mainType); + } + }); + + ComponentModel.topologicalTravel( + newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this + ); + + function visitComponent(mainType, dependencies) { + + var newCptOptionList = normalizeToArray(newOption[mainType]); + + var mapResult = mappingToExists( + componentsMap.get(mainType), newCptOptionList + ); + + makeIdAndName(mapResult); + + // Set mainType and complete subType. + each$1(mapResult, function(item, index) { + var opt = item.option; + if (isObject$1(opt)) { + item.keyInfo.mainType = mainType; + item.keyInfo.subType = determineSubType(mainType, opt, item.exist); + } + }); + + var dependentModels = getComponentsByTypes( + componentsMap, dependencies + ); + + option[mainType] = []; + componentsMap.set(mainType, []); + + each$1(mapResult, function(resultItem, index) { + var componentModel = resultItem.exist; + var newCptOption = resultItem.option; + + assert$1( + isObject$1(newCptOption) || componentModel, + 'Empty component definition' + ); + + // Consider where is no new option and should be merged using {}, + // see removeEdgeAndAdd in topologicalTravel and + // ComponentModel.getAllClassMainTypes. + if (!newCptOption) { + componentModel.mergeOption({}, this); + componentModel.optionUpdated({}, false); + } else { + var ComponentModelClass = ComponentModel.getClass( + mainType, resultItem.keyInfo.subType, true + ); + + if (componentModel && componentModel instanceof ComponentModelClass) { + componentModel.name = resultItem.keyInfo.name; + // componentModel.settingTask && componentModel.settingTask.dirty(); + componentModel.mergeOption(newCptOption, this); + componentModel.optionUpdated(newCptOption, false); + } else { + // PENDING Global as parent ? + var extraOpt = extend({ + dependentModels: dependentModels, + componentIndex: index + }, + resultItem.keyInfo + ); + componentModel = new ComponentModelClass( + newCptOption, this, this, extraOpt + ); + extend(componentModel, extraOpt); + componentModel.init(newCptOption, this, this, extraOpt); + + // Call optionUpdated after init. + // newCptOption has been used as componentModel.option + // and may be merged with theme and default, so pass null + // to avoid confusion. + componentModel.optionUpdated(null, true); + } + } + + componentsMap.get(mainType)[index] = componentModel; + option[mainType][index] = componentModel.option; + }, this); + + // Backup series for filtering. + if (mainType === 'series') { + createSeriesIndices(this, componentsMap.get('series')); + } + } + + this._seriesIndicesMap = createHashMap( + this._seriesIndices = this._seriesIndices || [] + ); + }, + + /** + * Get option for output (cloned option and inner info removed) + * @public + * @return {Object} + */ + getOption: function() { + var option = clone(this.option); + + each$1(option, function(opts, mainType) { + if (ComponentModel.hasClass(mainType)) { + var opts = normalizeToArray(opts); + for (var i = opts.length - 1; i >= 0; i--) { + // Remove options with inner id. + if (isIdInner(opts[i])) { + opts.splice(i, 1); + } + } + option[mainType] = opts; + } + }); + + delete option[OPTION_INNER_KEY]; + + return option; + }, + + /** + * @return {module:echarts/model/Model} + */ + getTheme: function() { + return this._theme; + }, + + /** + * @param {string} mainType + * @param {number} [idx=0] + * @return {module:echarts/model/Component} + */ + getComponent: function(mainType, idx) { + var list = this._componentsMap.get(mainType); + if (list) { + return list[idx || 0]; + } + }, + + /** + * If none of index and id and name used, return all components with mainType. + * @param {Object} condition + * @param {string} condition.mainType + * @param {string} [condition.subType] If ignore, only query by mainType + * @param {number|Array.} [condition.index] Either input index or id or name. + * @param {string|Array.} [condition.id] Either input index or id or name. + * @param {string|Array.} [condition.name] Either input index or id or name. + * @return {Array.} + */ + queryComponents: function(condition) { + var mainType = condition.mainType; + if (!mainType) { + return []; + } + + var index = condition.index; + var id = condition.id; + var name = condition.name; + + var cpts = this._componentsMap.get(mainType); + + if (!cpts || !cpts.length) { + return []; + } + + var result; + + if (index != null) { + if (!isArray(index)) { + index = [index]; + } + result = filter(map(index, function(idx) { + return cpts[idx]; + }), function(val) { + return !!val; + }); + } else if (id != null) { + var isIdArray = isArray(id); + result = filter(cpts, function(cpt) { + return (isIdArray && indexOf(id, cpt.id) >= 0) || + (!isIdArray && cpt.id === id); + }); + } else if (name != null) { + var isNameArray = isArray(name); + result = filter(cpts, function(cpt) { + return (isNameArray && indexOf(name, cpt.name) >= 0) || + (!isNameArray && cpt.name === name); + }); + } else { + // Return all components with mainType + result = cpts.slice(); + } + + return filterBySubType(result, condition); + }, + + /** + * The interface is different from queryComponents, + * which is convenient for inner usage. + * + * @usage + * var result = findComponents( + * {mainType: 'dataZoom', query: {dataZoomId: 'abc'}} + * ); + * var result = findComponents( + * {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}} + * ); + * var result = findComponents( + * {mainType: 'series'}, + * function (model, index) {...} + * ); + * // result like [component0, componnet1, ...] + * + * @param {Object} condition + * @param {string} condition.mainType Mandatory. + * @param {string} [condition.subType] Optional. + * @param {Object} [condition.query] like {xxxIndex, xxxId, xxxName}, + * where xxx is mainType. + * If query attribute is null/undefined or has no index/id/name, + * do not filtering by query conditions, which is convenient for + * no-payload situations or when target of action is global. + * @param {Function} [condition.filter] parameter: component, return boolean. + * @return {Array.} + */ + findComponents: function(condition) { + var query = condition.query; + var mainType = condition.mainType; + + var queryCond = getQueryCond(query); + var result = queryCond ? + this.queryComponents(queryCond) : + this._componentsMap.get(mainType); + + return doFilter(filterBySubType(result, condition)); + + function getQueryCond(q) { + var indexAttr = mainType + 'Index'; + var idAttr = mainType + 'Id'; + var nameAttr = mainType + 'Name'; + return q && ( + q[indexAttr] != null || + q[idAttr] != null || + q[nameAttr] != null + ) ? + { + mainType: mainType, + // subType will be filtered finally. + index: q[indexAttr], + id: q[idAttr], + name: q[nameAttr] + } : + null; + } + + function doFilter(res) { + return condition.filter ? + filter(res, condition.filter) : + res; + } + }, + + /** + * @usage + * eachComponent('legend', function (legendModel, index) { + * ... + * }); + * eachComponent(function (componentType, model, index) { + * // componentType does not include subType + * // (componentType is 'xxx' but not 'xxx.aa') + * }); + * eachComponent( + * {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}, + * function (model, index) {...} + * ); + * eachComponent( + * {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}, + * function (model, index) {...} + * ); + * + * @param {string|Object=} mainType When mainType is object, the definition + * is the same as the method 'findComponents'. + * @param {Function} cb + * @param {*} context + */ + eachComponent: function(mainType, cb, context) { + var componentsMap = this._componentsMap; + + if (typeof mainType === 'function') { + context = cb; + cb = mainType; + componentsMap.each(function(components, componentType) { + each$1(components, function(component, index) { + cb.call(context, componentType, component, index); + }); + }); + } else if (isString(mainType)) { + each$1(componentsMap.get(mainType), cb, context); + } else if (isObject$1(mainType)) { + var queryResult = this.findComponents(mainType); + each$1(queryResult, cb, context); + } + }, + + /** + * @param {string} name + * @return {Array.} + */ + getSeriesByName: function(name) { + var series = this._componentsMap.get('series'); + return filter(series, function(oneSeries) { + return oneSeries.name === name; + }); + }, + + /** + * @param {number} seriesIndex + * @return {module:echarts/model/Series} + */ + getSeriesByIndex: function(seriesIndex) { + return this._componentsMap.get('series')[seriesIndex]; + }, + + /** + * Get series list before filtered by type. + * FIXME: rename to getRawSeriesByType? + * + * @param {string} subType + * @return {Array.} + */ + getSeriesByType: function(subType) { + var series = this._componentsMap.get('series'); + return filter(series, function(oneSeries) { + return oneSeries.subType === subType; + }); + }, + + /** + * @return {Array.} + */ + getSeries: function() { + return this._componentsMap.get('series').slice(); + }, + + /** + * @return {number} + */ + getSeriesCount: function() { + return this._componentsMap.get('series').length; + }, + + /** + * After filtering, series may be different + * frome raw series. + * + * @param {Function} cb + * @param {*} context + */ + eachSeries: function(cb, context) { + assertSeriesInitialized(this); + each$1(this._seriesIndices, function(rawSeriesIndex) { + var series = this._componentsMap.get('series')[rawSeriesIndex]; + cb.call(context, series, rawSeriesIndex); + }, this); + }, + + /** + * Iterate raw series before filtered. + * + * @param {Function} cb + * @param {*} context + */ + eachRawSeries: function(cb, context) { + each$1(this._componentsMap.get('series'), cb, context); + }, + + /** + * After filtering, series may be different. + * frome raw series. + * + * @parma {string} subType + * @param {Function} cb + * @param {*} context + */ + eachSeriesByType: function(subType, cb, context) { + assertSeriesInitialized(this); + each$1(this._seriesIndices, function(rawSeriesIndex) { + var series = this._componentsMap.get('series')[rawSeriesIndex]; + if (series.subType === subType) { + cb.call(context, series, rawSeriesIndex); + } + }, this); + }, + + /** + * Iterate raw series before filtered of given type. + * + * @parma {string} subType + * @param {Function} cb + * @param {*} context + */ + eachRawSeriesByType: function(subType, cb, context) { + return each$1(this.getSeriesByType(subType), cb, context); + }, + + /** + * @param {module:echarts/model/Series} seriesModel + */ + isSeriesFiltered: function(seriesModel) { + assertSeriesInitialized(this); + return this._seriesIndicesMap.get(seriesModel.componentIndex) == null; + }, + + /** + * @return {Array.} + */ + getCurrentSeriesIndices: function() { + return (this._seriesIndices || []).slice(); + }, + + /** + * @param {Function} cb + * @param {*} context + */ + filterSeries: function(cb, context) { + assertSeriesInitialized(this); + var filteredSeries = filter( + this._componentsMap.get('series'), cb, context + ); + createSeriesIndices(this, filteredSeries); + }, + + restoreData: function(payload) { + var componentsMap = this._componentsMap; + + createSeriesIndices(this, componentsMap.get('series')); + + var componentTypes = []; + componentsMap.each(function(components, componentType) { + componentTypes.push(componentType); + }); + + ComponentModel.topologicalTravel( + componentTypes, + ComponentModel.getAllClassMainTypes(), + function(componentType, dependencies) { + each$1(componentsMap.get(componentType), function(component) { + (componentType !== 'series' || !isNotTargetSeries(component, payload)) && + component.restoreData(); + }); + } + ); + } + + }); + + function isNotTargetSeries(seriesModel, payload) { + if (payload) { + var index = payload.seiresIndex; + var id = payload.seriesId; + var name = payload.seriesName; + return (index != null && seriesModel.componentIndex !== index) || + (id != null && seriesModel.id !== id) || + (name != null && seriesModel.name !== name); + } + } + + /** + * @inner + */ + function mergeTheme(option, theme) { + // PENDING + // NOT use `colorLayer` in theme if option has `color` + var notMergeColorLayer = option.color && !option.colorLayer; + + each$1(theme, function(themeItem, name) { + if (name === 'colorLayer' && notMergeColorLayer) { + return; + } + // 如果有 component model 则把具体的 merge 逻辑交给该 model 处理 + if (!ComponentModel.hasClass(name)) { + if (typeof themeItem === 'object') { + option[name] = !option[name] ? + clone(themeItem) : + merge(option[name], themeItem, false); + } else { + if (option[name] == null) { + option[name] = themeItem; + } + } + } + }); + } + + function initBase(baseOption) { + baseOption = baseOption; + + // Using OPTION_INNER_KEY to mark that this option can not be used outside, + // i.e. `chart.setOption(chart.getModel().option);` is forbiden. + this.option = {}; + this.option[OPTION_INNER_KEY] = 1; + + /** + * Init with series: [], in case of calling findSeries method + * before series initialized. + * @type {Object.>} + * @private + */ + this._componentsMap = createHashMap({ + series: [] + }); + + /** + * Mapping between filtered series list and raw series list. + * key: filtered series indices, value: raw series indices. + * @type {Array.} + * @private + */ + this._seriesIndices; + + this._seriesIndicesMap; + + mergeTheme(baseOption, this._theme.option); + + // TODO Needs clone when merging to the unexisted property + merge(baseOption, globalDefault, false); + + this.mergeOption(baseOption); + } + + /** + * @inner + * @param {Array.|string} types model types + * @return {Object} key: {string} type, value: {Array.} models + */ + function getComponentsByTypes(componentsMap, types) { + if (!isArray(types)) { + types = types ? [types] : []; + } + + var ret = {}; + each$1(types, function(type) { + ret[type] = (componentsMap.get(type) || []).slice(); + }); + + return ret; + } + + /** + * @inner + */ + function determineSubType(mainType, newCptOption, existComponent) { + var subType = newCptOption.type ? + newCptOption.type : + existComponent ? + existComponent.subType + // Use determineSubType only when there is no existComponent. + : + ComponentModel.determineSubType(mainType, newCptOption); + + // tooltip, markline, markpoint may always has no subType + return subType; + } + + /** + * @inner + */ + function createSeriesIndices(ecModel, seriesModels) { + ecModel._seriesIndicesMap = createHashMap( + ecModel._seriesIndices = map(seriesModels, function(series) { + return series.componentIndex; + }) || [] + ); + } + + /** + * @inner + */ + function filterBySubType(components, condition) { + // Using hasOwnProperty for restrict. Consider + // subType is undefined in user payload. + return condition.hasOwnProperty('subType') ? + filter(components, function(cpt) { + return cpt.subType === condition.subType; + }) : + components; + } + + /** + * @inner + */ + function assertSeriesInitialized(ecModel) { + // Components that use _seriesIndices should depends on series component, + // which make sure that their initialization is after series. + if (__DEV__) { + if (!ecModel._seriesIndices) { + throw new Error('Option should contains series.'); + } + } + } + + mixin(GlobalModel, colorPaletteMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var echartsAPIList = [ + 'getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isDisposed', + 'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption', + 'getViewOfComponentModel', 'getViewOfSeriesModel' + ]; + // And `getCoordinateSystems` and `getComponentByElement` will be injected in echarts.js + + function ExtensionAPI(chartInstance) { + each$1(echartsAPIList, function(name) { + this[name] = bind(chartInstance[name], chartInstance); + }, this); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var coordinateSystemCreators = {}; + + function CoordinateSystemManager() { + + this._coordinateSystems = []; + } + + CoordinateSystemManager.prototype = { + + constructor: CoordinateSystemManager, + + create: function(ecModel, api) { + var coordinateSystems = []; + each$1(coordinateSystemCreators, function(creater, type) { + var list = creater.create(ecModel, api); + coordinateSystems = coordinateSystems.concat(list || []); + }); + + this._coordinateSystems = coordinateSystems; + }, + + update: function(ecModel, api) { + each$1(this._coordinateSystems, function(coordSys) { + coordSys.update && coordSys.update(ecModel, api); + }); + }, + + getCoordinateSystems: function() { + return this._coordinateSystems.slice(); + } + }; + + CoordinateSystemManager.register = function(type, coordinateSystemCreator) { + coordinateSystemCreators[type] = coordinateSystemCreator; + }; + + CoordinateSystemManager.get = function(type) { + return coordinateSystemCreators[type]; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * ECharts option manager + * + * @module {echarts/model/OptionManager} + */ + + + var each$4 = each$1; + var clone$3 = clone; + var map$1 = map; + var merge$1 = merge; + + var QUERY_REG = /^(min|max)?(.+)$/; + + /** + * TERM EXPLANATIONS: + * + * [option]: + * + * An object that contains definitions of components. For example: + * var option = { + * title: {...}, + * legend: {...}, + * visualMap: {...}, + * series: [ + * {data: [...]}, + * {data: [...]}, + * ... + * ] + * }; + * + * [rawOption]: + * + * An object input to echarts.setOption. 'rawOption' may be an + * 'option', or may be an object contains multi-options. For example: + * var option = { + * baseOption: { + * title: {...}, + * legend: {...}, + * series: [ + * {data: [...]}, + * {data: [...]}, + * ... + * ] + * }, + * timeline: {...}, + * options: [ + * {title: {...}, series: {data: [...]}}, + * {title: {...}, series: {data: [...]}}, + * ... + * ], + * media: [ + * { + * query: {maxWidth: 320}, + * option: {series: {x: 20}, visualMap: {show: false}} + * }, + * { + * query: {minWidth: 320, maxWidth: 720}, + * option: {series: {x: 500}, visualMap: {show: true}} + * }, + * { + * option: {series: {x: 1200}, visualMap: {show: true}} + * } + * ] + * }; + * + * @alias module:echarts/model/OptionManager + * @param {module:echarts/ExtensionAPI} api + */ + function OptionManager(api) { + + /** + * @private + * @type {module:echarts/ExtensionAPI} + */ + this._api = api; + + /** + * @private + * @type {Array.} + */ + this._timelineOptions = []; + + /** + * @private + * @type {Array.} + */ + this._mediaList = []; + + /** + * @private + * @type {Object} + */ + this._mediaDefault; + + /** + * -1, means default. + * empty means no media. + * @private + * @type {Array.} + */ + this._currentMediaIndices = []; + + /** + * @private + * @type {Object} + */ + this._optionBackup; + + /** + * @private + * @type {Object} + */ + this._newBaseOption; + } + + // timeline.notMerge is not supported in ec3. Firstly there is rearly + // case that notMerge is needed. Secondly supporting 'notMerge' requires + // rawOption cloned and backuped when timeline changed, which does no + // good to performance. What's more, that both timeline and setOption + // method supply 'notMerge' brings complex and some problems. + // Consider this case: + // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false); + // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false); + + OptionManager.prototype = { + + constructor: OptionManager, + + /** + * @public + * @param {Object} rawOption Raw option. + * @param {module:echarts/model/Global} ecModel + * @param {Array.} optionPreprocessorFuncs + * @return {Object} Init option + */ + setOption: function(rawOption, optionPreprocessorFuncs) { + if (rawOption) { + // That set dat primitive is dangerous if user reuse the data when setOption again. + each$1(normalizeToArray(rawOption.series), function(series) { + series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data); + }); + } + + // Caution: some series modify option data, if do not clone, + // it should ensure that the repeat modify correctly + // (create a new object when modify itself). + rawOption = clone$3(rawOption, true); + + // FIXME + // 如果 timeline options 或者 media 中设置了某个属性,而baseOption中没有设置,则进行警告。 + + var oldOptionBackup = this._optionBackup; + var newParsedOption = parseRawOption.call( + this, rawOption, optionPreprocessorFuncs, !oldOptionBackup + ); + this._newBaseOption = newParsedOption.baseOption; + + // For setOption at second time (using merge mode); + if (oldOptionBackup) { + // Only baseOption can be merged. + mergeOption(oldOptionBackup.baseOption, newParsedOption.baseOption); + + // For simplicity, timeline options and media options do not support merge, + // that is, if you `setOption` twice and both has timeline options, the latter + // timeline opitons will not be merged to the formers, but just substitude them. + if (newParsedOption.timelineOptions.length) { + oldOptionBackup.timelineOptions = newParsedOption.timelineOptions; + } + if (newParsedOption.mediaList.length) { + oldOptionBackup.mediaList = newParsedOption.mediaList; + } + if (newParsedOption.mediaDefault) { + oldOptionBackup.mediaDefault = newParsedOption.mediaDefault; + } + } else { + this._optionBackup = newParsedOption; + } + }, + + /** + * @param {boolean} isRecreate + * @return {Object} + */ + mountOption: function(isRecreate) { + var optionBackup = this._optionBackup; + + // TODO + // 如果没有reset功能则不clone。 + + this._timelineOptions = map$1(optionBackup.timelineOptions, clone$3); + this._mediaList = map$1(optionBackup.mediaList, clone$3); + this._mediaDefault = clone$3(optionBackup.mediaDefault); + this._currentMediaIndices = []; + + return clone$3(isRecreate + // this._optionBackup.baseOption, which is created at the first `setOption` + // called, and is merged into every new option by inner method `mergeOption` + // each time `setOption` called, can be only used in `isRecreate`, because + // its reliability is under suspicion. In other cases option merge is + // performed by `model.mergeOption`. + ? + optionBackup.baseOption : this._newBaseOption + ); + }, + + /** + * @param {module:echarts/model/Global} ecModel + * @return {Object} + */ + getTimelineOption: function(ecModel) { + var option; + var timelineOptions = this._timelineOptions; + + if (timelineOptions.length) { + // getTimelineOption can only be called after ecModel inited, + // so we can get currentIndex from timelineModel. + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel) { + option = clone$3( + timelineOptions[timelineModel.getCurrentIndex()], + true + ); + } + } + + return option; + }, + + /** + * @param {module:echarts/model/Global} ecModel + * @return {Array.} + */ + getMediaOption: function(ecModel) { + var ecWidth = this._api.getWidth(); + var ecHeight = this._api.getHeight(); + var mediaList = this._mediaList; + var mediaDefault = this._mediaDefault; + var indices = []; + var result = []; + + // No media defined. + if (!mediaList.length && !mediaDefault) { + return result; + } + + // Multi media may be applied, the latter defined media has higher priority. + for (var i = 0, len = mediaList.length; i < len; i++) { + if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) { + indices.push(i); + } + } + + // FIXME + // 是否mediaDefault应该强制用户设置,否则可能修改不能回归。 + if (!indices.length && mediaDefault) { + indices = [-1]; + } + + if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) { + result = map$1(indices, function(index) { + return clone$3( + index === -1 ? mediaDefault.option : mediaList[index].option + ); + }); + } + // Otherwise return nothing. + + this._currentMediaIndices = indices; + + return result; + } + }; + + function parseRawOption(rawOption, optionPreprocessorFuncs, isNew) { + var timelineOptions = []; + var mediaList = []; + var mediaDefault; + var baseOption; + + // Compatible with ec2. + var timelineOpt = rawOption.timeline; + + if (rawOption.baseOption) { + baseOption = rawOption.baseOption; + } + + // For timeline + if (timelineOpt || rawOption.options) { + baseOption = baseOption || {}; + timelineOptions = (rawOption.options || []).slice(); + } + + // For media query + if (rawOption.media) { + baseOption = baseOption || {}; + var media = rawOption.media; + each$4(media, function(singleMedia) { + if (singleMedia && singleMedia.option) { + if (singleMedia.query) { + mediaList.push(singleMedia); + } else if (!mediaDefault) { + // Use the first media default. + mediaDefault = singleMedia; + } + } + }); + } + + // For normal option + if (!baseOption) { + baseOption = rawOption; + } + + // Set timelineOpt to baseOption in ec3, + // which is convenient for merge option. + if (!baseOption.timeline) { + baseOption.timeline = timelineOpt; + } + + // Preprocess. + each$4([baseOption].concat(timelineOptions) + .concat(map(mediaList, function(media) { + return media.option; + })), + function(option) { + each$4(optionPreprocessorFuncs, function(preProcess) { + preProcess(option, isNew); + }); + } + ); + + return { + baseOption: baseOption, + timelineOptions: timelineOptions, + mediaDefault: mediaDefault, + mediaList: mediaList + }; + } + + /** + * @see + * Support: width, height, aspectRatio + * Can use max or min as prefix. + */ + function applyMediaQuery(query, ecWidth, ecHeight) { + var realMap = { + width: ecWidth, + height: ecHeight, + aspectratio: ecWidth / ecHeight // lowser case for convenientce. + }; + + var applicatable = true; + + each$1(query, function(value, attr) { + var matched = attr.match(QUERY_REG); + + if (!matched || !matched[1] || !matched[2]) { + return; + } + + var operator = matched[1]; + var realAttr = matched[2].toLowerCase(); + + if (!compare(realMap[realAttr], value, operator)) { + applicatable = false; + } + }); + + return applicatable; + } + + function compare(real, expect, operator) { + if (operator === 'min') { + return real >= expect; + } else if (operator === 'max') { + return real <= expect; + } else { // Equals + return real === expect; + } + } + + function indicesEquals(indices1, indices2) { + // indices is always order by asc and has only finite number. + return indices1.join(',') === indices2.join(','); + } + + /** + * Consider case: + * `chart.setOption(opt1);` + * Then user do some interaction like dataZoom, dataView changing. + * `chart.setOption(opt2);` + * Then user press 'reset button' in toolbox. + * + * After doing that all of the interaction effects should be reset, the + * chart should be the same as the result of invoke + * `chart.setOption(opt1); chart.setOption(opt2);`. + * + * Although it is not able ensure that + * `chart.setOption(opt1); chart.setOption(opt2);` is equivalents to + * `chart.setOption(merge(opt1, opt2));` exactly, + * this might be the only simple way to implement that feature. + * + * MEMO: We've considered some other approaches: + * 1. Each model handle its self restoration but not uniform treatment. + * (Too complex in logic and error-prone) + * 2. Use a shadow ecModel. (Performace expensive) + */ + function mergeOption(oldOption, newOption) { + newOption = newOption || {}; + + each$4(newOption, function(newCptOpt, mainType) { + if (newCptOpt == null) { + return; + } + + var oldCptOpt = oldOption[mainType]; + + if (!ComponentModel.hasClass(mainType)) { + oldOption[mainType] = merge$1(oldCptOpt, newCptOpt, true); + } else { + newCptOpt = normalizeToArray(newCptOpt); + oldCptOpt = normalizeToArray(oldCptOpt); + + var mapResult = mappingToExists(oldCptOpt, newCptOpt); + + oldOption[mainType] = map$1(mapResult, function(item) { + return (item.option && item.exist) ? + merge$1(item.exist, item.option, true) : + (item.exist || item.option); + }); + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$5 = each$1; + var isObject$3 = isObject$1; + + var POSSIBLE_STYLES = [ + 'areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle', + 'chordStyle', 'label', 'labelLine' + ]; + + function compatEC2ItemStyle(opt) { + var itemStyleOpt = opt && opt.itemStyle; + if (!itemStyleOpt) { + return; + } + for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) { + var styleName = POSSIBLE_STYLES[i]; + var normalItemStyleOpt = itemStyleOpt.normal; + var emphasisItemStyleOpt = itemStyleOpt.emphasis; + if (normalItemStyleOpt && normalItemStyleOpt[styleName]) { + opt[styleName] = opt[styleName] || {}; + if (!opt[styleName].normal) { + opt[styleName].normal = normalItemStyleOpt[styleName]; + } else { + merge(opt[styleName].normal, normalItemStyleOpt[styleName]); + } + normalItemStyleOpt[styleName] = null; + } + if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) { + opt[styleName] = opt[styleName] || {}; + if (!opt[styleName].emphasis) { + opt[styleName].emphasis = emphasisItemStyleOpt[styleName]; + } else { + merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]); + } + emphasisItemStyleOpt[styleName] = null; + } + } + } + + function convertNormalEmphasis(opt, optType, useExtend) { + if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) { + var normalOpt = opt[optType].normal; + var emphasisOpt = opt[optType].emphasis; + + if (normalOpt) { + // Timeline controlStyle has other properties besides normal and emphasis + if (useExtend) { + opt[optType].normal = opt[optType].emphasis = null; + defaults(opt[optType], normalOpt); + } else { + opt[optType] = normalOpt; + } + } + if (emphasisOpt) { + opt.emphasis = opt.emphasis || {}; + opt.emphasis[optType] = emphasisOpt; + } + } + } + + function removeEC3NormalStatus(opt) { + convertNormalEmphasis(opt, 'itemStyle'); + convertNormalEmphasis(opt, 'lineStyle'); + convertNormalEmphasis(opt, 'areaStyle'); + convertNormalEmphasis(opt, 'label'); + convertNormalEmphasis(opt, 'labelLine'); + // treemap + convertNormalEmphasis(opt, 'upperLabel'); + // graph + convertNormalEmphasis(opt, 'edgeLabel'); + } + + function compatTextStyle(opt, propName) { + // Check whether is not object (string\null\undefined ...) + var labelOptSingle = isObject$3(opt) && opt[propName]; + var textStyle = isObject$3(labelOptSingle) && labelOptSingle.textStyle; + if (textStyle) { + for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) { + var propName = TEXT_STYLE_OPTIONS[i]; + if (textStyle.hasOwnProperty(propName)) { + labelOptSingle[propName] = textStyle[propName]; + } + } + } + } + + function compatEC3CommonStyles(opt) { + if (opt) { + removeEC3NormalStatus(opt); + compatTextStyle(opt, 'label'); + opt.emphasis && compatTextStyle(opt.emphasis, 'label'); + } + } + + function processSeries(seriesOpt) { + if (!isObject$3(seriesOpt)) { + return; + } + + compatEC2ItemStyle(seriesOpt); + removeEC3NormalStatus(seriesOpt); + + compatTextStyle(seriesOpt, 'label'); + // treemap + compatTextStyle(seriesOpt, 'upperLabel'); + // graph + compatTextStyle(seriesOpt, 'edgeLabel'); + if (seriesOpt.emphasis) { + compatTextStyle(seriesOpt.emphasis, 'label'); + // treemap + compatTextStyle(seriesOpt.emphasis, 'upperLabel'); + // graph + compatTextStyle(seriesOpt.emphasis, 'edgeLabel'); + } + + var markPoint = seriesOpt.markPoint; + if (markPoint) { + compatEC2ItemStyle(markPoint); + compatEC3CommonStyles(markPoint); + } + + var markLine = seriesOpt.markLine; + if (markLine) { + compatEC2ItemStyle(markLine); + compatEC3CommonStyles(markLine); + } + + var markArea = seriesOpt.markArea; + if (markArea) { + compatEC3CommonStyles(markArea); + } + + var data = seriesOpt.data; + + // Break with ec3: if `setOption` again, there may be no `type` in option, + // then the backward compat based on option type will not be performed. + + if (seriesOpt.type === 'graph') { + data = data || seriesOpt.nodes; + var edgeData = seriesOpt.links || seriesOpt.edges; + if (edgeData && !isTypedArray(edgeData)) { + for (var i = 0; i < edgeData.length; i++) { + compatEC3CommonStyles(edgeData[i]); + } + } + each$1(seriesOpt.categories, function(opt) { + removeEC3NormalStatus(opt); + }); + } + + if (data && !isTypedArray(data)) { + for (var i = 0; i < data.length; i++) { + compatEC3CommonStyles(data[i]); + } + } + + // mark point data + var markPoint = seriesOpt.markPoint; + if (markPoint && markPoint.data) { + var mpData = markPoint.data; + for (var i = 0; i < mpData.length; i++) { + compatEC3CommonStyles(mpData[i]); + } + } + // mark line data + var markLine = seriesOpt.markLine; + if (markLine && markLine.data) { + var mlData = markLine.data; + for (var i = 0; i < mlData.length; i++) { + if (isArray(mlData[i])) { + compatEC3CommonStyles(mlData[i][0]); + compatEC3CommonStyles(mlData[i][1]); + } else { + compatEC3CommonStyles(mlData[i]); + } + } + } + + // Series + if (seriesOpt.type === 'gauge') { + compatTextStyle(seriesOpt, 'axisLabel'); + compatTextStyle(seriesOpt, 'title'); + compatTextStyle(seriesOpt, 'detail'); + } else if (seriesOpt.type === 'treemap') { + convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle'); + each$1(seriesOpt.levels, function(opt) { + removeEC3NormalStatus(opt); + }); + } else if (seriesOpt.type === 'tree') { + removeEC3NormalStatus(seriesOpt.leaves); + } + // sunburst starts from ec4, so it does not need to compat levels. + } + + function toArr(o) { + return isArray(o) ? o : o ? [o] : []; + } + + function toObj(o) { + return (isArray(o) ? o[0] : o) || {}; + } + + var compatStyle = function(option, isTheme) { + each$5(toArr(option.series), function(seriesOpt) { + isObject$3(seriesOpt) && processSeries(seriesOpt); + }); + + var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar']; + isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis'); + + each$5( + axes, + function(axisName) { + each$5(toArr(option[axisName]), function(axisOpt) { + if (axisOpt) { + compatTextStyle(axisOpt, 'axisLabel'); + compatTextStyle(axisOpt.axisPointer, 'label'); + } + }); + } + ); + + each$5(toArr(option.parallel), function(parallelOpt) { + var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault; + compatTextStyle(parallelAxisDefault, 'axisLabel'); + compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label'); + }); + + each$5(toArr(option.calendar), function(calendarOpt) { + convertNormalEmphasis(calendarOpt, 'itemStyle'); + compatTextStyle(calendarOpt, 'dayLabel'); + compatTextStyle(calendarOpt, 'monthLabel'); + compatTextStyle(calendarOpt, 'yearLabel'); + }); + + // radar.name.textStyle + each$5(toArr(option.radar), function(radarOpt) { + compatTextStyle(radarOpt, 'name'); + }); + + each$5(toArr(option.geo), function(geoOpt) { + if (isObject$3(geoOpt)) { + compatEC3CommonStyles(geoOpt); + each$5(toArr(geoOpt.regions), function(regionObj) { + compatEC3CommonStyles(regionObj); + }); + } + }); + + each$5(toArr(option.timeline), function(timelineOpt) { + compatEC3CommonStyles(timelineOpt); + convertNormalEmphasis(timelineOpt, 'label'); + convertNormalEmphasis(timelineOpt, 'itemStyle'); + convertNormalEmphasis(timelineOpt, 'controlStyle', true); + + var data = timelineOpt.data; + isArray(data) && each$1(data, function(item) { + if (isObject$1(item)) { + convertNormalEmphasis(item, 'label'); + convertNormalEmphasis(item, 'itemStyle'); + } + }); + }); + + each$5(toArr(option.toolbox), function(toolboxOpt) { + convertNormalEmphasis(toolboxOpt, 'iconStyle'); + each$5(toolboxOpt.feature, function(featureOpt) { + convertNormalEmphasis(featureOpt, 'iconStyle'); + }); + }); + + compatTextStyle(toObj(option.axisPointer), 'label'); + compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Compatitable with 2.0 + + function get(opt, path) { + path = path.split(','); + var obj = opt; + for (var i = 0; i < path.length; i++) { + obj = obj && obj[path[i]]; + if (obj == null) { + break; + } + } + return obj; + } + + function set$1(opt, path, val, overwrite) { + path = path.split(','); + var obj = opt; + var key; + for (var i = 0; i < path.length - 1; i++) { + key = path[i]; + if (obj[key] == null) { + obj[key] = {}; + } + obj = obj[key]; + } + if (overwrite || obj[path[i]] == null) { + obj[path[i]] = val; + } + } + + function compatLayoutProperties(option) { + each$1(LAYOUT_PROPERTIES, function(prop) { + if (prop[0] in option && !(prop[1] in option)) { + option[prop[1]] = option[prop[0]]; + } + }); + } + + var LAYOUT_PROPERTIES = [ + ['x', 'left'], + ['y', 'top'], + ['x2', 'right'], + ['y2', 'bottom'] + ]; + + var COMPATITABLE_COMPONENTS = [ + 'grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline' + ]; + + var backwardCompat = function(option, isTheme) { + compatStyle(option, isTheme); + + // Make sure series array for model initialization. + option.series = normalizeToArray(option.series); + + each$1(option.series, function(seriesOpt) { + if (!isObject$1(seriesOpt)) { + return; + } + + var seriesType = seriesOpt.type; + + if (seriesType === 'pie' || seriesType === 'gauge') { + if (seriesOpt.clockWise != null) { + seriesOpt.clockwise = seriesOpt.clockWise; + } + } + if (seriesType === 'gauge') { + var pointerColor = get(seriesOpt, 'pointer.color'); + pointerColor != null && + set$1(seriesOpt, 'itemStyle.normal.color', pointerColor); + } + + compatLayoutProperties(seriesOpt); + }); + + // dataRange has changed to visualMap + if (option.dataRange) { + option.visualMap = option.dataRange; + } + + each$1(COMPATITABLE_COMPONENTS, function(componentName) { + var options = option[componentName]; + if (options) { + if (!isArray(options)) { + options = [options]; + } + each$1(options, function(option) { + compatLayoutProperties(option); + }); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // (1) [Caution]: the logic is correct based on the premises: + // data processing stage is blocked in stream. + // See + // (2) Only register once when import repeatly. + // Should be executed before after series filtered and before stack calculation. + var dataStack = function(ecModel) { + var stackInfoMap = createHashMap(); + ecModel.eachSeries(function(seriesModel) { + var stack = seriesModel.get('stack'); + // Compatibal: when `stack` is set as '', do not stack. + if (stack) { + var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []); + var data = seriesModel.getData(); + + var stackInfo = { + // Used for calculate axis extent automatically. + stackResultDimension: data.getCalculationInfo('stackResultDimension'), + stackedOverDimension: data.getCalculationInfo('stackedOverDimension'), + stackedDimension: data.getCalculationInfo('stackedDimension'), + stackedByDimension: data.getCalculationInfo('stackedByDimension'), + isStackedByIndex: data.getCalculationInfo('isStackedByIndex'), + data: data, + seriesModel: seriesModel + }; + + // If stacked on axis that do not support data stack. + if (!stackInfo.stackedDimension || + !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension) + ) { + return; + } + + stackInfoList.length && data.setCalculationInfo( + 'stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel + ); + + stackInfoList.push(stackInfo); + } + }); + + stackInfoMap.each(calculateStack); + }; + + function calculateStack(stackInfoList) { + each$1(stackInfoList, function(targetStackInfo, idxInStack) { + var resultVal = []; + var resultNaN = [NaN, NaN]; + var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension]; + var targetData = targetStackInfo.data; + var isStackedByIndex = targetStackInfo.isStackedByIndex; + + // Should not write on raw data, because stack series model list changes + // depending on legend selection. + var newData = targetData.map(dims, function(v0, v1, dataIndex) { + var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); + + // Consider `connectNulls` of line area, if value is NaN, stackedOver + // should also be NaN, to draw a appropriate belt area. + if (isNaN(sum)) { + return resultNaN; + } + + var byValue; + var stackedDataRawIndex; + + if (isStackedByIndex) { + stackedDataRawIndex = targetData.getRawIndex(dataIndex); + } else { + byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex); + } + + // If stackOver is NaN, chart view will render point on value start. + var stackedOver = NaN; + + for (var j = idxInStack - 1; j >= 0; j--) { + var stackInfo = stackInfoList[j]; + + // Has been optimized by inverted indices on `stackedByDimension`. + if (!isStackedByIndex) { + stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue); + } + + if (stackedDataRawIndex >= 0) { + var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); + + // Considering positive stack, negative stack and empty data + if ((sum >= 0 && val > 0) // Positive stack + || + (sum <= 0 && val < 0) // Negative stack + ) { + sum += val; + stackedOver = val; + break; + } + } + } + + resultVal[0] = sum; + resultVal[1] = stackedOver; + + return resultVal; + }); + + targetData.hostModel.setData(newData); + // Update for consequent calculation + targetStackInfo.data = newData; + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO + // ??? refactor? check the outer usage of data provider. + // merge with defaultDimValueGetter? + + /** + * If normal array used, mutable chunk size is supported. + * If typed array used, chunk size must be fixed. + */ + function DefaultDataProvider(source, dimSize) { + if (!Source.isInstance(source)) { + source = Source.seriesDataToSource(source); + } + this._source = source; + + var data = this._data = source.data; + var sourceFormat = source.sourceFormat; + + // Typed array. TODO IE10+? + if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { + if (__DEV__) { + if (dimSize == null) { + throw new Error('Typed array data must specify dimension size'); + } + } + this._offset = 0; + this._dimSize = dimSize; + this._data = data; + } + + var methods = providerMethods[ + sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? + sourceFormat + '_' + source.seriesLayoutBy : + sourceFormat + ]; + + if (__DEV__) { + assert$1(methods, 'Invalide sourceFormat: ' + sourceFormat); + } + + extend(this, methods); + } + + var providerProto = DefaultDataProvider.prototype; + // If data is pure without style configuration + providerProto.pure = false; + // If data is persistent and will not be released after use. + providerProto.persistent = true; + + // ???! FIXME legacy data provider do not has method getSource + providerProto.getSource = function() { + return this._source; + }; + + var providerMethods = { + + 'arrayRows_column': { + pure: true, + count: function() { + return Math.max(0, this._data.length - this._source.startIndex); + }, + getItem: function(idx) { + return this._data[idx + this._source.startIndex]; + }, + appendData: appendDataSimply + }, + + 'arrayRows_row': { + pure: true, + count: function() { + var row = this._data[0]; + return row ? Math.max(0, row.length - this._source.startIndex) : 0; + }, + getItem: function(idx) { + idx += this._source.startIndex; + var item = []; + var data = this._data; + for (var i = 0; i < data.length; i++) { + var row = data[i]; + item.push(row ? row[idx] : null); + } + return item; + }, + appendData: function() { + throw new Error('Do not support appendData when set seriesLayoutBy: "row".'); + } + }, + + 'objectRows': { + pure: true, + count: countSimply, + getItem: getItemSimply, + appendData: appendDataSimply + }, + + 'keyedColumns': { + pure: true, + count: function() { + var dimName = this._source.dimensionsDefine[0].name; + var col = this._data[dimName]; + return col ? col.length : 0; + }, + getItem: function(idx) { + var item = []; + var dims = this._source.dimensionsDefine; + for (var i = 0; i < dims.length; i++) { + var col = this._data[dims[i].name]; + item.push(col ? col[idx] : null); + } + return item; + }, + appendData: function(newData) { + var data = this._data; + each$1(newData, function(newCol, key) { + var oldCol = data[key] || (data[key] = []); + for (var i = 0; i < (newCol || []).length; i++) { + oldCol.push(newCol[i]); + } + }); + } + }, + + 'original': { + count: countSimply, + getItem: getItemSimply, + appendData: appendDataSimply + }, + + 'typedArray': { + persistent: false, + pure: true, + count: function() { + return this._data ? (this._data.length / this._dimSize) : 0; + }, + getItem: function(idx, out) { + idx = idx - this._offset; + out = out || []; + var offset = this._dimSize * idx; + for (var i = 0; i < this._dimSize; i++) { + out[i] = this._data[offset + i]; + } + return out; + }, + appendData: function(newData) { + if (__DEV__) { + assert$1( + isTypedArray(newData), + 'Added data must be TypedArray if data in initialization is TypedArray' + ); + } + + this._data = newData; + }, + + // Clean self if data is already used. + clean: function() { + // PENDING + this._offset += this.count(); + this._data = null; + } + } + }; + + function countSimply() { + return this._data.length; + } + + function getItemSimply(idx) { + return this._data[idx]; + } + + function appendDataSimply(newData) { + for (var i = 0; i < newData.length; i++) { + this._data.push(newData[i]); + } + } + + + + var rawValueGetters = { + + arrayRows: getRawValueSimply, + + objectRows: function(dataItem, dataIndex, dimIndex, dimName) { + return dimIndex != null ? dataItem[dimName] : dataItem; + }, + + keyedColumns: getRawValueSimply, + + original: function(dataItem, dataIndex, dimIndex, dimName) { + // FIXME + // In some case (markpoint in geo (geo-map.html)), dataItem + // is {coord: [...]} + var value = getDataItemValue(dataItem); + return (dimIndex == null || !(value instanceof Array)) ? + value : + value[dimIndex]; + }, + + typedArray: getRawValueSimply + }; + + function getRawValueSimply(dataItem, dataIndex, dimIndex, dimName) { + return dimIndex != null ? dataItem[dimIndex] : dataItem; + } + + + var defaultDimValueGetters = { + + arrayRows: getDimValueSimply, + + objectRows: function(dataItem, dimName, dataIndex, dimIndex) { + return converDataValue(dataItem[dimName], this._dimensionInfos[dimName]); + }, + + keyedColumns: getDimValueSimply, + + original: function(dataItem, dimName, dataIndex, dimIndex) { + // Performance sensitive, do not use modelUtil.getDataItemValue. + // If dataItem is an plain object with no value field, the var `value` + // will be assigned with the object, but it will be tread correctly + // in the `convertDataValue`. + var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value); + + // If any dataItem is like { value: 10 } + if (!this._rawData.pure && isDataItemOption(dataItem)) { + this.hasItemOption = true; + } + return converDataValue( + (value instanceof Array) ? + value[dimIndex] + // If value is a single number or something else not array. + : + value, + this._dimensionInfos[dimName] + ); + }, + + typedArray: function(dataItem, dimName, dataIndex, dimIndex) { + return dataItem[dimIndex]; + } + + }; + + function getDimValueSimply(dataItem, dimName, dataIndex, dimIndex) { + return converDataValue(dataItem[dimIndex], this._dimensionInfos[dimName]); + } + + /** + * This helper method convert value in data. + * @param {string|number|Date} value + * @param {Object|string} [dimInfo] If string (like 'x'), dimType defaults 'number'. + * If "dimInfo.ordinalParseAndSave", ordinal value can be parsed. + */ + function converDataValue(value, dimInfo) { + // Performance sensitive. + var dimType = dimInfo && dimInfo.type; + if (dimType === 'ordinal') { + // If given value is a category string + var ordinalMeta = dimInfo && dimInfo.ordinalMeta; + return ordinalMeta ? + ordinalMeta.parseAndCollect(value) : + value; + } + + if (dimType === 'time' + // spead up when using timestamp + && + typeof value !== 'number' && + value != null && + value !== '-' + ) { + value = +parseDate(value); + } + + // dimType defaults 'number'. + // If dimType is not ordinal and value is null or undefined or NaN or '-', + // parse to NaN. + return (value == null || value === '') ? + NaN + // If string (like '-'), using '+' parse to NaN + // If object, also parse to NaN + : + +value; + } + + // ??? FIXME can these logic be more neat: getRawValue, getRawDataItem, + // Consider persistent. + // Caution: why use raw value to display on label or tooltip? + // A reason is to avoid format. For example time value we do not know + // how to format is expected. More over, if stack is used, calculated + // value may be 0.91000000001, which have brings trouble to display. + // TODO: consider how to treat null/undefined/NaN when display? + /** + * @param {module:echarts/data/List} data + * @param {number} dataIndex + * @param {string|number} [dim] dimName or dimIndex + * @return {Array.|string|number} can be null/undefined. + */ + function retrieveRawValue(data, dataIndex, dim) { + if (!data) { + return; + } + + // Consider data may be not persistent. + var dataItem = data.getRawDataItem(dataIndex); + + if (dataItem == null) { + return; + } + + var sourceFormat = data.getProvider().getSource().sourceFormat; + var dimName; + var dimIndex; + + var dimInfo = data.getDimensionInfo(dim); + if (dimInfo) { + dimName = dimInfo.name; + dimIndex = dimInfo.index; + } + + return rawValueGetters[sourceFormat](dataItem, dataIndex, dimIndex, dimName); + } + + /** + * Compatible with some cases (in pie, map) like: + * data: [{name: 'xx', value: 5, selected: true}, ...] + * where only sourceFormat is 'original' and 'objectRows' supported. + * + * ??? TODO + * Supported detail options in data item when using 'arrayRows'. + * + * @param {module:echarts/data/List} data + * @param {number} dataIndex + * @param {string} attr like 'selected' + */ + function retrieveRawAttr(data, dataIndex, attr) { + if (!data) { + return; + } + + var sourceFormat = data.getProvider().getSource().sourceFormat; + + if (sourceFormat !== SOURCE_FORMAT_ORIGINAL && + sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS + ) { + return; + } + + var dataItem = data.getRawDataItem(dataIndex); + if (sourceFormat === SOURCE_FORMAT_ORIGINAL && !isObject$1(dataItem)) { + dataItem = null; + } + if (dataItem) { + return dataItem[attr]; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var DIMENSION_LABEL_REG = /\{@(.+?)\}/g; + + // PENDING A little ugly + var dataFormatMixin = { + /** + * Get params for formatter + * @param {number} dataIndex + * @param {string} [dataType] + * @return {Object} + */ + getDataParams: function(dataIndex, dataType) { + var data = this.getData(dataType); + var rawValue = this.getRawValue(dataIndex, dataType); + var rawDataIndex = data.getRawIndex(dataIndex); + var name = data.getName(dataIndex); + var itemOpt = data.getRawDataItem(dataIndex); + var color = data.getItemVisual(dataIndex, 'color'); + + return { + componentType: this.mainType, + componentSubType: this.subType, + seriesType: this.mainType === 'series' ? this.subType : null, + seriesIndex: this.seriesIndex, + seriesId: this.id, + seriesName: this.name, + name: name, + dataIndex: rawDataIndex, + data: itemOpt, + dataType: dataType, + value: rawValue, + color: color, + marker: getTooltipMarker(color), + + // Param name list for mapping `a`, `b`, `c`, `d`, `e` + $vars: ['seriesName', 'name', 'value'] + }; + }, + + /** + * Format label + * @param {number} dataIndex + * @param {string} [status='normal'] 'normal' or 'emphasis' + * @param {string} [dataType] + * @param {number} [dimIndex] + * @param {string} [labelProp='label'] + * @return {string} If not formatter, return null/undefined + */ + getFormattedLabel: function(dataIndex, status, dataType, dimIndex, labelProp) { + status = status || 'normal'; + var data = this.getData(dataType); + var itemModel = data.getItemModel(dataIndex); + + var params = this.getDataParams(dataIndex, dataType); + if (dimIndex != null && (params.value instanceof Array)) { + params.value = params.value[dimIndex]; + } + + var formatter = itemModel.get( + status === 'normal' ? + [labelProp || 'label', 'formatter'] : + [status, labelProp || 'label', 'formatter'] + ); + + if (typeof formatter === 'function') { + params.status = status; + return formatter(params); + } else if (typeof formatter === 'string') { + var str = formatTpl(formatter, params); + + // Support 'aaa{@[3]}bbb{@product}ccc'. + // Do not support '}' in dim name util have to. + return str.replace(DIMENSION_LABEL_REG, function(origin, dim) { + var len = dim.length; + if (dim.charAt(0) === '[' && dim.charAt(len - 1) === ']') { + dim = +dim.slice(1, len - 1); // Also: '[]' => 0 + } + return retrieveRawValue(data, dataIndex, dim); + }); + } + }, + + /** + * Get raw value in option + * @param {number} idx + * @param {string} [dataType] + * @return {Array|number|string} + */ + getRawValue: function(idx, dataType) { + return retrieveRawValue(this.getData(dataType), idx); + }, + + /** + * Should be implemented. + * @param {number} dataIndex + * @param {boolean} [multipleSeries=false] + * @param {number} [dataType] + * @return {string} tooltip string + */ + formatTooltip: function() { + // Empty function + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {Object} define + * @return See the return of `createTask`. + */ + function createTask(define) { + return new Task(define); + } + + /** + * @constructor + * @param {Object} define + * @param {Function} define.reset Custom reset + * @param {Function} [define.plan] Returns 'reset' indicate reset immediately. + * @param {Function} [define.count] count is used to determin data task. + * @param {Function} [define.onDirty] count is used to determin data task. + */ + function Task(define) { + define = define || {}; + + this._reset = define.reset; + this._plan = define.plan; + this._count = define.count; + this._onDirty = define.onDirty; + + this._dirty = true; + + // Context must be specified implicitly, to + // avoid miss update context when model changed. + this.context; + } + + var taskProto = Task.prototype; + + /** + * @param {Object} performArgs + * @param {number} [performArgs.step] Specified step. + * @param {number} [performArgs.skip] Skip customer perform call. + * @param {number} [performArgs.modBy] Sampling window size. + * @param {number} [performArgs.modDataCount] Sampling count. + */ + taskProto.perform = function(performArgs) { + var upTask = this._upstream; + var skip = performArgs && performArgs.skip; + + // TODO some refactor. + // Pull data. Must pull data each time, because context.data + // may be updated by Series.setData. + if (this._dirty && upTask) { + var context = this.context; + context.data = context.outputData = upTask.context.outputData; + } + + if (this.__pipeline) { + this.__pipeline.currentTask = this; + } + + var planResult; + if (this._plan && !skip) { + planResult = this._plan(this.context); + } + + // Support sharding by mod, which changes the render sequence and makes the rendered graphic + // elements uniformed distributed when progress, especially when moving or zooming. + var lastModBy = normalizeModBy(this._modBy); + var lastModDataCount = this._modDataCount || 0; + var modBy = normalizeModBy(performArgs && performArgs.modBy); + var modDataCount = performArgs && performArgs.modDataCount || 0; + if (lastModBy !== modBy || lastModDataCount !== modDataCount) { + planResult = 'reset'; + } + + function normalizeModBy(val) { + !(val >= 1) && (val = 1); // jshint ignore:line + return val; + } + + var forceFirstProgress; + if (this._dirty || planResult === 'reset') { + this._dirty = false; + forceFirstProgress = reset(this, skip); + } + + this._modBy = modBy; + this._modDataCount = modDataCount; + + var step = performArgs && performArgs.step; + + if (upTask) { + + if (__DEV__) { + assert$1(upTask._outputDueEnd != null); + } + this._dueEnd = upTask._outputDueEnd; + } + // DataTask or overallTask + else { + if (__DEV__) { + assert$1(!this._progress || this._count); + } + this._dueEnd = this._count ? this._count(this.context) : Infinity; + } + + // Note: Stubs, that its host overall task let it has progress, has progress. + // If no progress, pass index from upstream to downstream each time plan called. + if (this._progress) { + var start = this._dueIndex; + var end = Math.min( + step != null ? this._dueIndex + step : Infinity, + this._dueEnd + ); + + if (!skip && (forceFirstProgress || start < end)) { + var progress = this._progress; + if (isArray(progress)) { + for (var i = 0; i < progress.length; i++) { + doProgress(this, progress[i], start, end, modBy, modDataCount); + } + } else { + doProgress(this, progress, start, end, modBy, modDataCount); + } + } + + this._dueIndex = end; + // If no `outputDueEnd`, assume that output data and + // input data is the same, so use `dueIndex` as `outputDueEnd`. + var outputDueEnd = this._settedOutputEnd != null ? + this._settedOutputEnd : end; + + if (__DEV__) { + // ??? Can not rollback. + assert$1(outputDueEnd >= this._outputDueEnd); + } + + this._outputDueEnd = outputDueEnd; + } else { + // (1) Some overall task has no progress. + // (2) Stubs, that its host overall task do not let it has progress, has no progress. + // This should always be performed so it can be passed to downstream. + this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null ? + this._settedOutputEnd : this._dueEnd; + } + + return this.unfinished(); + }; + + var iterator = (function() { + + var end; + var current; + var modBy; + var modDataCount; + var winCount; + + var it = { + reset: function(s, e, sStep, sCount) { + current = s; + end = e; + + modBy = sStep; + modDataCount = sCount; + winCount = Math.ceil(modDataCount / modBy); + + it.next = (modBy > 1 && modDataCount > 0) ? modNext : sequentialNext; + } + }; + + return it; + + function sequentialNext() { + return current < end ? current++ : null; + } + + function modNext() { + var dataIndex = (current % winCount) * modBy + Math.ceil(current / winCount); + var result = current >= end ? + null : + dataIndex < modDataCount ? + dataIndex + // If modDataCount is smaller than data.count() (consider `appendData` case), + // Use normal linear rendering mode. + : + current; + current++; + return result; + } + })(); + + taskProto.dirty = function() { + this._dirty = true; + this._onDirty && this._onDirty(this.context); + }; + + function doProgress(taskIns, progress, start, end, modBy, modDataCount) { + iterator.reset(start, end, modBy, modDataCount); + taskIns._callingProgress = progress; + taskIns._callingProgress({ + start: start, + end: end, + count: end - start, + next: iterator.next + }, taskIns.context); + } + + function reset(taskIns, skip) { + taskIns._dueIndex = taskIns._outputDueEnd = taskIns._dueEnd = 0; + taskIns._settedOutputEnd = null; + + var progress; + var forceFirstProgress; + + if (!skip && taskIns._reset) { + progress = taskIns._reset(taskIns.context); + if (progress && progress.progress) { + forceFirstProgress = progress.forceFirstProgress; + progress = progress.progress; + } + // To simplify no progress checking, array must has item. + if (isArray(progress) && !progress.length) { + progress = null; + } + } + + taskIns._progress = progress; + taskIns._modBy = taskIns._modDataCount = null; + + var downstream = taskIns._downstream; + downstream && downstream.dirty(); + + return forceFirstProgress; + } + + /** + * @return {boolean} + */ + taskProto.unfinished = function() { + return this._progress && this._dueIndex < this._dueEnd; + }; + + /** + * @param {Object} downTask The downstream task. + * @return {Object} The downstream task. + */ + taskProto.pipe = function(downTask) { + if (__DEV__) { + assert$1(downTask && !downTask._disposed && downTask !== this); + } + + // If already downstream, do not dirty downTask. + if (this._downstream !== downTask || this._dirty) { + this._downstream = downTask; + downTask._upstream = this; + downTask.dirty(); + } + }; + + taskProto.dispose = function() { + if (this._disposed) { + return; + } + + this._upstream && (this._upstream._downstream = null); + this._downstream && (this._downstream._upstream = null); + + this._dirty = false; + this._disposed = true; + }; + + taskProto.getUpstream = function() { + return this._upstream; + }; + + taskProto.getDownstream = function() { + return this._downstream; + }; + + taskProto.setOutputEnd = function(end) { + // This only happend in dataTask, dataZoom, map, currently. + // where dataZoom do not set end each time, but only set + // when reset. So we should record the setted end, in case + // that the stub of dataZoom perform again and earse the + // setted end by upstream. + this._outputDueEnd = this._settedOutputEnd = end; + }; + + + /////////////////////////////////////////////////////////// + // For stream debug (Should be commented out after used!) + // Usage: printTask(this, 'begin'); + // Usage: printTask(this, null, {someExtraProp}); + // function printTask(task, prefix, extra) { + // window.ecTaskUID == null && (window.ecTaskUID = 0); + // task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`); + // task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`); + // var props = []; + // if (task.__pipeline) { + // var val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`; + // props.push({text: 'idx', value: val}); + // } else { + // var stubCount = 0; + // task.agentStubMap.each(() => stubCount++); + // props.push({text: 'idx', value: `overall (stubs: ${stubCount})`}); + // } + // props.push({text: 'uid', value: task.uidDebug}); + // if (task.__pipeline) { + // props.push({text: 'pid', value: task.__pipeline.id}); + // task.agent && props.push( + // {text: 'stubFor', value: task.agent.uidDebug} + // ); + // } + // props.push( + // {text: 'dirty', value: task._dirty}, + // {text: 'dueIndex', value: task._dueIndex}, + // {text: 'dueEnd', value: task._dueEnd}, + // {text: 'outputDueEnd', value: task._outputDueEnd} + // ); + // if (extra) { + // Object.keys(extra).forEach(key => { + // props.push({text: key, value: extra[key]}); + // }); + // } + // var args = ['color: blue']; + // var msg = `%c[${prefix || 'T'}] %c` + props.map(item => ( + // args.push('color: black', 'color: red'), + // `${item.text}: %c${item.value}` + // )).join('%c, '); + // console.log.apply(console, [msg].concat(args)); + // // console.log(this); + // } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$4 = makeInner(); + + var SeriesModel = ComponentModel.extend({ + + type: 'series.__base__', + + /** + * @readOnly + */ + seriesIndex: 0, + + // coodinateSystem will be injected in the echarts/CoordinateSystem + coordinateSystem: null, + + /** + * @type {Object} + * @protected + */ + defaultOption: null, + + /** + * Data provided for legend + * @type {Function} + */ + // PENDING + legendDataProvider: null, + + /** + * Access path of color for visual + */ + visualColorAccessPath: 'itemStyle.color', + + /** + * Support merge layout params. + * Only support 'box' now (left/right/top/bottom/width/height). + * @type {string|Object} Object can be {ignoreSize: true} + * @readOnly + */ + layoutMode: null, + + init: function(option, parentModel, ecModel, extraOpt) { + + /** + * @type {number} + * @readOnly + */ + this.seriesIndex = this.componentIndex; + + this.dataTask = createTask({ + count: dataTaskCount, + reset: dataTaskReset + }); + this.dataTask.context = { + model: this + }; + + this.mergeDefaultAndTheme(option, ecModel); + + prepareSource(this); + + + var data = this.getInitialData(option, ecModel); + wrapData(data, this); + this.dataTask.context.data = data; + + if (__DEV__) { + assert$1(data, 'getInitialData returned invalid data.'); + } + + /** + * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph} + * @private + */ + inner$4(this).dataBeforeProcessed = data; + + // If we reverse the order (make data firstly, and then make + // dataBeforeProcessed by cloneShallow), cloneShallow will + // cause data.graph.data !== data when using + // module:echarts/data/Graph or module:echarts/data/Tree. + // See module:echarts/data/helper/linkList + + // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model + // init or merge stage, because the data can be restored. So we do not `restoreData` + // and `setData` here, which forbids calling `seriesModel.getData()` in this stage. + // Call `seriesModel.getRawData()` instead. + // this.restoreData(); + + autoSeriesName(this); + }, + + /** + * Util for merge default and theme to option + * @param {Object} option + * @param {module:echarts/model/Global} ecModel + */ + mergeDefaultAndTheme: function(option, ecModel) { + var layoutMode = this.layoutMode; + var inputPositionParams = layoutMode ? + getLayoutParams(option) : {}; + + // Backward compat: using subType on theme. + // But if name duplicate between series subType + // (for example: parallel) add component mainType, + // add suffix 'Series'. + var themeSubType = this.subType; + if (ComponentModel.hasClass(themeSubType)) { + themeSubType += 'Series'; + } + merge( + option, + ecModel.getTheme().get(this.subType) + ); + merge(option, this.getDefaultOption()); + + // Default label emphasis `show` + defaultEmphasis(option, 'label', ['show']); + + this.fillDataTextStyle(option.data); + + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }, + + mergeOption: function(newSeriesOption, ecModel) { + // this.settingTask.dirty(); + + newSeriesOption = merge(this.option, newSeriesOption, true); + this.fillDataTextStyle(newSeriesOption.data); + + var layoutMode = this.layoutMode; + if (layoutMode) { + mergeLayoutParam(this.option, newSeriesOption, layoutMode); + } + + prepareSource(this); + + var data = this.getInitialData(newSeriesOption, ecModel); + wrapData(data, this); + this.dataTask.dirty(); + this.dataTask.context.data = data; + + inner$4(this).dataBeforeProcessed = data; + + autoSeriesName(this); + }, + + fillDataTextStyle: function(data) { + // Default data label emphasis `show` + // FIXME Tree structure data ? + // FIXME Performance ? + if (data && !isTypedArray(data)) { + var props = ['show']; + for (var i = 0; i < data.length; i++) { + if (data[i] && data[i].label) { + defaultEmphasis(data[i], 'label', props); + } + } + } + }, + + /** + * Init a data structure from data related option in series + * Must be overwritten + */ + getInitialData: function() {}, + + /** + * Append data to list + * @param {Object} params + * @param {Array|TypedArray} params.data + */ + appendData: function(params) { + // FIXME ??? + // (1) If data from dataset, forbidden append. + // (2) support append data of dataset. + var data = this.getRawData(); + data.appendData(params.data); + }, + + /** + * Consider some method like `filter`, `map` need make new data, + * We should make sure that `seriesModel.getData()` get correct + * data in the stream procedure. So we fetch data from upstream + * each time `task.perform` called. + * @param {string} [dataType] + * @return {module:echarts/data/List} + */ + getData: function(dataType) { + var task = getCurrentTask(this); + if (task) { + var data = task.context.data; + return dataType == null ? data : data.getLinkedData(dataType); + } else { + // When series is not alive (that may happen when click toolbox + // restore or setOption with not merge mode), series data may + // be still need to judge animation or something when graphic + // elements want to know whether fade out. + return inner$4(this).data; + } + }, + + /** + * @param {module:echarts/data/List} data + */ + setData: function(data) { + var task = getCurrentTask(this); + if (task) { + var context = task.context; + // Consider case: filter, data sample. + if (context.data !== data && task.modifyOutputEnd) { + task.setOutputEnd(data.count()); + } + context.outputData = data; + // Caution: setData should update context.data, + // Because getData may be called multiply in a + // single stage and expect to get the data just + // set. (For example, AxisProxy, x y both call + // getData and setDate sequentially). + // So the context.data should be fetched from + // upstream each time when a stage starts to be + // performed. + if (task !== this.dataTask) { + context.data = data; + } + } + inner$4(this).data = data; + }, + + /** + * @see {module:echarts/data/helper/sourceHelper#getSource} + * @return {module:echarts/data/Source} source + */ + getSource: function() { + return getSource(this); + }, + + /** + * Get data before processed + * @return {module:echarts/data/List} + */ + getRawData: function() { + return inner$4(this).dataBeforeProcessed; + }, + + /** + * Get base axis if has coordinate system and has axis. + * By default use coordSys.getBaseAxis(); + * Can be overrided for some chart. + * @return {type} description + */ + getBaseAxis: function() { + var coordSys = this.coordinateSystem; + return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis(); + }, + + // FIXME + /** + * Default tooltip formatter + * + * @param {number} dataIndex + * @param {boolean} [multipleSeries=false] + * @param {number} [dataType] + */ + formatTooltip: function(dataIndex, multipleSeries, dataType) { + + function formatArrayValue(value) { + // ??? TODO refactor these logic. + // check: category-no-encode-has-axis-data in dataset.html + var vertially = reduce(value, function(vertially, val, idx) { + var dimItem = data.getDimensionInfo(idx); + return vertially |= dimItem && dimItem.tooltip !== false && dimItem.displayName != null; + }, 0); + + var result = []; + + tooltipDims.length ? + each$1(tooltipDims, function(dim) { + setEachItem(retrieveRawValue(data, dataIndex, dim), dim); + }) + // By default, all dims is used on tooltip. + : + each$1(value, setEachItem); + + function setEachItem(val, dim) { + var dimInfo = data.getDimensionInfo(dim); + // If `dimInfo.tooltip` is not set, show tooltip. + if (!dimInfo || dimInfo.otherDims.tooltip === false) { + return; + } + var dimType = dimInfo.type; + var dimHead = getTooltipMarker({ + color: color, + type: 'subItem' + }); + var valStr = (vertially ? + dimHead + encodeHTML(dimInfo.displayName || '-') + ': ' : + '' + ) + // FIXME should not format time for raw data? + + + encodeHTML(dimType === 'ordinal' ? + val + '' : + dimType === 'time' ? + (multipleSeries ? '' : formatTime('yyyy/MM/dd hh:mm:ss', val)) : + addCommas(val) + ); + valStr && result.push(valStr); + } + + return (vertially ? '
' : '') + result.join(vertially ? '
' : ', '); + } + + function formatSingleValue(val) { + return encodeHTML(addCommas(val)); + } + + var data = this.getData(); + var tooltipDims = data.mapDimension('defaultedTooltip', true); + var tooltipDimLen = tooltipDims.length; + var value = this.getRawValue(dataIndex); + var isValueArr = isArray(value); + + var color = data.getItemVisual(dataIndex, 'color'); + if (isObject$1(color) && color.colorStops) { + color = (color.colorStops[0] || {}).color; + } + color = color || 'transparent'; + + // Complicated rule for pretty tooltip. + var formattedValue = (tooltipDimLen > 1 || (isValueArr && !tooltipDimLen)) ? + formatArrayValue(value) : + tooltipDimLen ? + formatSingleValue(retrieveRawValue(data, dataIndex, tooltipDims[0])) : + formatSingleValue(isValueArr ? value[0] : value); + + var colorEl = getTooltipMarker(color); + + var name = data.getName(dataIndex); + + var seriesName = this.name; + if (!isNameSpecified(this)) { + seriesName = ''; + } + seriesName = seriesName ? + encodeHTML(seriesName) + (!multipleSeries ? '
' : ': ') : + ''; + + return !multipleSeries ? + seriesName + colorEl + + (name ? + encodeHTML(name) + ': ' + formattedValue : + formattedValue + ) : + colorEl + seriesName + formattedValue; + }, + + /** + * @return {boolean} + */ + isAnimationEnabled: function() { + if (env$1.node) { + return false; + } + + var animationEnabled = this.getShallow('animation'); + if (animationEnabled) { + if (this.getData().count() > this.getShallow('animationThreshold')) { + animationEnabled = false; + } + } + return animationEnabled; + }, + + restoreData: function() { + this.dataTask.dirty(); + }, + + getColorFromPalette: function(name, scope, requestColorNum) { + var ecModel = this.ecModel; + // PENDING + var color = colorPaletteMixin.getColorFromPalette.call(this, name, scope, requestColorNum); + if (!color) { + color = ecModel.getColorFromPalette(name, scope, requestColorNum); + } + return color; + }, + + /** + * Use `data.mapDimension(coordDim, true)` instead. + * @deprecated + */ + coordDimToDataDim: function(coordDim) { + return this.getRawData().mapDimension(coordDim, true); + }, + + /** + * Get progressive rendering count each step + * @return {number} + */ + getProgressive: function() { + return this.get('progressive'); + }, + + /** + * Get progressive rendering count each step + * @return {number} + */ + getProgressiveThreshold: function() { + return this.get('progressiveThreshold'); + }, + + /** + * Get data indices for show tooltip content. See tooltip. + * @abstract + * @param {Array.|string} dim + * @param {Array.} value + * @param {module:echarts/coord/single/SingleAxis} baseAxis + * @return {Object} {dataIndices, nestestValue}. + */ + getAxisTooltipData: null, + + /** + * See tooltip. + * @abstract + * @param {number} dataIndex + * @return {Array.} Point of tooltip. null/undefined can be returned. + */ + getTooltipPosition: null, + + /** + * @see {module:echarts/stream/Scheduler} + */ + pipeTask: null, + + /** + * Convinient for override in extended class. + * @protected + * @type {Function} + */ + preventIncremental: null, + + /** + * @public + * @readOnly + * @type {Object} + */ + pipelineContext: null + + }); + + + mixin(SeriesModel, dataFormatMixin); + mixin(SeriesModel, colorPaletteMixin); + + /** + * MUST be called after `prepareSource` called + * Here we need to make auto series, especially for auto legend. But we + * do not modify series.name in option to avoid side effects. + */ + function autoSeriesName(seriesModel) { + // User specified name has higher priority, otherwise it may cause + // series can not be queried unexpectedly. + var name = seriesModel.name; + if (!isNameSpecified(seriesModel)) { + seriesModel.name = getSeriesAutoName(seriesModel) || name; + } + } + + function getSeriesAutoName(seriesModel) { + var data = seriesModel.getRawData(); + var dataDims = data.mapDimension('seriesName', true); + var nameArr = []; + each$1(dataDims, function(dataDim) { + var dimInfo = data.getDimensionInfo(dataDim); + dimInfo.displayName && nameArr.push(dimInfo.displayName); + }); + return nameArr.join(' '); + } + + function dataTaskCount(context) { + return context.model.getRawData().count(); + } + + function dataTaskReset(context) { + var seriesModel = context.model; + seriesModel.setData(seriesModel.getRawData().cloneShallow()); + return dataTaskProgress; + } + + function dataTaskProgress(param, context) { + // Avoid repead cloneShallow when data just created in reset. + if (param.end > context.outputData.count()) { + context.model.getRawData().cloneShallow(context.outputData); + } + } + + // TODO refactor + function wrapData(data, seriesModel) { + each$1(data.CHANGABLE_METHODS, function(methodName) { + data.wrapMethod(methodName, curry(onDataSelfChange, seriesModel)); + }); + } + + function onDataSelfChange(seriesModel) { + var task = getCurrentTask(seriesModel); + if (task) { + // Consider case: filter, selectRange + task.setOutputEnd(this.count()); + } + } + + function getCurrentTask(seriesModel) { + var scheduler = (seriesModel.ecModel || {}).scheduler; + var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid); + + if (pipeline) { + // When pipline finished, the currrentTask keep the last + // task (renderTask). + var task = pipeline.currentTask; + if (task) { + var agentStubMap = task.agentStubMap; + if (agentStubMap) { + task = agentStubMap.get(seriesModel.uid); + } + } + return task; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var Component = function() { + /** + * @type {module:zrender/container/Group} + * @readOnly + */ + this.group = new Group(); + + /** + * @type {string} + * @readOnly + */ + this.uid = getUID('viewComponent'); + }; + + Component.prototype = { + + constructor: Component, + + init: function(ecModel, api) {}, + + render: function(componentModel, ecModel, api, payload) {}, + + dispose: function() {} + + }; + + var componentProto = Component.prototype; + componentProto.updateView = componentProto.updateLayout = componentProto.updateVisual = function(seriesModel, + ecModel, api, payload) { + // Do nothing; + }; + // Enable Component.extend. + enableClassExtend(Component); + + // Enable capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on. + enableClassManagement(Component, { + registerWhenExtend: true + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @return {string} If large mode changed, return string 'reset'; + */ + var createRenderPlanner = function() { + var inner = makeInner(); + + return function(seriesModel) { + var fields = inner(seriesModel); + var pipelineContext = seriesModel.pipelineContext; + + var originalLarge = fields.large; + var originalProgressive = fields.progressiveRender; + + var large = fields.large = pipelineContext.large; + var progressive = fields.progressiveRender = pipelineContext.progressiveRender; + + return !!((originalLarge ^ large) || (originalProgressive ^ progressive)) && 'reset'; + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$5 = makeInner(); + var renderPlanner = createRenderPlanner(); + + function Chart() { + + /** + * @type {module:zrender/container/Group} + * @readOnly + */ + this.group = new Group(); + + /** + * @type {string} + * @readOnly + */ + this.uid = getUID('viewChart'); + + this.renderTask = createTask({ + plan: renderTaskPlan, + reset: renderTaskReset + }); + this.renderTask.context = { + view: this + }; + } + + Chart.prototype = { + + type: 'chart', + + /** + * Init the chart. + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + init: function(ecModel, api) {}, + + /** + * Render the chart. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + render: function(seriesModel, ecModel, api, payload) {}, + + /** + * Highlight series or specified data item. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + highlight: function(seriesModel, ecModel, api, payload) { + toggleHighlight(seriesModel.getData(), payload, 'emphasis'); + }, + + /** + * Downplay series or specified data item. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + downplay: function(seriesModel, ecModel, api, payload) { + toggleHighlight(seriesModel.getData(), payload, 'normal'); + }, + + /** + * Remove self. + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + remove: function(ecModel, api) { + this.group.removeAll(); + }, + + /** + * Dispose self. + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + dispose: function() {}, + + /** + * Rendering preparation in progressive mode. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + incrementalPrepareRender: null, + + /** + * Render in progressive mode. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + incrementalRender: null, + + /** + * Update transform directly. + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + * @return {Object} {update: true} + */ + updateTransform: null + + /** + * The view contains the given point. + * @interface + * @param {Array.} point + * @return {boolean} + */ + // containPoint: function () {} + + }; + + var chartProto = Chart.prototype; + chartProto.updateView = chartProto.updateLayout = chartProto.updateVisual = function(seriesModel, ecModel, api, + payload) { + this.render(seriesModel, ecModel, api, payload); + }; + + /** + * Set state of single element + * @param {module:zrender/Element} el + * @param {string} state + */ + function elSetState(el, state) { + if (el) { + el.trigger(state); + if (el.type === 'group') { + for (var i = 0; i < el.childCount(); i++) { + elSetState(el.childAt(i), state); + } + } + } + } + /** + * @param {module:echarts/data/List} data + * @param {Object} payload + * @param {string} state 'normal'|'emphasis' + */ + function toggleHighlight(data, payload, state) { + var dataIndex = queryDataIndex(data, payload); + + if (dataIndex != null) { + each$1(normalizeToArray(dataIndex), function(dataIdx) { + elSetState(data.getItemGraphicEl(dataIdx), state); + }); + } else { + data.eachItemGraphicEl(function(el) { + elSetState(el, state); + }); + } + } + + // Enable Chart.extend. + enableClassExtend(Chart, ['dispose']); + + // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on. + enableClassManagement(Chart, { + registerWhenExtend: true + }); + + Chart.markUpdateMethod = function(payload, methodName) { + inner$5(payload).updateMethod = methodName; + }; + + function renderTaskPlan(context) { + return renderPlanner(context.model); + } + + function renderTaskReset(context) { + var seriesModel = context.model; + var ecModel = context.ecModel; + var api = context.api; + var payload = context.payload; + // ???! remove updateView updateVisual + var progressiveRender = seriesModel.pipelineContext.progressiveRender; + var view = context.view; + + var updateMethod = payload && inner$5(payload).updateMethod; + var methodName = progressiveRender ? + 'incrementalPrepareRender' : + (updateMethod && view[updateMethod]) ? + updateMethod + // `appendData` is also supported when data amount + // is less than progressive threshold. + : + 'render'; + + if (methodName !== 'render') { + view[methodName](seriesModel, ecModel, api, payload); + } + + return progressMethodMap[methodName]; + } + + var progressMethodMap = { + incrementalPrepareRender: { + progress: function(params, context) { + context.view.incrementalRender( + params, context.model, context.ecModel, context.api, context.payload + ); + } + }, + render: { + // Put view.render in `progress` to support appendData. But in this case + // view.render should not be called in reset, otherwise it will be called + // twise. Use `forceFirstProgress` to make sure that view.render is called + // in any cases. + forceFirstProgress: true, + progress: function(params, context) { + context.view.render( + context.model, context.ecModel, context.api, context.payload + ); + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var ORIGIN_METHOD = '\0__throttleOriginMethod'; + var RATE = '\0__throttleRate'; + var THROTTLE_TYPE = '\0__throttleType'; + + /** + * @public + * @param {(Function)} fn + * @param {number} [delay=0] Unit: ms. + * @param {boolean} [debounce=false] + * true: If call interval less than `delay`, only the last call works. + * false: If call interval less than `delay, call works on fixed rate. + * @return {(Function)} throttled fn. + */ + function throttle(fn, delay, debounce) { + + var currCall; + var lastCall = 0; + var lastExec = 0; + var timer = null; + var diff; + var scope; + var args; + var debounceNextCall; + + delay = delay || 0; + + function exec() { + lastExec = (new Date()).getTime(); + timer = null; + fn.apply(scope, args || []); + } + + var cb = function() { + currCall = (new Date()).getTime(); + scope = this; + args = arguments; + var thisDelay = debounceNextCall || delay; + var thisDebounce = debounceNextCall || debounce; + debounceNextCall = null; + diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay; + + clearTimeout(timer); + + // Here we should make sure that: the `exec` SHOULD NOT be called later + // than a new call of `cb`, that is, preserving the command order. Consider + // calculating "scale rate" when roaming as an example. When a call of `cb` + // happens, either the `exec` is called dierectly, or the call is delayed. + // But the delayed call should never be later than next call of `cb`. Under + // this assurance, we can simply update view state each time `dispatchAction` + // triggered by user roaming, but not need to add extra code to avoid the + // state being "rolled-back". + if (thisDebounce) { + timer = setTimeout(exec, thisDelay); + } else { + if (diff >= 0) { + exec(); + } else { + timer = setTimeout(exec, -diff); + } + } + + lastCall = currCall; + }; + + /** + * Clear throttle. + * @public + */ + cb.clear = function() { + if (timer) { + clearTimeout(timer); + timer = null; + } + }; + + /** + * Enable debounce once. + */ + cb.debounceNextCall = function(debounceDelay) { + debounceNextCall = debounceDelay; + }; + + return cb; + } + + /** + * Create throttle method or update throttle rate. + * + * @example + * ComponentView.prototype.render = function () { + * ... + * throttle.createOrUpdate( + * this, + * '_dispatchAction', + * this.model.get('throttle'), + * 'fixRate' + * ); + * }; + * ComponentView.prototype.remove = function () { + * throttle.clear(this, '_dispatchAction'); + * }; + * ComponentView.prototype.dispose = function () { + * throttle.clear(this, '_dispatchAction'); + * }; + * + * @public + * @param {Object} obj + * @param {string} fnAttr + * @param {number} [rate] + * @param {string} [throttleType='fixRate'] 'fixRate' or 'debounce' + * @return {Function} throttled function. + */ + function createOrUpdate(obj, fnAttr, rate, throttleType) { + var fn = obj[fnAttr]; + + if (!fn) { + return; + } + + var originFn = fn[ORIGIN_METHOD] || fn; + var lastThrottleType = fn[THROTTLE_TYPE]; + var lastRate = fn[RATE]; + + if (lastRate !== rate || lastThrottleType !== throttleType) { + if (rate == null || !throttleType) { + return (obj[fnAttr] = originFn); + } + + fn = obj[fnAttr] = throttle( + originFn, rate, throttleType === 'debounce' + ); + fn[ORIGIN_METHOD] = originFn; + fn[THROTTLE_TYPE] = throttleType; + fn[RATE] = rate; + } + + return fn; + } + + /** + * Clear throttle. Example see throttle.createOrUpdate. + * + * @public + * @param {Object} obj + * @param {string} fnAttr + */ + function clear(obj, fnAttr) { + var fn = obj[fnAttr]; + if (fn && fn[ORIGIN_METHOD]) { + obj[fnAttr] = fn[ORIGIN_METHOD]; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var seriesColor = { + createOnAllSeries: true, + performRawSeries: true, + reset: function(seriesModel, ecModel) { + var data = seriesModel.getData(); + var colorAccessPath = (seriesModel.visualColorAccessPath || 'itemStyle.color').split('.'); + var color = seriesModel.get(colorAccessPath) // Set in itemStyle + || + seriesModel.getColorFromPalette( + // TODO series count changed. + seriesModel.name, null, ecModel.getSeriesCount() + ); // Default color + + // FIXME Set color function or use the platte color + data.setVisual('color', color); + + // Only visible series has each data be visual encoded + if (!ecModel.isSeriesFiltered(seriesModel)) { + if (typeof color === 'function' && !(color instanceof Gradient)) { + data.each(function(idx) { + data.setItemVisual( + idx, 'color', color(seriesModel.getDataParams(idx)) + ); + }); + } + + // itemStyle in each data item + var dataEach = function(data, idx) { + var itemModel = data.getItemModel(idx); + var color = itemModel.get(colorAccessPath, true); + if (color != null) { + data.setItemVisual(idx, 'color', color); + } + }; + + return { + dataEach: data.hasItemOption ? dataEach : null + }; + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var lang = { + toolbox: { + brush: { + title: { + rect: '矩形选择', + polygon: '圈选', + lineX: '横向选择', + lineY: '纵向选择', + keep: '保持选择', + clear: '清除选择' + } + }, + dataView: { + title: '数据视图', + lang: ['数据视图', '关闭', '刷新'] + }, + dataZoom: { + title: { + zoom: '区域缩放', + back: '区域缩放还原' + } + }, + magicType: { + title: { + line: '切换为折线图', + bar: '切换为柱状图', + stack: '切换为堆叠', + tiled: '切换为平铺' + } + }, + restore: { + title: '还原' + }, + saveAsImage: { + title: '保存为图片', + lang: ['右键另存为图片'] + } + }, + series: { + typeNames: { + pie: '饼图', + bar: '柱状图', + line: '折线图', + scatter: '散点图', + effectScatter: '涟漪散点图', + radar: '雷达图', + tree: '树图', + treemap: '矩形树图', + boxplot: '箱型图', + candlestick: 'K线图', + k: 'K线图', + heatmap: '热力图', + map: '地图', + parallel: '平行坐标图', + lines: '线图', + graph: '关系图', + sankey: '桑基图', + funnel: '漏斗图', + gauge: '仪表盘图', + pictorialBar: '象形柱图', + themeRiver: '主题河流图', + sunburst: '旭日图' + } + }, + aria: { + general: { + withTitle: '这是一个关于“{title}”的图表。', + withoutTitle: '这是一个图表,' + }, + series: { + single: { + prefix: '', + withName: '图表类型是{seriesType},表示{seriesName}。', + withoutName: '图表类型是{seriesType}。' + }, + multiple: { + prefix: '它由{seriesCount}个图表系列组成。', + withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType},', + withoutName: '第{seriesId}个系列是一个{seriesType},', + separator: { + middle: ';', + end: '。' + } + } + }, + data: { + allData: '其数据是——', + partialData: '其中,前{displayCnt}项是——', + withName: '{name}的数据是{value}', + withoutName: '{value}', + separator: { + middle: ',', + end: '' + } + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var aria = function(dom, ecModel) { + var ariaModel = ecModel.getModel('aria'); + if (!ariaModel.get('show')) { + return; + } else if (ariaModel.get('description')) { + dom.setAttribute('aria-label', ariaModel.get('description')); + return; + } + + var seriesCnt = 0; + ecModel.eachSeries(function(seriesModel, idx) { + ++seriesCnt; + }, this); + + var maxDataCnt = ariaModel.get('data.maxCount') || 10; + var maxSeriesCnt = ariaModel.get('series.maxCount') || 10; + var displaySeriesCnt = Math.min(seriesCnt, maxSeriesCnt); + + var ariaLabel; + if (seriesCnt < 1) { + // No series, no aria label + return; + } else { + var title = getTitle(); + if (title) { + ariaLabel = replace(getConfig('general.withTitle'), { + title: title + }); + } else { + ariaLabel = getConfig('general.withoutTitle'); + } + + var seriesLabels = []; + var prefix = seriesCnt > 1 ? + 'series.multiple.prefix' : + 'series.single.prefix'; + ariaLabel += replace(getConfig(prefix), { + seriesCount: seriesCnt + }); + + ecModel.eachSeries(function(seriesModel, idx) { + if (idx < displaySeriesCnt) { + var seriesLabel; + + var seriesName = seriesModel.get('name'); + var seriesTpl = 'series.' + + (seriesCnt > 1 ? 'multiple' : 'single') + '.'; + seriesLabel = getConfig(seriesName ? + seriesTpl + 'withName' : + seriesTpl + 'withoutName'); + + seriesLabel = replace(seriesLabel, { + seriesId: seriesModel.seriesIndex, + seriesName: seriesModel.get('name'), + seriesType: getSeriesTypeName(seriesModel.subType) + }); + + var data = seriesModel.getData(); + window.data = data; + if (data.count() > maxDataCnt) { + // Show part of data + seriesLabel += replace(getConfig('data.partialData'), { + displayCnt: maxDataCnt + }); + } else { + seriesLabel += getConfig('data.allData'); + } + + var dataLabels = []; + for (var i = 0; i < data.count(); i++) { + if (i < maxDataCnt) { + var name = data.getName(i); + var value = retrieveRawValue(data, i); + dataLabels.push( + replace( + name ? + getConfig('data.withName') : + getConfig('data.withoutName'), { + name: name, + value: value + } + ) + ); + } + } + seriesLabel += dataLabels + .join(getConfig('data.separator.middle')) + + getConfig('data.separator.end'); + + seriesLabels.push(seriesLabel); + } + }); + + ariaLabel += seriesLabels + .join(getConfig('series.multiple.separator.middle')) + + getConfig('series.multiple.separator.end'); + + dom.setAttribute('aria-label', ariaLabel); + } + + function replace(str, keyValues) { + if (typeof str !== 'string') { + return str; + } + + var result = str; + each$1(keyValues, function(value, key) { + result = result.replace( + new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'), + value + ); + }); + return result; + } + + function getConfig(path) { + var userConfig = ariaModel.get(path); + if (userConfig == null) { + var pathArr = path.split('.'); + var result = lang.aria; + for (var i = 0; i < pathArr.length; ++i) { + result = result[pathArr[i]]; + } + return result; + } else { + return userConfig; + } + } + + function getTitle() { + var title = ecModel.getModel('title').option; + if (title && title.length) { + title = title[0]; + } + return title && title.text; + } + + function getSeriesTypeName(type) { + return lang.series.typeNames[type] || '自定义图'; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PI$1 = Math.PI; + + /** + * @param {module:echarts/ExtensionAPI} api + * @param {Object} [opts] + * @param {string} [opts.text] + * @param {string} [opts.color] + * @param {string} [opts.textColor] + * @return {module:zrender/Element} + */ + var loadingDefault = function(api, opts) { + opts = opts || {}; + defaults(opts, { + text: 'loading', + color: '#c23531', + textColor: '#000', + maskColor: 'rgba(255, 255, 255, 0.8)', + zlevel: 0 + }); + var mask = new Rect({ + style: { + fill: opts.maskColor + }, + zlevel: opts.zlevel, + z: 10000 + }); + var arc = new Arc({ + shape: { + startAngle: -PI$1 / 2, + endAngle: -PI$1 / 2 + 0.1, + r: 10 + }, + style: { + stroke: opts.color, + lineCap: 'round', + lineWidth: 5 + }, + zlevel: opts.zlevel, + z: 10001 + }); + var labelRect = new Rect({ + style: { + fill: 'none', + text: opts.text, + textPosition: 'right', + textDistance: 10, + textFill: opts.textColor + }, + zlevel: opts.zlevel, + z: 10001 + }); + + arc.animateShape(true) + .when(1000, { + endAngle: PI$1 * 3 / 2 + }) + .start('circularInOut'); + arc.animateShape(true) + .when(1000, { + startAngle: PI$1 * 3 / 2 + }) + .delay(300) + .start('circularInOut'); + + var group = new Group(); + group.add(arc); + group.add(labelRect); + group.add(mask); + // Inject resize + group.resize = function() { + var cx = api.getWidth() / 2; + var cy = api.getHeight() / 2; + arc.setShape({ + cx: cx, + cy: cy + }); + var r = arc.shape.r; + labelRect.setShape({ + x: cx - r, + y: cy - r, + width: r * 2, + height: r * 2 + }); + + mask.setShape({ + x: 0, + y: 0, + width: api.getWidth(), + height: api.getHeight() + }); + }; + group.resize(); + return group; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/stream/Scheduler + */ + + /** + * @constructor + */ + function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) { + this.ecInstance = ecInstance; + this.api = api; + this.unfinished; + + // Fix current processors in case that in some rear cases that + // processors might be registered after echarts instance created. + // Register processors incrementally for a echarts instance is + // not supported by this stream architecture. + var dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice(); + var visualHandlers = this._visualHandlers = visualHandlers.slice(); + this._allHandlers = dataProcessorHandlers.concat(visualHandlers); + + /** + * @private + * @type { + * [handlerUID: string]: { + * seriesTaskMap?: { + * [seriesUID: string]: Task + * }, + * overallTask?: Task + * } + * } + */ + this._stageTaskMap = createHashMap(); + } + + var proto = Scheduler.prototype; + + /** + * @param {module:echarts/model/Global} ecModel + * @param {Object} payload + */ + proto.restoreData = function(ecModel, payload) { + // TODO: Only restroe needed series and components, but not all components. + // Currently `restoreData` of all of the series and component will be called. + // But some independent components like `title`, `legend`, `graphic`, `toolbox`, + // `tooltip`, `axisPointer`, etc, do not need series refresh when `setOption`, + // and some components like coordinate system, axes, dataZoom, visualMap only + // need their target series refresh. + // (1) If we are implementing this feature some day, we should consider these cases: + // if a data processor depends on a component (e.g., dataZoomProcessor depends + // on the settings of `dataZoom`), it should be re-performed if the component + // is modified by `setOption`. + // (2) If a processor depends on sevral series, speicified by its `getTargetSeries`, + // it should be re-performed when the result array of `getTargetSeries` changed. + // We use `dependencies` to cover these issues. + // (3) How to update target series when coordinate system related components modified. + + // TODO: simply the dirty mechanism? Check whether only the case here can set tasks dirty, + // and this case all of the tasks will be set as dirty. + + ecModel.restoreData(payload); + + // Theoretically an overall task not only depends on each of its target series, but also + // depends on all of the series. + // The overall task is not in pipeline, and `ecModel.restoreData` only set pipeline tasks + // dirty. If `getTargetSeries` of an overall task returns nothing, we should also ensure + // that the overall task is set as dirty and to be performed, otherwise it probably cause + // state chaos. So we have to set dirty of all of the overall tasks manually, otherwise it + // probably cause state chaos (consider `dataZoomProcessor`). + this._stageTaskMap.each(function(taskRecord) { + var overallTask = taskRecord.overallTask; + overallTask && overallTask.dirty(); + }); + }; + + // If seriesModel provided, incremental threshold is check by series data. + proto.getPerformArgs = function(task, isBlock) { + // For overall task + if (!task.__pipeline) { + return; + } + + var pipeline = this._pipelineMap.get(task.__pipeline.id); + var pCtx = pipeline.context; + var incremental = !isBlock && + pipeline.progressiveEnabled && + (!pCtx || pCtx.progressiveRender) && + task.__idxInPipeline > pipeline.blockIndex; + + var step = incremental ? pipeline.step : null; + var modDataCount = pCtx && pCtx.modDataCount; + var modBy = modDataCount != null ? Math.ceil(modDataCount / step) : null; + + return { + step: step, + modBy: modBy, + modDataCount: modDataCount + }; + }; + + proto.getPipeline = function(pipelineId) { + return this._pipelineMap.get(pipelineId); + }; + + /** + * Current, progressive rendering starts from visual and layout. + * Always detect render mode in the same stage, avoiding that incorrect + * detection caused by data filtering. + * Caution: + * `updateStreamModes` use `seriesModel.getData()`. + */ + proto.updateStreamModes = function(seriesModel, view) { + var pipeline = this._pipelineMap.get(seriesModel.uid); + var data = seriesModel.getData(); + var dataLen = data.count(); + + // `progressiveRender` means that can render progressively in each + // animation frame. Note that some types of series do not provide + // `view.incrementalPrepareRender` but support `chart.appendData`. We + // use the term `incremental` but not `progressive` to describe the + // case that `chart.appendData`. + var progressiveRender = pipeline.progressiveEnabled && + view.incrementalPrepareRender && + dataLen >= pipeline.threshold; + + var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold'); + + // TODO: modDataCount should not updated if `appendData`, otherwise cause whole repaint. + // see `test/candlestick-large3.html` + var modDataCount = seriesModel.get('progressiveChunkMode') === 'mod' ? dataLen : null; + + seriesModel.pipelineContext = pipeline.context = { + progressiveRender: progressiveRender, + modDataCount: modDataCount, + large: large + }; + }; + + proto.restorePipelines = function(ecModel) { + var scheduler = this; + var pipelineMap = scheduler._pipelineMap = createHashMap(); + + ecModel.eachSeries(function(seriesModel) { + var progressive = seriesModel.getProgressive(); + var pipelineId = seriesModel.uid; + + pipelineMap.set(pipelineId, { + id: pipelineId, + head: null, + tail: null, + threshold: seriesModel.getProgressiveThreshold(), + progressiveEnabled: progressive && + !(seriesModel.preventIncremental && seriesModel.preventIncremental()), + blockIndex: -1, + step: Math.round(progressive || 700), + count: 0 + }); + + pipe(scheduler, seriesModel, seriesModel.dataTask); + }); + }; + + proto.prepareStageTasks = function() { + var stageTaskMap = this._stageTaskMap; + var ecModel = this.ecInstance.getModel(); + var api = this.api; + + each$1(this._allHandlers, function(handler) { + var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, []); + + handler.reset && createSeriesStageTask(this, handler, record, ecModel, api); + handler.overallReset && createOverallStageTask(this, handler, record, ecModel, api); + }, this); + }; + + proto.prepareView = function(view, model, ecModel, api) { + var renderTask = view.renderTask; + var context = renderTask.context; + + context.model = model; + context.ecModel = ecModel; + context.api = api; + + renderTask.__block = !view.incrementalPrepareRender; + + pipe(this, model, renderTask); + }; + + + proto.performDataProcessorTasks = function(ecModel, payload) { + // If we do not use `block` here, it should be considered when to update modes. + performStageTasks(this, this._dataProcessorHandlers, ecModel, payload, { + block: true + }); + }; + + // opt + // opt.visualType: 'visual' or 'layout' + // opt.setDirty + proto.performVisualTasks = function(ecModel, payload, opt) { + performStageTasks(this, this._visualHandlers, ecModel, payload, opt); + }; + + function performStageTasks(scheduler, stageHandlers, ecModel, payload, opt) { + opt = opt || {}; + var unfinished; + + each$1(stageHandlers, function(stageHandler, idx) { + if (opt.visualType && opt.visualType !== stageHandler.visualType) { + return; + } + + var stageHandlerRecord = scheduler._stageTaskMap.get(stageHandler.uid); + var seriesTaskMap = stageHandlerRecord.seriesTaskMap; + var overallTask = stageHandlerRecord.overallTask; + + if (overallTask) { + var overallNeedDirty; + var agentStubMap = overallTask.agentStubMap; + agentStubMap.each(function(stub) { + if (needSetDirty(opt, stub)) { + stub.dirty(); + overallNeedDirty = true; + } + }); + overallNeedDirty && overallTask.dirty(); + updatePayload(overallTask, payload); + var performArgs = scheduler.getPerformArgs(overallTask, opt.block); + // Execute stubs firstly, which may set the overall task dirty, + // then execute the overall task. And stub will call seriesModel.setData, + // which ensures that in the overallTask seriesModel.getData() will not + // return incorrect data. + agentStubMap.each(function(stub) { + stub.perform(performArgs); + }); + unfinished |= overallTask.perform(performArgs); + } else if (seriesTaskMap) { + seriesTaskMap.each(function(task, pipelineId) { + if (needSetDirty(opt, task)) { + task.dirty(); + } + var performArgs = scheduler.getPerformArgs(task, opt.block); + performArgs.skip = !stageHandler.performRawSeries && + ecModel.isSeriesFiltered(task.context.model); + updatePayload(task, payload); + unfinished |= task.perform(performArgs); + }); + } + }); + + function needSetDirty(opt, task) { + return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id)); + } + + scheduler.unfinished |= unfinished; + } + + proto.performSeriesTasks = function(ecModel) { + var unfinished; + + ecModel.eachSeries(function(seriesModel) { + // Progress to the end for dataInit and dataRestore. + unfinished |= seriesModel.dataTask.perform(); + }); + + this.unfinished |= unfinished; + }; + + proto.plan = function() { + // Travel pipelines, check block. + this._pipelineMap.each(function(pipeline) { + var task = pipeline.tail; + do { + if (task.__block) { + pipeline.blockIndex = task.__idxInPipeline; + break; + } + task = task.getUpstream(); + } + while (task); + }); + }; + + var updatePayload = proto.updatePayload = function(task, payload) { + payload !== 'remain' && (task.context.payload = payload); + }; + + function createSeriesStageTask(scheduler, stageHandler, stageHandlerRecord, ecModel, api) { + var seriesTaskMap = stageHandlerRecord.seriesTaskMap || + (stageHandlerRecord.seriesTaskMap = createHashMap()); + var seriesType = stageHandler.seriesType; + var getTargetSeries = stageHandler.getTargetSeries; + + // If a stageHandler should cover all series, `createOnAllSeries` should be declared mandatorily, + // to avoid some typo or abuse. Otherwise if an extension do not specify a `seriesType`, + // it works but it may cause other irrelevant charts blocked. + if (stageHandler.createOnAllSeries) { + ecModel.eachRawSeries(create); + } else if (seriesType) { + ecModel.eachRawSeriesByType(seriesType, create); + } else if (getTargetSeries) { + getTargetSeries(ecModel, api).each(create); + } + + function create(seriesModel) { + var pipelineId = seriesModel.uid; + + // Init tasks for each seriesModel only once. + // Reuse original task instance. + var task = seriesTaskMap.get(pipelineId) || + seriesTaskMap.set(pipelineId, createTask({ + plan: seriesTaskPlan, + reset: seriesTaskReset, + count: seriesTaskCount + })); + task.context = { + model: seriesModel, + ecModel: ecModel, + api: api, + useClearVisual: stageHandler.isVisual && !stageHandler.isLayout, + plan: stageHandler.plan, + reset: stageHandler.reset, + scheduler: scheduler + }; + pipe(scheduler, seriesModel, task); + } + + // Clear unused series tasks. + var pipelineMap = scheduler._pipelineMap; + seriesTaskMap.each(function(task, pipelineId) { + if (!pipelineMap.get(pipelineId)) { + task.dispose(); + seriesTaskMap.removeKey(pipelineId); + } + }); + } + + function createOverallStageTask(scheduler, stageHandler, stageHandlerRecord, ecModel, api) { + var overallTask = stageHandlerRecord.overallTask = stageHandlerRecord.overallTask + // For overall task, the function only be called on reset stage. + || + createTask({ + reset: overallTaskReset + }); + + overallTask.context = { + ecModel: ecModel, + api: api, + overallReset: stageHandler.overallReset, + scheduler: scheduler + }; + + // Reuse orignal stubs. + var agentStubMap = overallTask.agentStubMap = overallTask.agentStubMap || createHashMap(); + + var seriesType = stageHandler.seriesType; + var getTargetSeries = stageHandler.getTargetSeries; + var overallProgress = true; + var modifyOutputEnd = stageHandler.modifyOutputEnd; + + // An overall task with seriesType detected or has `getTargetSeries`, we add + // stub in each pipelines, it will set the overall task dirty when the pipeline + // progress. Moreover, to avoid call the overall task each frame (too frequent), + // we set the pipeline block. + if (seriesType) { + ecModel.eachRawSeriesByType(seriesType, createStub); + } else if (getTargetSeries) { + getTargetSeries(ecModel, api).each(createStub); + } + // Otherwise, (usually it is legancy case), the overall task will only be + // executed when upstream dirty. Otherwise the progressive rendering of all + // pipelines will be disabled unexpectedly. But it still needs stubs to receive + // dirty info from upsteam. + else { + overallProgress = false; + each$1(ecModel.getSeries(), createStub); + } + + function createStub(seriesModel) { + var pipelineId = seriesModel.uid; + var stub = agentStubMap.get(pipelineId); + if (!stub) { + stub = agentStubMap.set(pipelineId, createTask({ + reset: stubReset, + onDirty: stubOnDirty + })); + // When the result of `getTargetSeries` changed, the overallTask + // should be set as dirty and re-performed. + overallTask.dirty(); + } + stub.context = { + model: seriesModel, + overallProgress: overallProgress, + modifyOutputEnd: modifyOutputEnd + }; + stub.agent = overallTask; + stub.__block = overallProgress; + + pipe(scheduler, seriesModel, stub); + } + + // Clear unused stubs. + var pipelineMap = scheduler._pipelineMap; + agentStubMap.each(function(stub, pipelineId) { + if (!pipelineMap.get(pipelineId)) { + stub.dispose(); + // When the result of `getTargetSeries` changed, the overallTask + // should be set as dirty and re-performed. + overallTask.dirty(); + agentStubMap.removeKey(pipelineId); + } + }); + } + + function overallTaskReset(context) { + context.overallReset( + context.ecModel, context.api, context.payload + ); + } + + function stubReset(context, upstreamContext) { + return context.overallProgress && stubProgress; + } + + function stubProgress() { + this.agent.dirty(); + this.getDownstream().dirty(); + } + + function stubOnDirty() { + this.agent && this.agent.dirty(); + } + + function seriesTaskPlan(context) { + return context.plan && context.plan( + context.model, context.ecModel, context.api, context.payload + ); + } + + function seriesTaskReset(context) { + if (context.useClearVisual) { + context.data.clearAllVisual(); + } + var resetDefines = context.resetDefines = normalizeToArray(context.reset( + context.model, context.ecModel, context.api, context.payload + )); + return resetDefines.length > 1 ? + map(resetDefines, function(v, idx) { + return makeSeriesTaskProgress(idx); + }) : + singleSeriesTaskProgress; + } + + var singleSeriesTaskProgress = makeSeriesTaskProgress(0); + + function makeSeriesTaskProgress(resetDefineIdx) { + return function(params, context) { + var data = context.data; + var resetDefine = context.resetDefines[resetDefineIdx]; + + if (resetDefine && resetDefine.dataEach) { + for (var i = params.start; i < params.end; i++) { + resetDefine.dataEach(data, i); + } + } else if (resetDefine && resetDefine.progress) { + resetDefine.progress(params, data); + } + }; + } + + function seriesTaskCount(context) { + return context.data.count(); + } + + function pipe(scheduler, seriesModel, task) { + var pipelineId = seriesModel.uid; + var pipeline = scheduler._pipelineMap.get(pipelineId); + !pipeline.head && (pipeline.head = task); + pipeline.tail && pipeline.tail.pipe(task); + pipeline.tail = task; + task.__idxInPipeline = pipeline.count++; + task.__pipeline = pipeline; + } + + Scheduler.wrapStageHandler = function(stageHandler, visualType) { + if (isFunction$1(stageHandler)) { + stageHandler = { + overallReset: stageHandler, + seriesType: detectSeriseType(stageHandler) + }; + } + + stageHandler.uid = getUID('stageHandler'); + visualType && (stageHandler.visualType = visualType); + + return stageHandler; + }; + + + + /** + * Only some legacy stage handlers (usually in echarts extensions) are pure function. + * To ensure that they can work normally, they should work in block mode, that is, + * they should not be started util the previous tasks finished. So they cause the + * progressive rendering disabled. We try to detect the series type, to narrow down + * the block range to only the series type they concern, but not all series. + */ + function detectSeriseType(legacyFunc) { + seriesType = null; + try { + // Assume there is no async when calling `eachSeriesByType`. + legacyFunc(ecModelMock, apiMock); + } catch (e) {} + return seriesType; + } + + var ecModelMock = {}; + var apiMock = {}; + var seriesType; + + mockMethods(ecModelMock, GlobalModel); + mockMethods(apiMock, ExtensionAPI); + ecModelMock.eachSeriesByType = ecModelMock.eachRawSeriesByType = function(type) { + seriesType = type; + }; + ecModelMock.eachComponent = function(cond) { + if (cond.mainType === 'series' && cond.subType) { + seriesType = cond.subType; + } + }; + + function mockMethods(target, Clz) { + for (var name in Clz.prototype) { + // Do not use hasOwnProperty + target[name] = noop; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var colorAll = ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#E062AE', '#E690D1', + '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF' + ]; + + var lightTheme = { + + color: colorAll, + + colorLayer: [ + ['#37A2DA', '#ffd85c', '#fd7b5f'], + ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'], + ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'], + colorAll + ] + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var contrastColor = '#eee'; + var axisCommon = function() { + return { + axisLine: { + lineStyle: { + color: contrastColor + } + }, + axisTick: { + lineStyle: { + color: contrastColor + } + }, + axisLabel: { + textStyle: { + color: contrastColor + } + }, + splitLine: { + lineStyle: { + type: 'dashed', + color: '#aaa' + } + }, + splitArea: { + areaStyle: { + color: contrastColor + } + } + }; + }; + + var colorPalette = ['#dd6b66', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53', '#eedd78', '#73a373', '#73b9bc', + '#7289ab', '#91ca8c', '#f49f42' + ]; + var theme = { + color: colorPalette, + backgroundColor: '#333', + tooltip: { + axisPointer: { + lineStyle: { + color: contrastColor + }, + crossStyle: { + color: contrastColor + } + } + }, + legend: { + textStyle: { + color: contrastColor + } + }, + textStyle: { + color: contrastColor + }, + title: { + textStyle: { + color: contrastColor + } + }, + toolbox: { + iconStyle: { + normal: { + borderColor: contrastColor + } + } + }, + dataZoom: { + textStyle: { + color: contrastColor + } + }, + visualMap: { + textStyle: { + color: contrastColor + } + }, + timeline: { + lineStyle: { + color: contrastColor + }, + itemStyle: { + normal: { + color: colorPalette[1] + } + }, + label: { + normal: { + textStyle: { + color: contrastColor + } + } + }, + controlStyle: { + normal: { + color: contrastColor, + borderColor: contrastColor + } + } + }, + timeAxis: axisCommon(), + logAxis: axisCommon(), + valueAxis: axisCommon(), + categoryAxis: axisCommon(), + + line: { + symbol: 'circle' + }, + graph: { + color: colorPalette + }, + gauge: { + title: { + textStyle: { + color: contrastColor + } + } + }, + candlestick: { + itemStyle: { + normal: { + color: '#FD1050', + color0: '#0CF49B', + borderColor: '#FD1050', + borderColor0: '#0CF49B' + } + } + } + }; + theme.categoryAxis.splitLine.show = false; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * This module is imported by echarts directly. + * + * Notice: + * Always keep this file exists for backward compatibility. + * Because before 4.1.0, dataset is an optional component, + * some users may import this module manually. + */ + + ComponentModel.extend({ + + type: 'dataset', + + /** + * @protected + */ + defaultOption: { + + // 'row', 'column' + seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN, + + // null/'auto': auto detect header, see "module:echarts/data/helper/sourceHelper" + sourceHeader: null, + + dimensions: null, + + source: null + }, + + optionUpdated: function() { + detectSourceFormat(this); + } + + }); + + Component.extend({ + + type: 'dataset' + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var assert = assert$1; + var each = each$1; + var isFunction = isFunction$1; + var isObject = isObject$1; + var parseClassType = ComponentModel.parseClassType; + + var version = '4.1.0'; + + var dependencies = { + zrender: '4.0.4' + }; + + var TEST_FRAME_REMAIN_TIME = 1; + + var PRIORITY_PROCESSOR_FILTER = 1000; + var PRIORITY_PROCESSOR_STATISTIC = 5000; + + var PRIORITY_VISUAL_LAYOUT = 1000; + var PRIORITY_VISUAL_GLOBAL = 2000; + var PRIORITY_VISUAL_CHART = 3000; + var PRIORITY_VISUAL_COMPONENT = 4000; + // FIXME + // necessary? + var PRIORITY_VISUAL_BRUSH = 5000; + + var PRIORITY = { + PROCESSOR: { + FILTER: PRIORITY_PROCESSOR_FILTER, + STATISTIC: PRIORITY_PROCESSOR_STATISTIC + }, + VISUAL: { + LAYOUT: PRIORITY_VISUAL_LAYOUT, + GLOBAL: PRIORITY_VISUAL_GLOBAL, + CHART: PRIORITY_VISUAL_CHART, + COMPONENT: PRIORITY_VISUAL_COMPONENT, + BRUSH: PRIORITY_VISUAL_BRUSH + } + }; + + // Main process have three entries: `setOption`, `dispatchAction` and `resize`, + // where they must not be invoked nestedly, except the only case: invoke + // dispatchAction with updateMethod "none" in main process. + // This flag is used to carry out this rule. + // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]). + var IN_MAIN_PROCESS = '__flagInMainProcess'; + var OPTION_UPDATED = '__optionUpdated'; + var ACTION_REG = /^[a-zA-Z0-9_]+$/; + + + function createRegisterEventWithLowercaseName(method) { + return function(eventName, handler, context) { + // Event name is all lowercase + eventName = eventName && eventName.toLowerCase(); + Eventful.prototype[method].call(this, eventName, handler, context); + }; + } + + /** + * @module echarts~MessageCenter + */ + function MessageCenter() { + Eventful.call(this); + } + MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on'); + MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off'); + MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one'); + mixin(MessageCenter, Eventful); + + /** + * @module echarts~ECharts + */ + function ECharts(dom, theme$$1, opts) { + opts = opts || {}; + + // Get theme by name + if (typeof theme$$1 === 'string') { + theme$$1 = themeStorage[theme$$1]; + } + + /** + * @type {string} + */ + this.id; + + /** + * Group id + * @type {string} + */ + this.group; + + /** + * @type {HTMLElement} + * @private + */ + this._dom = dom; + + var defaultRenderer = 'canvas'; + if (__DEV__) { + defaultRenderer = ( + typeof window === 'undefined' ? global : window + ).__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer; + } + + /** + * @type {module:zrender/ZRender} + * @private + */ + var zr = this._zr = init$1(dom, { + renderer: opts.renderer || defaultRenderer, + devicePixelRatio: opts.devicePixelRatio, + width: opts.width, + height: opts.height + }); + + /** + * Expect 60 pfs. + * @type {Function} + * @private + */ + this._throttledZrFlush = throttle(bind(zr.flush, zr), 17); + + var theme$$1 = clone(theme$$1); + theme$$1 && backwardCompat(theme$$1, true); + /** + * @type {Object} + * @private + */ + this._theme = theme$$1; + + /** + * @type {Array.} + * @private + */ + this._chartsViews = []; + + /** + * @type {Object.} + * @private + */ + this._chartsMap = {}; + + /** + * @type {Array.} + * @private + */ + this._componentsViews = []; + + /** + * @type {Object.} + * @private + */ + this._componentsMap = {}; + + /** + * @type {module:echarts/CoordinateSystem} + * @private + */ + this._coordSysMgr = new CoordinateSystemManager(); + + /** + * @type {module:echarts/ExtensionAPI} + * @private + */ + var api = this._api = createExtensionAPI(this); + + // Sort on demand + function prioritySortFunc(a, b) { + return a.__prio - b.__prio; + } + sort(visualFuncs, prioritySortFunc); + sort(dataProcessorFuncs, prioritySortFunc); + + /** + * @type {module:echarts/stream/Scheduler} + */ + this._scheduler = new Scheduler(this, api, dataProcessorFuncs, visualFuncs); + + Eventful.call(this); + + /** + * @type {module:echarts~MessageCenter} + * @private + */ + this._messageCenter = new MessageCenter(); + + // Init mouse events + this._initEvents(); + + // In case some people write `window.onresize = chart.resize` + this.resize = bind(this.resize, this); + + // Can't dispatch action during rendering procedure + this._pendingActions = []; + + zr.animation.on('frame', this._onframe, this); + + bindRenderedEvent(zr, this); + + // ECharts instance can be used as value. + setAsPrimitive(this); + } + + var echartsProto = ECharts.prototype; + + echartsProto._onframe = function() { + if (this._disposed) { + return; + } + + var scheduler = this._scheduler; + + // Lazy update + if (this[OPTION_UPDATED]) { + var silent = this[OPTION_UPDATED].silent; + + this[IN_MAIN_PROCESS] = true; + + prepare(this); + updateMethods.update.call(this); + + this[IN_MAIN_PROCESS] = false; + + this[OPTION_UPDATED] = false; + + flushPendingActions.call(this, silent); + + triggerUpdatedEvent.call(this, silent); + } + // Avoid do both lazy update and progress in one frame. + else if (scheduler.unfinished) { + // Stream progress. + var remainTime = TEST_FRAME_REMAIN_TIME; + var ecModel = this._model; + var api = this._api; + scheduler.unfinished = false; + do { + var startTime = +new Date(); + + scheduler.performSeriesTasks(ecModel); + + // Currently dataProcessorFuncs do not check threshold. + scheduler.performDataProcessorTasks(ecModel); + + updateStreamModes(this, ecModel); + + // Do not update coordinate system here. Because that coord system update in + // each frame is not a good user experience. So we follow the rule that + // the extent of the coordinate system is determin in the first frame (the + // frame is executed immedietely after task reset. + // this._coordSysMgr.update(ecModel, api); + + // console.log('--- ec frame visual ---', remainTime); + scheduler.performVisualTasks(ecModel); + + renderSeries(this, this._model, api, 'remain'); + + remainTime -= (+new Date() - startTime); + } + while (remainTime > 0 && scheduler.unfinished); + + // Call flush explicitly for trigger finished event. + if (!scheduler.unfinished) { + this._zr.flush(); + } + // Else, zr flushing be ensue within the same frame, + // because zr flushing is after onframe event. + } + }; + + /** + * @return {HTMLElement} + */ + echartsProto.getDom = function() { + return this._dom; + }; + + /** + * @return {module:zrender~ZRender} + */ + echartsProto.getZr = function() { + return this._zr; + }; + + /** + * Usage: + * chart.setOption(option, notMerge, lazyUpdate); + * chart.setOption(option, { + * notMerge: ..., + * lazyUpdate: ..., + * silent: ... + * }); + * + * @param {Object} option + * @param {Object|boolean} [opts] opts or notMerge. + * @param {boolean} [opts.notMerge=false] + * @param {boolean} [opts.lazyUpdate=false] Useful when setOption frequently. + */ + echartsProto.setOption = function(option, notMerge, lazyUpdate) { + if (__DEV__) { + assert(!this[IN_MAIN_PROCESS], '`setOption` should not be called during main process.'); + } + + var silent; + if (isObject(notMerge)) { + lazyUpdate = notMerge.lazyUpdate; + silent = notMerge.silent; + notMerge = notMerge.notMerge; + } + + this[IN_MAIN_PROCESS] = true; + + if (!this._model || notMerge) { + var optionManager = new OptionManager(this._api); + var theme$$1 = this._theme; + var ecModel = this._model = new GlobalModel(null, null, theme$$1, optionManager); + ecModel.scheduler = this._scheduler; + ecModel.init(null, null, theme$$1, optionManager); + } + + this._model.setOption(option, optionPreprocessorFuncs); + + if (lazyUpdate) { + this[OPTION_UPDATED] = { + silent: silent + }; + this[IN_MAIN_PROCESS] = false; + } else { + prepare(this); + + updateMethods.update.call(this); + + // Ensure zr refresh sychronously, and then pixel in canvas can be + // fetched after `setOption`. + this._zr.flush(); + + this[OPTION_UPDATED] = false; + this[IN_MAIN_PROCESS] = false; + + flushPendingActions.call(this, silent); + triggerUpdatedEvent.call(this, silent); + } + }; + + /** + * @DEPRECATED + */ + echartsProto.setTheme = function() { + console.log('ECharts#setTheme() is DEPRECATED in ECharts 3.0'); + }; + + /** + * @return {module:echarts/model/Global} + */ + echartsProto.getModel = function() { + return this._model; + }; + + /** + * @return {Object} + */ + echartsProto.getOption = function() { + return this._model && this._model.getOption(); + }; + + /** + * @return {number} + */ + echartsProto.getWidth = function() { + return this._zr.getWidth(); + }; + + /** + * @return {number} + */ + echartsProto.getHeight = function() { + return this._zr.getHeight(); + }; + + /** + * @return {number} + */ + echartsProto.getDevicePixelRatio = function() { + return this._zr.painter.dpr || window.devicePixelRatio || 1; + }; + + /** + * Get canvas which has all thing rendered + * @param {Object} opts + * @param {string} [opts.backgroundColor] + * @return {string} + */ + echartsProto.getRenderedCanvas = function(opts) { + if (!env$1.canvasSupported) { + return; + } + opts = opts || {}; + opts.pixelRatio = opts.pixelRatio || 1; + opts.backgroundColor = opts.backgroundColor || + this._model.get('backgroundColor'); + var zr = this._zr; + // var list = zr.storage.getDisplayList(); + // Stop animations + // Never works before in init animation, so remove it. + // zrUtil.each(list, function (el) { + // el.stopAnimation(true); + // }); + return zr.painter.getRenderedCanvas(opts); + }; + + /** + * Get svg data url + * @return {string} + */ + echartsProto.getSvgDataUrl = function() { + if (!env$1.svgSupported) { + return; + } + + var zr = this._zr; + var list = zr.storage.getDisplayList(); + // Stop animations + each$1(list, function(el) { + el.stopAnimation(true); + }); + + return zr.painter.pathToDataUrl(); + }; + + /** + * @return {string} + * @param {Object} opts + * @param {string} [opts.type='png'] + * @param {string} [opts.pixelRatio=1] + * @param {string} [opts.backgroundColor] + * @param {string} [opts.excludeComponents] + */ + echartsProto.getDataURL = function(opts) { + opts = opts || {}; + var excludeComponents = opts.excludeComponents; + var ecModel = this._model; + var excludesComponentViews = []; + var self = this; + + each(excludeComponents, function(componentType) { + ecModel.eachComponent({ + mainType: componentType + }, function(component) { + var view = self._componentsMap[component.__viewId]; + if (!view.group.ignore) { + excludesComponentViews.push(view); + view.group.ignore = true; + } + }); + }); + + var url = this._zr.painter.getType() === 'svg' ? + this.getSvgDataUrl() : + this.getRenderedCanvas(opts).toDataURL( + 'image/' + (opts && opts.type || 'png') + ); + + each(excludesComponentViews, function(view) { + view.group.ignore = false; + }); + + return url; + }; + + + /** + * @return {string} + * @param {Object} opts + * @param {string} [opts.type='png'] + * @param {string} [opts.pixelRatio=1] + * @param {string} [opts.backgroundColor] + */ + echartsProto.getConnectedDataURL = function(opts) { + if (!env$1.canvasSupported) { + return; + } + var groupId = this.group; + var mathMin = Math.min; + var mathMax = Math.max; + var MAX_NUMBER = Infinity; + if (connectedGroups[groupId]) { + var left = MAX_NUMBER; + var top = MAX_NUMBER; + var right = -MAX_NUMBER; + var bottom = -MAX_NUMBER; + var canvasList = []; + var dpr = (opts && opts.pixelRatio) || 1; + + each$1(instances, function(chart, id) { + if (chart.group === groupId) { + var canvas = chart.getRenderedCanvas( + clone(opts) + ); + var boundingRect = chart.getDom().getBoundingClientRect(); + left = mathMin(boundingRect.left, left); + top = mathMin(boundingRect.top, top); + right = mathMax(boundingRect.right, right); + bottom = mathMax(boundingRect.bottom, bottom); + canvasList.push({ + dom: canvas, + left: boundingRect.left, + top: boundingRect.top + }); + } + }); + + left *= dpr; + top *= dpr; + right *= dpr; + bottom *= dpr; + var width = right - left; + var height = bottom - top; + var targetCanvas = createCanvas(); + targetCanvas.width = width; + targetCanvas.height = height; + var zr = init$1(targetCanvas); + + each(canvasList, function(item) { + var img = new ZImage({ + style: { + x: item.left * dpr - left, + y: item.top * dpr - top, + image: item.dom + } + }); + zr.add(img); + }); + zr.refreshImmediately(); + + return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png')); + } else { + return this.getDataURL(opts); + } + }; + + /** + * Convert from logical coordinate system to pixel coordinate system. + * See CoordinateSystem#convertToPixel. + * @param {string|Object} finder + * If string, e.g., 'geo', means {geoIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex / seriesId / seriesName, + * geoIndex / geoId, geoName, + * bmapIndex / bmapId / bmapName, + * xAxisIndex / xAxisId / xAxisName, + * yAxisIndex / yAxisId / yAxisName, + * gridIndex / gridId / gridName, + * ... (can be extended) + * } + * @param {Array|number} value + * @return {Array|number} result + */ + echartsProto.convertToPixel = curry(doConvertPixel, 'convertToPixel'); + + /** + * Convert from pixel coordinate system to logical coordinate system. + * See CoordinateSystem#convertFromPixel. + * @param {string|Object} finder + * If string, e.g., 'geo', means {geoIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex / seriesId / seriesName, + * geoIndex / geoId / geoName, + * bmapIndex / bmapId / bmapName, + * xAxisIndex / xAxisId / xAxisName, + * yAxisIndex / yAxisId / yAxisName + * gridIndex / gridId / gridName, + * ... (can be extended) + * } + * @param {Array|number} value + * @return {Array|number} result + */ + echartsProto.convertFromPixel = curry(doConvertPixel, 'convertFromPixel'); + + function doConvertPixel(methodName, finder, value) { + var ecModel = this._model; + var coordSysList = this._coordSysMgr.getCoordinateSystems(); + var result; + + finder = parseFinder(ecModel, finder); + + for (var i = 0; i < coordSysList.length; i++) { + var coordSys = coordSysList[i]; + if (coordSys[methodName] && + (result = coordSys[methodName](ecModel, finder, value)) != null + ) { + return result; + } + } + + if (__DEV__) { + console.warn( + 'No coordinate system that supports ' + methodName + ' found by the given finder.' + ); + } + } + + /** + * Is the specified coordinate systems or components contain the given pixel point. + * @param {string|Object} finder + * If string, e.g., 'geo', means {geoIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex / seriesId / seriesName, + * geoIndex / geoId / geoName, + * bmapIndex / bmapId / bmapName, + * xAxisIndex / xAxisId / xAxisName, + * yAxisIndex / yAxisId / yAxisName, + * gridIndex / gridId / gridName, + * ... (can be extended) + * } + * @param {Array|number} value + * @return {boolean} result + */ + echartsProto.containPixel = function(finder, value) { + var ecModel = this._model; + var result; + + finder = parseFinder(ecModel, finder); + + each$1(finder, function(models, key) { + key.indexOf('Models') >= 0 && each$1(models, function(model) { + var coordSys = model.coordinateSystem; + if (coordSys && coordSys.containPoint) { + result |= !!coordSys.containPoint(value); + } else if (key === 'seriesModels') { + var view = this._chartsMap[model.__viewId]; + if (view && view.containPoint) { + result |= view.containPoint(value, model); + } else { + if (__DEV__) { + console.warn(key + ': ' + (view ? + 'The found component do not support containPoint.' : + 'No view mapping to the found component.' + )); + } + } + } else { + if (__DEV__) { + console.warn(key + ': containPoint is not supported'); + } + } + }, this); + }, this); + + return !!result; + }; + + /** + * Get visual from series or data. + * @param {string|Object} finder + * If string, e.g., 'series', means {seriesIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex / seriesId / seriesName, + * dataIndex / dataIndexInside + * } + * If dataIndex is not specified, series visual will be fetched, + * but not data item visual. + * If all of seriesIndex, seriesId, seriesName are not specified, + * visual will be fetched from first series. + * @param {string} visualType 'color', 'symbol', 'symbolSize' + */ + echartsProto.getVisual = function(finder, visualType) { + var ecModel = this._model; + + finder = parseFinder(ecModel, finder, { + defaultMainType: 'series' + }); + + var seriesModel = finder.seriesModel; + + if (__DEV__) { + if (!seriesModel) { + console.warn('There is no specified seires model'); + } + } + + var data = seriesModel.getData(); + + var dataIndexInside = finder.hasOwnProperty('dataIndexInside') ? + finder.dataIndexInside : + finder.hasOwnProperty('dataIndex') ? + data.indexOfRawIndex(finder.dataIndex) : + null; + + return dataIndexInside != null ? + data.getItemVisual(dataIndexInside, visualType) : + data.getVisual(visualType); + }; + + /** + * Get view of corresponding component model + * @param {module:echarts/model/Component} componentModel + * @return {module:echarts/view/Component} + */ + echartsProto.getViewOfComponentModel = function(componentModel) { + return this._componentsMap[componentModel.__viewId]; + }; + + /** + * Get view of corresponding series model + * @param {module:echarts/model/Series} seriesModel + * @return {module:echarts/view/Chart} + */ + echartsProto.getViewOfSeriesModel = function(seriesModel) { + return this._chartsMap[seriesModel.__viewId]; + }; + + var updateMethods = { + + prepareAndUpdate: function(payload) { + prepare(this); + updateMethods.update.call(this, payload); + }, + + /** + * @param {Object} payload + * @private + */ + update: function(payload) { + // console.profile && console.profile('update'); + + var ecModel = this._model; + var api = this._api; + var zr = this._zr; + var coordSysMgr = this._coordSysMgr; + var scheduler = this._scheduler; + + // update before setOption + if (!ecModel) { + return; + } + + scheduler.restoreData(ecModel, payload); + + scheduler.performSeriesTasks(ecModel); + + // TODO + // Save total ecModel here for undo/redo (after restoring data and before processing data). + // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call. + + // Create new coordinate system each update + // In LineView may save the old coordinate system and use it to get the orignal point + coordSysMgr.create(ecModel, api); + + scheduler.performDataProcessorTasks(ecModel, payload); + + // Current stream render is not supported in data process. So we can update + // stream modes after data processing, where the filtered data is used to + // deteming whether use progressive rendering. + updateStreamModes(this, ecModel); + + // We update stream modes before coordinate system updated, then the modes info + // can be fetched when coord sys updating (consider the barGrid extent fix). But + // the drawback is the full coord info can not be fetched. Fortunately this full + // coord is not requied in stream mode updater currently. + coordSysMgr.update(ecModel, api); + + clearColorPalette(ecModel); + scheduler.performVisualTasks(ecModel, payload); + + render(this, ecModel, api, payload); + + // Set background + var backgroundColor = ecModel.get('backgroundColor') || 'transparent'; + + // In IE8 + if (!env$1.canvasSupported) { + var colorArr = parse(backgroundColor); + backgroundColor = stringify(colorArr, 'rgb'); + if (colorArr[3] === 0) { + backgroundColor = 'transparent'; + } + } else { + zr.setBackgroundColor(backgroundColor); + } + + performPostUpdateFuncs(ecModel, api); + + // console.profile && console.profileEnd('update'); + }, + + /** + * @param {Object} payload + * @private + */ + updateTransform: function(payload) { + var ecModel = this._model; + var ecIns = this; + var api = this._api; + + // update before setOption + if (!ecModel) { + return; + } + + // ChartView.markUpdateMethod(payload, 'updateTransform'); + + var componentDirtyList = []; + ecModel.eachComponent(function(componentType, componentModel) { + var componentView = ecIns.getViewOfComponentModel(componentModel); + if (componentView && componentView.__alive) { + if (componentView.updateTransform) { + var result = componentView.updateTransform(componentModel, ecModel, api, payload); + result && result.update && componentDirtyList.push(componentView); + } else { + componentDirtyList.push(componentView); + } + } + }); + + var seriesDirtyMap = createHashMap(); + ecModel.eachSeries(function(seriesModel) { + var chartView = ecIns._chartsMap[seriesModel.__viewId]; + if (chartView.updateTransform) { + var result = chartView.updateTransform(seriesModel, ecModel, api, payload); + result && result.update && seriesDirtyMap.set(seriesModel.uid, 1); + } else { + seriesDirtyMap.set(seriesModel.uid, 1); + } + }); + + clearColorPalette(ecModel); + // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true); + this._scheduler.performVisualTasks( + ecModel, payload, { + setDirty: true, + dirtyMap: seriesDirtyMap + } + ); + + // Currently, not call render of components. Geo render cost a lot. + // renderComponents(ecIns, ecModel, api, payload, componentDirtyList); + renderSeries(ecIns, ecModel, api, payload, seriesDirtyMap); + + performPostUpdateFuncs(ecModel, this._api); + }, + + /** + * @param {Object} payload + * @private + */ + updateView: function(payload) { + var ecModel = this._model; + + // update before setOption + if (!ecModel) { + return; + } + + Chart.markUpdateMethod(payload, 'updateView'); + + clearColorPalette(ecModel); + + // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + this._scheduler.performVisualTasks(ecModel, payload, { + setDirty: true + }); + + render(this, this._model, this._api, payload); + + performPostUpdateFuncs(ecModel, this._api); + }, + + /** + * @param {Object} payload + * @private + */ + updateVisual: function(payload) { + updateMethods.update.call(this, payload); + + // var ecModel = this._model; + + // // update before setOption + // if (!ecModel) { + // return; + // } + + // ChartView.markUpdateMethod(payload, 'updateVisual'); + + // clearColorPalette(ecModel); + + // // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + // this._scheduler.performVisualTasks(ecModel, payload, {visualType: 'visual', setDirty: true}); + + // render(this, this._model, this._api, payload); + + // performPostUpdateFuncs(ecModel, this._api); + }, + + /** + * @param {Object} payload + * @private + */ + updateLayout: function(payload) { + updateMethods.update.call(this, payload); + + // var ecModel = this._model; + + // // update before setOption + // if (!ecModel) { + // return; + // } + + // ChartView.markUpdateMethod(payload, 'updateLayout'); + + // // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + // // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true); + // this._scheduler.performVisualTasks(ecModel, payload, {setDirty: true}); + + // render(this, this._model, this._api, payload); + + // performPostUpdateFuncs(ecModel, this._api); + } + }; + + function prepare(ecIns) { + var ecModel = ecIns._model; + var scheduler = ecIns._scheduler; + + scheduler.restorePipelines(ecModel); + + scheduler.prepareStageTasks(); + + prepareView(ecIns, 'component', ecModel, scheduler); + + prepareView(ecIns, 'chart', ecModel, scheduler); + + scheduler.plan(); + } + + /** + * @private + */ + function updateDirectly(ecIns, method, payload, mainType, subType) { + var ecModel = ecIns._model; + + // broadcast + if (!mainType) { + // FIXME + // Chart will not be update directly here, except set dirty. + // But there is no such scenario now. + each(ecIns._componentsViews.concat(ecIns._chartsViews), callView); + return; + } + + var query = {}; + query[mainType + 'Id'] = payload[mainType + 'Id']; + query[mainType + 'Index'] = payload[mainType + 'Index']; + query[mainType + 'Name'] = payload[mainType + 'Name']; + + var condition = { + mainType: mainType, + query: query + }; + subType && (condition.subType = subType); // subType may be '' by parseClassType; + + var excludeSeriesId = payload.excludeSeriesId; + if (excludeSeriesId != null) { + excludeSeriesId = createHashMap(normalizeToArray(excludeSeriesId)); + } + + // If dispatchAction before setOption, do nothing. + ecModel && ecModel.eachComponent(condition, function(model) { + if (!excludeSeriesId || excludeSeriesId.get(model.id) == null) { + callView(ecIns[ + mainType === 'series' ? '_chartsMap' : '_componentsMap' + ][model.__viewId]); + } + }, ecIns); + + function callView(view) { + view && view.__alive && view[method] && view[method]( + view.__model, ecModel, ecIns._api, payload + ); + } + } + + /** + * Resize the chart + * @param {Object} opts + * @param {number} [opts.width] Can be 'auto' (the same as null/undefined) + * @param {number} [opts.height] Can be 'auto' (the same as null/undefined) + * @param {boolean} [opts.silent=false] + */ + echartsProto.resize = function(opts) { + if (__DEV__) { + assert(!this[IN_MAIN_PROCESS], '`resize` should not be called during main process.'); + } + + this._zr.resize(opts); + + var ecModel = this._model; + + // Resize loading effect + this._loadingFX && this._loadingFX.resize(); + + if (!ecModel) { + return; + } + + var optionChanged = ecModel.resetOption('media'); + + var silent = opts && opts.silent; + + this[IN_MAIN_PROCESS] = true; + + optionChanged && prepare(this); + updateMethods.update.call(this); + + this[IN_MAIN_PROCESS] = false; + + flushPendingActions.call(this, silent); + + triggerUpdatedEvent.call(this, silent); + }; + + function updateStreamModes(ecIns, ecModel) { + var chartsMap = ecIns._chartsMap; + var scheduler = ecIns._scheduler; + ecModel.eachSeries(function(seriesModel) { + scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]); + }); + } + + /** + * Show loading effect + * @param {string} [name='default'] + * @param {Object} [cfg] + */ + echartsProto.showLoading = function(name, cfg) { + if (isObject(name)) { + cfg = name; + name = ''; + } + name = name || 'default'; + + this.hideLoading(); + if (!loadingEffects[name]) { + if (__DEV__) { + console.warn('Loading effects ' + name + ' not exists.'); + } + return; + } + var el = loadingEffects[name](this._api, cfg); + var zr = this._zr; + this._loadingFX = el; + + zr.add(el); + }; + + /** + * Hide loading effect + */ + echartsProto.hideLoading = function() { + this._loadingFX && this._zr.remove(this._loadingFX); + this._loadingFX = null; + }; + + /** + * @param {Object} eventObj + * @return {Object} + */ + echartsProto.makeActionFromEvent = function(eventObj) { + var payload = extend({}, eventObj); + payload.type = eventActionMap[eventObj.type]; + return payload; + }; + + /** + * @pubilc + * @param {Object} payload + * @param {string} [payload.type] Action type + * @param {Object|boolean} [opt] If pass boolean, means opt.silent + * @param {boolean} [opt.silent=false] Whether trigger events. + * @param {boolean} [opt.flush=undefined] + * true: Flush immediately, and then pixel in canvas can be fetched + * immediately. Caution: it might affect performance. + * false: Not not flush. + * undefined: Auto decide whether perform flush. + */ + echartsProto.dispatchAction = function(payload, opt) { + if (!isObject(opt)) { + opt = { + silent: !!opt + }; + } + + if (!actions[payload.type]) { + return; + } + + // Avoid dispatch action before setOption. Especially in `connect`. + if (!this._model) { + return; + } + + // May dispatchAction in rendering procedure + if (this[IN_MAIN_PROCESS]) { + this._pendingActions.push(payload); + return; + } + + doDispatchAction.call(this, payload, opt.silent); + + if (opt.flush) { + this._zr.flush(true); + } else if (opt.flush !== false && env$1.browser.weChat) { + // In WeChat embeded browser, `requestAnimationFrame` and `setInterval` + // hang when sliding page (on touch event), which cause that zr does not + // refresh util user interaction finished, which is not expected. + // But `dispatchAction` may be called too frequently when pan on touch + // screen, which impacts performance if do not throttle them. + this._throttledZrFlush(); + } + + flushPendingActions.call(this, opt.silent); + + triggerUpdatedEvent.call(this, opt.silent); + }; + + function doDispatchAction(payload, silent) { + var payloadType = payload.type; + var escapeConnect = payload.escapeConnect; + var actionWrap = actions[payloadType]; + var actionInfo = actionWrap.actionInfo; + + var cptType = (actionInfo.update || 'update').split(':'); + var updateMethod = cptType.pop(); + cptType = cptType[0] != null && parseClassType(cptType[0]); + + this[IN_MAIN_PROCESS] = true; + + var payloads = [payload]; + var batched = false; + // Batch action + if (payload.batch) { + batched = true; + payloads = map(payload.batch, function(item) { + item = defaults(extend({}, item), payload); + item.batch = null; + return item; + }); + } + + var eventObjBatch = []; + var eventObj; + var isHighDown = payloadType === 'highlight' || payloadType === 'downplay'; + + each(payloads, function(batchItem) { + // Action can specify the event by return it. + eventObj = actionWrap.action(batchItem, this._model, this._api); + // Emit event outside + eventObj = eventObj || extend({}, batchItem); + // Convert type to eventType + eventObj.type = actionInfo.event || eventObj.type; + eventObjBatch.push(eventObj); + + // light update does not perform data process, layout and visual. + if (isHighDown) { + // method, payload, mainType, subType + updateDirectly(this, updateMethod, batchItem, 'series'); + } else if (cptType) { + updateDirectly(this, updateMethod, batchItem, cptType.main, cptType.sub); + } + }, this); + + if (updateMethod !== 'none' && !isHighDown && !cptType) { + // Still dirty + if (this[OPTION_UPDATED]) { + // FIXME Pass payload ? + prepare(this); + updateMethods.update.call(this, payload); + this[OPTION_UPDATED] = false; + } else { + updateMethods[updateMethod].call(this, payload); + } + } + + // Follow the rule of action batch + if (batched) { + eventObj = { + type: actionInfo.event || payloadType, + escapeConnect: escapeConnect, + batch: eventObjBatch + }; + } else { + eventObj = eventObjBatch[0]; + } + + this[IN_MAIN_PROCESS] = false; + + !silent && this._messageCenter.trigger(eventObj.type, eventObj); + } + + function flushPendingActions(silent) { + var pendingActions = this._pendingActions; + while (pendingActions.length) { + var payload = pendingActions.shift(); + doDispatchAction.call(this, payload, silent); + } + } + + function triggerUpdatedEvent(silent) { + !silent && this.trigger('updated'); + } + + /** + * Event `rendered` is triggered when zr + * rendered. It is useful for realtime + * snapshot (reflect animation). + * + * Event `finished` is triggered when: + * (1) zrender rendering finished. + * (2) initial animation finished. + * (3) progressive rendering finished. + * (4) no pending action. + * (5) no delayed setOption needs to be processed. + */ + function bindRenderedEvent(zr, ecIns) { + zr.on('rendered', function() { + + ecIns.trigger('rendered'); + + // The `finished` event should not be triggered repeatly, + // so it should only be triggered when rendering indeed happend + // in zrender. (Consider the case that dipatchAction is keep + // triggering when mouse move). + if ( + // Although zr is dirty if initial animation is not finished + // and this checking is called on frame, we also check + // animation finished for robustness. + zr.animation.isFinished() && + !ecIns[OPTION_UPDATED] && + !ecIns._scheduler.unfinished && + !ecIns._pendingActions.length + ) { + ecIns.trigger('finished'); + } + }); + } + + /** + * @param {Object} params + * @param {number} params.seriesIndex + * @param {Array|TypedArray} params.data + */ + echartsProto.appendData = function(params) { + var seriesIndex = params.seriesIndex; + var ecModel = this.getModel(); + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + + if (__DEV__) { + assert(params.data && seriesModel); + } + + seriesModel.appendData(params); + + // Note: `appendData` does not support that update extent of coordinate + // system, util some scenario require that. In the expected usage of + // `appendData`, the initial extent of coordinate system should better + // be fixed by axis `min`/`max` setting or initial data, otherwise if + // the extent changed while `appendData`, the location of the painted + // graphic elements have to be changed, which make the usage of + // `appendData` meaningless. + + this._scheduler.unfinished = true; + }; + + /** + * Register event + * @method + */ + echartsProto.on = createRegisterEventWithLowercaseName('on'); + echartsProto.off = createRegisterEventWithLowercaseName('off'); + echartsProto.one = createRegisterEventWithLowercaseName('one'); + + /** + * Prepare view instances of charts and components + * @param {module:echarts/model/Global} ecModel + * @private + */ + function prepareView(ecIns, type, ecModel, scheduler) { + var isComponent = type === 'component'; + var viewList = isComponent ? ecIns._componentsViews : ecIns._chartsViews; + var viewMap = isComponent ? ecIns._componentsMap : ecIns._chartsMap; + var zr = ecIns._zr; + var api = ecIns._api; + + for (var i = 0; i < viewList.length; i++) { + viewList[i].__alive = false; + } + + isComponent + ? + ecModel.eachComponent(function(componentType, model) { + componentType !== 'series' && doPrepare(model); + }) : + ecModel.eachSeries(doPrepare); + + function doPrepare(model) { + // Consider: id same and type changed. + var viewId = '_ec_' + model.id + '_' + model.type; + var view = viewMap[viewId]; + if (!view) { + var classType = parseClassType(model.type); + var Clazz = isComponent ? + Component.getClass(classType.main, classType.sub) : + Chart.getClass(classType.sub); + + if (__DEV__) { + assert(Clazz, classType.sub + ' does not exist.'); + } + + view = new Clazz(); + view.init(ecModel, api); + viewMap[viewId] = view; + viewList.push(view); + zr.add(view.group); + } + + model.__viewId = view.__id = viewId; + view.__alive = true; + view.__model = model; + view.group.__ecComponentInfo = { + mainType: model.mainType, + index: model.componentIndex + }; + !isComponent && scheduler.prepareView(view, model, ecModel, api); + } + + for (var i = 0; i < viewList.length;) { + var view = viewList[i]; + if (!view.__alive) { + !isComponent && view.renderTask.dispose(); + zr.remove(view.group); + view.dispose(ecModel, api); + viewList.splice(i, 1); + delete viewMap[view.__id]; + view.__id = view.group.__ecComponentInfo = null; + } else { + i++; + } + } + } + + // /** + // * Encode visual infomation from data after data processing + // * + // * @param {module:echarts/model/Global} ecModel + // * @param {object} layout + // * @param {boolean} [layoutFilter] `true`: only layout, + // * `false`: only not layout, + // * `null`/`undefined`: all. + // * @param {string} taskBaseTag + // * @private + // */ + // function startVisualEncoding(ecIns, ecModel, api, payload, layoutFilter) { + // each(visualFuncs, function (visual, index) { + // var isLayout = visual.isLayout; + // if (layoutFilter == null + // || (layoutFilter === false && !isLayout) + // || (layoutFilter === true && isLayout) + // ) { + // visual.func(ecModel, api, payload); + // } + // }); + // } + + function clearColorPalette(ecModel) { + ecModel.clearColorPalette(); + ecModel.eachSeries(function(seriesModel) { + seriesModel.clearColorPalette(); + }); + } + + function render(ecIns, ecModel, api, payload) { + + renderComponents(ecIns, ecModel, api, payload); + + each(ecIns._chartsViews, function(chart) { + chart.__alive = false; + }); + + renderSeries(ecIns, ecModel, api, payload); + + // Remove groups of unrendered charts + each(ecIns._chartsViews, function(chart) { + if (!chart.__alive) { + chart.remove(ecModel, api); + } + }); + } + + function renderComponents(ecIns, ecModel, api, payload, dirtyList) { + each(dirtyList || ecIns._componentsViews, function(componentView) { + var componentModel = componentView.__model; + componentView.render(componentModel, ecModel, api, payload); + + updateZ(componentModel, componentView); + }); + } + + /** + * Render each chart and component + * @private + */ + function renderSeries(ecIns, ecModel, api, payload, dirtyMap) { + // Render all charts + var scheduler = ecIns._scheduler; + var unfinished; + ecModel.eachSeries(function(seriesModel) { + var chartView = ecIns._chartsMap[seriesModel.__viewId]; + chartView.__alive = true; + + var renderTask = chartView.renderTask; + scheduler.updatePayload(renderTask, payload); + + if (dirtyMap && dirtyMap.get(seriesModel.uid)) { + renderTask.dirty(); + } + + unfinished |= renderTask.perform(scheduler.getPerformArgs(renderTask)); + + chartView.group.silent = !!seriesModel.get('silent'); + + updateZ(seriesModel, chartView); + + updateBlend(seriesModel, chartView); + }); + scheduler.unfinished |= unfinished; + + // If use hover layer + updateHoverLayerStatus(ecIns._zr, ecModel); + + // Add aria + aria(ecIns._zr.dom, ecModel); + } + + function performPostUpdateFuncs(ecModel, api) { + each(postUpdateFuncs, function(func) { + func(ecModel, api); + }); + } + + + var MOUSE_EVENT_NAMES = [ + 'click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', + 'mousedown', 'mouseup', 'globalout', 'contextmenu' + ]; + + /** + * @private + */ + echartsProto._initEvents = function() { + each(MOUSE_EVENT_NAMES, function(eveName) { + this._zr.on(eveName, function(e) { + var ecModel = this.getModel(); + var el = e.target; + var params; + + // no e.target when 'globalout'. + if (eveName === 'globalout') { + params = {}; + } else if (el && el.dataIndex != null) { + var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex); + params = dataModel && dataModel.getDataParams(el.dataIndex, el.dataType) || {}; + } + // If element has custom eventData of components + else if (el && el.eventData) { + params = extend({}, el.eventData); + } + + if (params) { + params.event = e; + params.type = eveName; + this.trigger(eveName, params); + } + + }, this); + }, this); + + each(eventActionMap, function(actionType, eventType) { + this._messageCenter.on(eventType, function(event) { + this.trigger(eventType, event); + }, this); + }, this); + }; + + /** + * @return {boolean} + */ + echartsProto.isDisposed = function() { + return this._disposed; + }; + + /** + * Clear + */ + echartsProto.clear = function() { + this.setOption({ + series: [] + }, true); + }; + + /** + * Dispose instance + */ + echartsProto.dispose = function() { + if (this._disposed) { + if (__DEV__) { + console.warn('Instance ' + this.id + ' has been disposed'); + } + return; + } + this._disposed = true; + + setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, ''); + + var api = this._api; + var ecModel = this._model; + + each(this._componentsViews, function(component) { + component.dispose(ecModel, api); + }); + each(this._chartsViews, function(chart) { + chart.dispose(ecModel, api); + }); + + // Dispose after all views disposed + this._zr.dispose(); + + delete instances[this.id]; + }; + + mixin(ECharts, Eventful); + + function updateHoverLayerStatus(zr, ecModel) { + var storage = zr.storage; + var elCount = 0; + storage.traverse(function(el) { + if (!el.isGroup) { + elCount++; + } + }); + if (elCount > ecModel.get('hoverLayerThreshold') && !env$1.node) { + storage.traverse(function(el) { + if (!el.isGroup) { + // Don't switch back. + el.useHoverLayer = true; + } + }); + } + } + + /** + * Update chart progressive and blend. + * @param {module:echarts/model/Series|module:echarts/model/Component} model + * @param {module:echarts/view/Component|module:echarts/view/Chart} view + */ + function updateBlend(seriesModel, chartView) { + var blendMode = seriesModel.get('blendMode') || null; + if (__DEV__) { + if (!env$1.canvasSupported && blendMode && blendMode !== 'source-over') { + console.warn('Only canvas support blendMode'); + } + } + chartView.group.traverse(function(el) { + // FIXME marker and other components + if (!el.isGroup) { + // Only set if blendMode is changed. In case element is incremental and don't wan't to rerender. + if (el.style.blend !== blendMode) { + el.setStyle('blend', blendMode); + } + } + if (el.eachPendingDisplayable) { + el.eachPendingDisplayable(function(displayable) { + displayable.setStyle('blend', blendMode); + }); + } + }); + } + + /** + * @param {module:echarts/model/Series|module:echarts/model/Component} model + * @param {module:echarts/view/Component|module:echarts/view/Chart} view + */ + function updateZ(model, view) { + var z = model.get('z'); + var zlevel = model.get('zlevel'); + // Set z and zlevel + view.group.traverse(function(el) { + if (el.type !== 'group') { + z != null && (el.z = z); + zlevel != null && (el.zlevel = zlevel); + } + }); + } + + function createExtensionAPI(ecInstance) { + var coordSysMgr = ecInstance._coordSysMgr; + return extend(new ExtensionAPI(ecInstance), { + // Inject methods + getCoordinateSystems: bind( + coordSysMgr.getCoordinateSystems, coordSysMgr + ), + getComponentByElement: function(el) { + while (el) { + var modelInfo = el.__ecComponentInfo; + if (modelInfo != null) { + return ecInstance._model.getComponent(modelInfo.mainType, modelInfo.index); + } + el = el.parent; + } + } + }); + } + + /** + * @type {Object} key: actionType. + * @inner + */ + var actions = {}; + + /** + * Map eventType to actionType + * @type {Object} + */ + var eventActionMap = {}; + + /** + * Data processor functions of each stage + * @type {Array.>} + * @inner + */ + var dataProcessorFuncs = []; + + /** + * @type {Array.} + * @inner + */ + var optionPreprocessorFuncs = []; + + /** + * @type {Array.} + * @inner + */ + var postUpdateFuncs = []; + + /** + * Visual encoding functions of each stage + * @type {Array.>} + */ + var visualFuncs = []; + + /** + * Theme storage + * @type {Object.} + */ + var themeStorage = {}; + /** + * Loading effects + */ + var loadingEffects = {}; + + var instances = {}; + var connectedGroups = {}; + + var idBase = new Date() - 0; + var groupIdBase = new Date() - 0; + var DOM_ATTRIBUTE_KEY = '_echarts_instance_'; + + var mapDataStores = {}; + + function enableConnect(chart) { + var STATUS_PENDING = 0; + var STATUS_UPDATING = 1; + var STATUS_UPDATED = 2; + var STATUS_KEY = '__connectUpdateStatus'; + + function updateConnectedChartsStatus(charts, status) { + for (var i = 0; i < charts.length; i++) { + var otherChart = charts[i]; + otherChart[STATUS_KEY] = status; + } + } + + each(eventActionMap, function(actionType, eventType) { + chart._messageCenter.on(eventType, function(event) { + if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) { + if (event && event.escapeConnect) { + return; + } + + var action = chart.makeActionFromEvent(event); + var otherCharts = []; + + each(instances, function(otherChart) { + if (otherChart !== chart && otherChart.group === chart.group) { + otherCharts.push(otherChart); + } + }); + + updateConnectedChartsStatus(otherCharts, STATUS_PENDING); + each(otherCharts, function(otherChart) { + if (otherChart[STATUS_KEY] !== STATUS_UPDATING) { + otherChart.dispatchAction(action); + } + }); + updateConnectedChartsStatus(otherCharts, STATUS_UPDATED); + } + }); + }); + } + + /** + * @param {HTMLElement} dom + * @param {Object} [theme] + * @param {Object} opts + * @param {number} [opts.devicePixelRatio] Use window.devicePixelRatio by default + * @param {string} [opts.renderer] Currently only 'canvas' is supported. + * @param {number} [opts.width] Use clientWidth of the input `dom` by default. + * Can be 'auto' (the same as null/undefined) + * @param {number} [opts.height] Use clientHeight of the input `dom` by default. + * Can be 'auto' (the same as null/undefined) + */ + function init(dom, theme$$1, opts) { + if (__DEV__) { + // Check version + if ((version$1.replace('.', '') - 0) < (dependencies.zrender.replace('.', '') - 0)) { + throw new Error( + 'zrender/src ' + version$1 + + ' is too old for ECharts ' + version + + '. Current version need ZRender ' + + dependencies.zrender + '+' + ); + } + + if (!dom) { + throw new Error('Initialize failed: invalid dom.'); + } + } + + var existInstance = getInstanceByDom(dom); + if (existInstance) { + if (__DEV__) { + console.warn('There is a chart instance already initialized on the dom.'); + } + return existInstance; + } + + if (__DEV__) { + if (isDom(dom) && + dom.nodeName.toUpperCase() !== 'CANVAS' && + ( + (!dom.clientWidth && (!opts || opts.width == null)) || + (!dom.clientHeight && (!opts || opts.height == null)) + ) + ) { + console.warn('Can\'t get dom width or height'); + } + } + + var chart = new ECharts(dom, theme$$1, opts); + chart.id = 'ec_' + idBase++; + instances[chart.id] = chart; + + setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id); + + enableConnect(chart); + + return chart; + } + + /** + * @return {string|Array.} groupId + */ + function connect(groupId) { + // Is array of charts + if (isArray(groupId)) { + var charts = groupId; + groupId = null; + // If any chart has group + each(charts, function(chart) { + if (chart.group != null) { + groupId = chart.group; + } + }); + groupId = groupId || ('g_' + groupIdBase++); + each(charts, function(chart) { + chart.group = groupId; + }); + } + connectedGroups[groupId] = true; + return groupId; + } + + /** + * @DEPRECATED + * @return {string} groupId + */ + function disConnect(groupId) { + connectedGroups[groupId] = false; + } + + /** + * @return {string} groupId + */ + var disconnect = disConnect; + + /** + * Dispose a chart instance + * @param {module:echarts~ECharts|HTMLDomElement|string} chart + */ + function dispose(chart) { + if (typeof chart === 'string') { + chart = instances[chart]; + } else if (!(chart instanceof ECharts)) { + // Try to treat as dom + chart = getInstanceByDom(chart); + } + if ((chart instanceof ECharts) && !chart.isDisposed()) { + chart.dispose(); + } + } + + /** + * @param {HTMLElement} dom + * @return {echarts~ECharts} + */ + function getInstanceByDom(dom) { + return instances[getAttribute(dom, DOM_ATTRIBUTE_KEY)]; + } + + /** + * @param {string} key + * @return {echarts~ECharts} + */ + function getInstanceById(key) { + return instances[key]; + } + + /** + * Register theme + */ + function registerTheme(name, theme$$1) { + themeStorage[name] = theme$$1; + } + + /** + * Register option preprocessor + * @param {Function} preprocessorFunc + */ + function registerPreprocessor(preprocessorFunc) { + optionPreprocessorFuncs.push(preprocessorFunc); + } + + /** + * @param {number} [priority=1000] + * @param {Object|Function} processor + */ + function registerProcessor(priority, processor) { + normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_FILTER); + } + + /** + * Register postUpdater + * @param {Function} postUpdateFunc + */ + function registerPostUpdate(postUpdateFunc) { + postUpdateFuncs.push(postUpdateFunc); + } + + /** + * Usage: + * registerAction('someAction', 'someEvent', function () { ... }); + * registerAction('someAction', function () { ... }); + * registerAction( + * {type: 'someAction', event: 'someEvent', update: 'updateView'}, + * function () { ... } + * ); + * + * @param {(string|Object)} actionInfo + * @param {string} actionInfo.type + * @param {string} [actionInfo.event] + * @param {string} [actionInfo.update] + * @param {string} [eventName] + * @param {Function} action + */ + function registerAction(actionInfo, eventName, action) { + if (typeof eventName === 'function') { + action = eventName; + eventName = ''; + } + var actionType = isObject(actionInfo) ? + actionInfo.type : + ([actionInfo, actionInfo = { + event: eventName + }][0]); + + // Event name is all lowercase + actionInfo.event = (actionInfo.event || actionType).toLowerCase(); + eventName = actionInfo.event; + + // Validate action type and event name. + assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName)); + + if (!actions[actionType]) { + actions[actionType] = { + action: action, + actionInfo: actionInfo + }; + } + eventActionMap[eventName] = actionType; + } + + /** + * @param {string} type + * @param {*} CoordinateSystem + */ + function registerCoordinateSystem(type, CoordinateSystem$$1) { + CoordinateSystemManager.register(type, CoordinateSystem$$1); + } + + /** + * Get dimensions of specified coordinate system. + * @param {string} type + * @return {Array.} + */ + function getCoordinateSystemDimensions(type) { + var coordSysCreator = CoordinateSystemManager.get(type); + if (coordSysCreator) { + return coordSysCreator.getDimensionsInfo ? + coordSysCreator.getDimensionsInfo() : + coordSysCreator.dimensions.slice(); + } + } + + /** + * Layout is a special stage of visual encoding + * Most visual encoding like color are common for different chart + * But each chart has it's own layout algorithm + * + * @param {number} [priority=1000] + * @param {Function} layoutTask + */ + function registerLayout(priority, layoutTask) { + normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout'); + } + + /** + * @param {number} [priority=3000] + * @param {module:echarts/stream/Task} visualTask + */ + function registerVisual(priority, visualTask) { + normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual'); + } + + /** + * @param {Object|Function} fn: {seriesType, createOnAllSeries, performRawSeries, reset} + */ + function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) { + if (isFunction(priority) || isObject(priority)) { + fn = priority; + priority = defaultPriority; + } + + if (__DEV__) { + if (isNaN(priority) || priority == null) { + throw new Error('Illegal priority'); + } + // Check duplicate + each(targetList, function(wrap) { + assert(wrap.__raw !== fn); + }); + } + + var stageHandler = Scheduler.wrapStageHandler(fn, visualType); + + stageHandler.__prio = priority; + stageHandler.__raw = fn; + targetList.push(stageHandler); + + return stageHandler; + } + + /** + * @param {string} name + */ + function registerLoading(name, loadingFx) { + loadingEffects[name] = loadingFx; + } + + /** + * @param {Object} opts + * @param {string} [superClass] + */ + function extendComponentModel(opts /*, superClass*/ ) { + // var Clazz = ComponentModel; + // if (superClass) { + // var classType = parseClassType(superClass); + // Clazz = ComponentModel.getClass(classType.main, classType.sub, true); + // } + return ComponentModel.extend(opts); + } + + /** + * @param {Object} opts + * @param {string} [superClass] + */ + function extendComponentView(opts /*, superClass*/ ) { + // var Clazz = ComponentView; + // if (superClass) { + // var classType = parseClassType(superClass); + // Clazz = ComponentView.getClass(classType.main, classType.sub, true); + // } + return Component.extend(opts); + } + + /** + * @param {Object} opts + * @param {string} [superClass] + */ + function extendSeriesModel(opts /*, superClass*/ ) { + // var Clazz = SeriesModel; + // if (superClass) { + // superClass = 'series.' + superClass.replace('series.', ''); + // var classType = parseClassType(superClass); + // Clazz = ComponentModel.getClass(classType.main, classType.sub, true); + // } + return SeriesModel.extend(opts); + } + + /** + * @param {Object} opts + * @param {string} [superClass] + */ + function extendChartView(opts /*, superClass*/ ) { + // var Clazz = ChartView; + // if (superClass) { + // superClass = superClass.replace('series.', ''); + // var classType = parseClassType(superClass); + // Clazz = ChartView.getClass(classType.main, true); + // } + return Chart.extend(opts); + } + + /** + * ZRender need a canvas context to do measureText. + * But in node environment canvas may be created by node-canvas. + * So we need to specify how to create a canvas instead of using document.createElement('canvas') + * + * Be careful of using it in the browser. + * + * @param {Function} creator + * @example + * var Canvas = require('canvas'); + * var echarts = require('echarts'); + * echarts.setCanvasCreator(function () { + * // Small size is enough. + * return new Canvas(32, 32); + * }); + */ + function setCanvasCreator(creator) { + $override('createCanvas', creator); + } + + /** + * @param {string} mapName + * @param {Object|string} geoJson + * @param {Object} [specialAreas] + * + * @example + * $.get('USA.json', function (geoJson) { + * echarts.registerMap('USA', geoJson); + * // Or + * echarts.registerMap('USA', { + * geoJson: geoJson, + * specialAreas: {} + * }) + * }); + */ + function registerMap(mapName, geoJson, specialAreas) { + if (geoJson.geoJson && !geoJson.features) { + specialAreas = geoJson.specialAreas; + geoJson = geoJson.geoJson; + } + if (typeof geoJson === 'string') { + geoJson = (typeof JSON !== 'undefined' && JSON.parse) ? + JSON.parse(geoJson) : (new Function('return (' + geoJson + ');'))(); + } + mapDataStores[mapName] = { + geoJson: geoJson, + specialAreas: specialAreas + }; + } + + /** + * @param {string} mapName + * @return {Object} + */ + function getMap(mapName) { + return mapDataStores[mapName]; + } + + registerVisual(PRIORITY_VISUAL_GLOBAL, seriesColor); + registerPreprocessor(backwardCompat); + registerProcessor(PRIORITY_PROCESSOR_STATISTIC, dataStack); + registerLoading('default', loadingDefault); + + // Default actions + + registerAction({ + type: 'highlight', + event: 'highlight', + update: 'highlight' + }, noop); + + registerAction({ + type: 'downplay', + event: 'downplay', + update: 'downplay' + }, noop); + + // Default theme + registerTheme('light', lightTheme); + registerTheme('dark', theme); + + // For backward compatibility, where the namespace `dataTool` will + // be mounted on `echarts` is the extension `dataTool` is imported. + var dataTool = {}; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + function defaultKeyGetter(item) { + return item; + } + + /** + * @param {Array} oldArr + * @param {Array} newArr + * @param {Function} oldKeyGetter + * @param {Function} newKeyGetter + * @param {Object} [context] Can be visited by this.context in callback. + */ + function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context) { + this._old = oldArr; + this._new = newArr; + + this._oldKeyGetter = oldKeyGetter || defaultKeyGetter; + this._newKeyGetter = newKeyGetter || defaultKeyGetter; + + this.context = context; + } + + DataDiffer.prototype = { + + constructor: DataDiffer, + + /** + * Callback function when add a data + */ + add: function(func) { + this._add = func; + return this; + }, + + /** + * Callback function when update a data + */ + update: function(func) { + this._update = func; + return this; + }, + + /** + * Callback function when remove a data + */ + remove: function(func) { + this._remove = func; + return this; + }, + + execute: function() { + var oldArr = this._old; + var newArr = this._new; + + var oldDataIndexMap = {}; + var newDataIndexMap = {}; + var oldDataKeyArr = []; + var newDataKeyArr = []; + var i; + + initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter', this); + initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter', this); + + // Travel by inverted order to make sure order consistency + // when duplicate keys exists (consider newDataIndex.pop() below). + // For performance consideration, these code below do not look neat. + for (i = 0; i < oldArr.length; i++) { + var key = oldDataKeyArr[i]; + var idx = newDataIndexMap[key]; + + // idx can never be empty array here. see 'set null' logic below. + if (idx != null) { + // Consider there is duplicate key (for example, use dataItem.name as key). + // We should make sure every item in newArr and oldArr can be visited. + var len = idx.length; + if (len) { + len === 1 && (newDataIndexMap[key] = null); + idx = idx.unshift(); + } else { + newDataIndexMap[key] = null; + } + this._update && this._update(idx, i); + } else { + this._remove && this._remove(i); + } + } + + for (var i = 0; i < newDataKeyArr.length; i++) { + var key = newDataKeyArr[i]; + if (newDataIndexMap.hasOwnProperty(key)) { + var idx = newDataIndexMap[key]; + if (idx == null) { + continue; + } + // idx can never be empty array here. see 'set null' logic above. + if (!idx.length) { + this._add && this._add(idx); + } else { + for (var j = 0, len = idx.length; j < len; j++) { + this._add && this._add(idx[j]); + } + } + } + } + } + }; + + function initIndexMap(arr, map, keyArr, keyGetterName, dataDiffer) { + for (var i = 0; i < arr.length; i++) { + // Add prefix to avoid conflict with Object.prototype. + var key = '_ec_' + dataDiffer[keyGetterName](arr[i], i); + var existence = map[key]; + if (existence == null) { + keyArr.push(key); + map[key] = i; + } else { + if (!existence.length) { + map[key] = existence = [existence]; + } + existence.push(i); + } + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var OTHER_DIMENSIONS = createHashMap([ + 'tooltip', 'label', 'itemName', 'itemId', 'seriesName' + ]); + + function summarizeDimensions(data) { + var summary = {}; + var encode = summary.encode = {}; + var notExtraCoordDimMap = createHashMap(); + var defaultedLabel = []; + var defaultedTooltip = []; + + each$1(data.dimensions, function(dimName) { + var dimItem = data.getDimensionInfo(dimName); + + var coordDim = dimItem.coordDim; + if (coordDim) { + if (__DEV__) { + assert$1(OTHER_DIMENSIONS.get(coordDim) == null); + } + var coordDimArr = encode[coordDim]; + if (!encode.hasOwnProperty(coordDim)) { + coordDimArr = encode[coordDim] = []; + } + coordDimArr[dimItem.coordDimIndex] = dimName; + + if (!dimItem.isExtraCoord) { + notExtraCoordDimMap.set(coordDim, 1); + + // Use the last coord dim (and label friendly) as default label, + // because when dataset is used, it is hard to guess which dimension + // can be value dimension. If both show x, y on label is not look good, + // and conventionally y axis is focused more. + if (mayLabelDimType(dimItem.type)) { + defaultedLabel[0] = dimName; + } + } + if (dimItem.defaultTooltip) { + defaultedTooltip.push(dimName); + } + } + + OTHER_DIMENSIONS.each(function(v, otherDim) { + var otherDimArr = encode[otherDim]; + if (!encode.hasOwnProperty(otherDim)) { + otherDimArr = encode[otherDim] = []; + } + + var dimIndex = dimItem.otherDims[otherDim]; + if (dimIndex != null && dimIndex !== false) { + otherDimArr[dimIndex] = dimItem.name; + } + }); + }); + + var dataDimsOnCoord = []; + var encodeFirstDimNotExtra = {}; + + notExtraCoordDimMap.each(function(v, coordDim) { + var dimArr = encode[coordDim]; + // ??? FIXME extra coord should not be set in dataDimsOnCoord. + // But should fix the case that radar axes: simplify the logic + // of `completeDimension`, remove `extraPrefix`. + encodeFirstDimNotExtra[coordDim] = dimArr[0]; + // Not necessary to remove duplicate, because a data + // dim canot on more than one coordDim. + dataDimsOnCoord = dataDimsOnCoord.concat(dimArr); + }); + + summary.dataDimsOnCoord = dataDimsOnCoord; + summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra; + + var encodeLabel = encode.label; + // FIXME `encode.label` is not recommanded, because formatter can not be set + // in this way. Use label.formatter instead. May be remove this approach someday. + if (encodeLabel && encodeLabel.length) { + defaultedLabel = encodeLabel.slice(); + } + + var encodeTooltip = encode.tooltip; + if (encodeTooltip && encodeTooltip.length) { + defaultedTooltip = encodeTooltip.slice(); + } else if (!defaultedTooltip.length) { + defaultedTooltip = defaultedLabel.slice(); + } + + encode.defaultedLabel = defaultedLabel; + encode.defaultedTooltip = defaultedTooltip; + + return summary; + } + + function getDimensionTypeByAxis(axisType) { + return axisType === 'category' ? + 'ordinal' : + axisType === 'time' ? + 'time' : + 'float'; + } + + function mayLabelDimType(dimType) { + // In most cases, ordinal and time do not suitable for label. + // Ordinal info can be displayed on axis. Time is too long. + return !(dimType === 'ordinal' || dimType === 'time'); + } + + // function findTheLastDimMayLabel(data) { + // // Get last value dim + // var dimensions = data.dimensions.slice(); + // var valueType; + // var valueDim; + // while (dimensions.length && ( + // valueDim = dimensions.pop(), + // valueType = data.getDimensionInfo(valueDim).type, + // valueType === 'ordinal' || valueType === 'time' + // )) {} // jshint ignore:line + // return valueDim; + // } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * List for data storage + * @module echarts/data/List + */ + + var isObject$4 = isObject$1; + + var UNDEFINED = 'undefined'; + + // Use prefix to avoid index to be the same as otherIdList[idx], + // which will cause weird udpate animation. + var ID_PREFIX = 'e\0\0'; + + var dataCtors = { + 'float': typeof Float64Array === UNDEFINED ? + Array : Float64Array, + 'int': typeof Int32Array === UNDEFINED ? + Array : Int32Array, + // Ordinal data type can be string or int + 'ordinal': Array, + 'number': Array, + 'time': Array + }; + + // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is + // different from the Ctor of typed array. + var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array; + var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array; + + function getIndicesCtor(list) { + // The possible max value in this._indicies is always this._rawCount despite of filtering. + return list._rawCount > 65535 ? CtorUint32Array : CtorUint16Array; + } + + function cloneChunk(originalChunk) { + var Ctor = originalChunk.constructor; + // Only shallow clone is enough when Array. + return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk); + } + + var TRANSFERABLE_PROPERTIES = [ + 'hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', + '_rawData', '_chunkSize', '_chunkCount', '_dimValueGetter', + '_count', '_rawCount', '_nameDimIdx', '_idDimIdx' + ]; + var CLONE_PROPERTIES = [ + '_extent', '_approximateExtent', '_rawExtent' + ]; + + function transferProperties(target, source) { + each$1(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function(propName) { + if (source.hasOwnProperty(propName)) { + target[propName] = source[propName]; + } + }); + + target.__wrappedMethods = source.__wrappedMethods; + + each$1(CLONE_PROPERTIES, function(propName) { + target[propName] = clone(source[propName]); + }); + + target._calculationInfo = extend(source._calculationInfo); + } + + + + + + /** + * @constructor + * @alias module:echarts/data/List + * + * @param {Array.} dimensions + * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...]. + * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius + * Spetial fields: { + * ordinalMeta: + * createInvertedIndices: + * } + * @param {module:echarts/model/Model} hostModel + */ + var List = function(dimensions, hostModel) { + + dimensions = dimensions || ['x', 'y']; + + var dimensionInfos = {}; + var dimensionNames = []; + var invertedIndicesMap = {}; + + for (var i = 0; i < dimensions.length; i++) { + // Use the original dimensions[i], where other flag props may exists. + var dimensionInfo = dimensions[i]; + + if (isString(dimensionInfo)) { + dimensionInfo = { + name: dimensionInfo + }; + } + + var dimensionName = dimensionInfo.name; + dimensionInfo.type = dimensionInfo.type || 'float'; + if (!dimensionInfo.coordDim) { + dimensionInfo.coordDim = dimensionName; + dimensionInfo.coordDimIndex = 0; + } + + dimensionInfo.otherDims = dimensionInfo.otherDims || {}; + dimensionNames.push(dimensionName); + dimensionInfos[dimensionName] = dimensionInfo; + + dimensionInfo.index = i; + + if (dimensionInfo.createInvertedIndices) { + invertedIndicesMap[dimensionName] = []; + } + } + + /** + * @readOnly + * @type {Array.} + */ + this.dimensions = dimensionNames; + + /** + * Infomation of each data dimension, like data type. + * @type {Object} + */ + this._dimensionInfos = dimensionInfos; + + /** + * @type {module:echarts/model/Model} + */ + this.hostModel = hostModel; + + /** + * @type {module:echarts/model/Model} + */ + this.dataType; + + /** + * Indices stores the indices of data subset after filtered. + * This data subset will be used in chart. + * @type {Array.} + * @readOnly + */ + this._indices = null; + + this._count = 0; + this._rawCount = 0; + + /** + * Data storage + * @type {Object.>} + * @private + */ + this._storage = {}; + + /** + * @type {Array.} + */ + this._nameList = []; + /** + * @type {Array.} + */ + this._idList = []; + + /** + * Models of data option is stored sparse for optimizing memory cost + * @type {Array.} + * @private + */ + this._optionModels = []; + + /** + * Global visual properties after visual coding + * @type {Object} + * @private + */ + this._visual = {}; + + /** + * Globel layout properties. + * @type {Object} + * @private + */ + this._layout = {}; + + /** + * Item visual properties after visual coding + * @type {Array.} + * @private + */ + this._itemVisuals = []; + + /** + * Key: visual type, Value: boolean + * @type {Object} + * @readOnly + */ + this.hasItemVisual = {}; + + /** + * Item layout properties after layout + * @type {Array.} + * @private + */ + this._itemLayouts = []; + + /** + * Graphic elemnents + * @type {Array.} + * @private + */ + this._graphicEls = []; + + /** + * Max size of each chunk. + * @type {number} + * @private + */ + this._chunkSize = 1e5; + + /** + * @type {number} + * @private + */ + this._chunkCount = 0; + + /** + * @type {Array.} + * @private + */ + this._rawData; + + /** + * Raw extent will not be cloned, but only transfered. + * It will not be calculated util needed. + * key: dim, + * value: {end: number, extent: Array.} + * @type {Object} + * @private + */ + this._rawExtent = {}; + + /** + * @type {Object} + * @private + */ + this._extent = {}; + + /** + * key: dim + * value: extent + * @type {Object} + * @private + */ + this._approximateExtent = {}; + + /** + * Cache summary info for fast visit. See "dimensionHelper". + * @type {Object} + * @private + */ + this._dimensionsSummary = summarizeDimensions(this); + + /** + * @type {Object.} + * @private + */ + this._invertedIndicesMap = invertedIndicesMap; + + /** + * @type {Object} + * @private + */ + this._calculationInfo = {}; + }; + + var listProto = List.prototype; + + listProto.type = 'list'; + + /** + * If each data item has it's own option + * @type {boolean} + */ + listProto.hasItemOption = true; + + /** + * Get dimension name + * @param {string|number} dim + * Dimension can be concrete names like x, y, z, lng, lat, angle, radius + * Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius' + * @return {string} Concrete dim name. + */ + listProto.getDimension = function(dim) { + if (!isNaN(dim)) { + dim = this.dimensions[dim] || dim; + } + return dim; + }; + + /** + * Get type and calculation info of particular dimension + * @param {string|number} dim + * Dimension can be concrete names like x, y, z, lng, lat, angle, radius + * Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius' + */ + listProto.getDimensionInfo = function(dim) { + // Do not clone, because there may be categories in dimInfo. + return this._dimensionInfos[this.getDimension(dim)]; + }; + + /** + * @return {Array.} concrete dimension name list on coord. + */ + listProto.getDimensionsOnCoord = function() { + return this._dimensionsSummary.dataDimsOnCoord.slice(); + }; + + /** + * @param {string} coordDim + * @param {number} [idx] A coordDim may map to more than one data dim. + * If idx is `true`, return a array of all mapped dims. + * If idx is not specified, return the first dim not extra. + * @return {string|Array.} concrete data dim. + * If idx is number, and not found, return null/undefined. + * If idx is `true`, and not found, return empty array (always return array). + */ + listProto.mapDimension = function(coordDim, idx) { + var dimensionsSummary = this._dimensionsSummary; + + if (idx == null) { + return dimensionsSummary.encodeFirstDimNotExtra[coordDim]; + } + + var dims = dimensionsSummary.encode[coordDim]; + return idx === true + // always return array if idx is `true` + ? + (dims || []).slice() : + (dims && dims[idx]); + }; + + /** + * Initialize from data + * @param {Array.} data source or data or data provider. + * @param {Array.} [nameLIst] The name of a datum is used on data diff and + * defualt label/tooltip. + * A name can be specified in encode.itemName, + * or dataItem.name (only for series option data), + * or provided in nameList from outside. + * @param {Function} [dimValueGetter] (dataItem, dimName, dataIndex, dimIndex) => number + */ + listProto.initData = function(data, nameList, dimValueGetter) { + + var notProvider = Source.isInstance(data) || isArrayLike(data); + if (notProvider) { + data = new DefaultDataProvider(data, this.dimensions.length); + } + + if (__DEV__) { + if (!notProvider && (typeof data.getItem != 'function' || typeof data.count != 'function')) { + throw new Error('Inavlid data provider.'); + } + } + + this._rawData = data; + + // Clear + this._storage = {}; + this._indices = null; + + this._nameList = nameList || []; + + this._idList = []; + + this._nameRepeatCount = {}; + + if (!dimValueGetter) { + this.hasItemOption = false; + } + + /** + * @readOnly + */ + this.defaultDimValueGetter = defaultDimValueGetters[ + this._rawData.getSource().sourceFormat + ]; + + // Default dim value getter + this._dimValueGetter = dimValueGetter = dimValueGetter || + this.defaultDimValueGetter; + + // Reset raw extent. + this._rawExtent = {}; + + this._initDataFromProvider(0, data.count()); + + // If data has no item option. + if (data.pure) { + this.hasItemOption = false; + } + }; + + listProto.getProvider = function() { + return this._rawData; + }; + + listProto.appendData = function(data) { + if (__DEV__) { + assert$1(!this._indices, 'appendData can only be called on raw data.'); + } + + var rawData = this._rawData; + var start = this.count(); + rawData.appendData(data); + var end = rawData.count(); + if (!rawData.persistent) { + end += start; + } + this._initDataFromProvider(start, end); + }; + + listProto._initDataFromProvider = function(start, end) { + // Optimize. + if (start >= end) { + return; + } + + var chunkSize = this._chunkSize; + var rawData = this._rawData; + var storage = this._storage; + var dimensions = this.dimensions; + var dimLen = dimensions.length; + var dimensionInfoMap = this._dimensionInfos; + var nameList = this._nameList; + var idList = this._idList; + var rawExtent = this._rawExtent; + var nameRepeatCount = this._nameRepeatCount = {}; + var nameDimIdx; + + var chunkCount = this._chunkCount; + var lastChunkIndex = chunkCount - 1; + for (var i = 0; i < dimLen; i++) { + var dim = dimensions[i]; + if (!rawExtent[dim]) { + rawExtent[dim] = getInitialExtent(); + } + + var dimInfo = dimensionInfoMap[dim]; + if (dimInfo.otherDims.itemName === 0) { + nameDimIdx = this._nameDimIdx = i; + } + if (dimInfo.otherDims.itemId === 0) { + this._idDimIdx = i; + } + var DataCtor = dataCtors[dimInfo.type]; + + if (!storage[dim]) { + storage[dim] = []; + } + var resizeChunkArray = storage[dim][lastChunkIndex]; + if (resizeChunkArray && resizeChunkArray.length < chunkSize) { + var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize)); + // The cost of the copy is probably inconsiderable + // within the initial chunkSize. + for (var j = 0; j < resizeChunkArray.length; j++) { + newStore[j] = resizeChunkArray[j]; + } + storage[dim][lastChunkIndex] = newStore; + } + + // Create new chunks. + for (var k = chunkCount * chunkSize; k < end; k += chunkSize) { + storage[dim].push(new DataCtor(Math.min(end - k, chunkSize))); + } + this._chunkCount = storage[dim].length; + } + + var dataItem = new Array(dimLen); + for (var idx = start; idx < end; idx++) { + // NOTICE: Try not to write things into dataItem + dataItem = rawData.getItem(idx, dataItem); + // Each data item is value + // [1, 2] + // 2 + // Bar chart, line chart which uses category axis + // only gives the 'y' value. 'x' value is the indices of category + // Use a tempValue to normalize the value to be a (x, y) value + var chunkIndex = Math.floor(idx / chunkSize); + var chunkOffset = idx % chunkSize; + + // Store the data by dimensions + for (var k = 0; k < dimLen; k++) { + var dim = dimensions[k]; + var dimStorage = storage[dim][chunkIndex]; + // PENDING NULL is empty or zero + var val = this._dimValueGetter(dataItem, dim, idx, k); + dimStorage[chunkOffset] = val; + + var dimRawExtent = rawExtent[dim]; + if (val < dimRawExtent[0]) { + dimRawExtent[0] = val; + } + if (val > dimRawExtent[1]) { + dimRawExtent[1] = val; + } + } + + // ??? FIXME not check by pure but sourceFormat? + // TODO refactor these logic. + if (!rawData.pure) { + var name = nameList[idx]; + + if (dataItem && name == null) { + // If dataItem is {name: ...}, it has highest priority. + // That is appropriate for many common cases. + if (dataItem.name != null) { + // There is no other place to persistent dataItem.name, + // so save it to nameList. + nameList[idx] = name = dataItem.name; + } else if (nameDimIdx != null) { + var nameDim = dimensions[nameDimIdx]; + var nameDimChunk = storage[nameDim][chunkIndex]; + if (nameDimChunk) { + name = nameDimChunk[chunkOffset]; + var ordinalMeta = dimensionInfoMap[nameDim].ordinalMeta; + if (ordinalMeta && ordinalMeta.categories.length) { + name = ordinalMeta.categories[name]; + } + } + } + } + + // Try using the id in option + // id or name is used on dynamical data, mapping old and new items. + var id = dataItem == null ? null : dataItem.id; + + if (id == null && name != null) { + // Use name as id and add counter to avoid same name + nameRepeatCount[name] = nameRepeatCount[name] || 0; + id = name; + if (nameRepeatCount[name] > 0) { + id += '__ec__' + nameRepeatCount[name]; + } + nameRepeatCount[name]++; + } + id != null && (idList[idx] = id); + } + } + + if (!rawData.persistent && rawData.clean) { + // Clean unused data if data source is typed array. + rawData.clean(); + } + + this._rawCount = this._count = end; + + // Reset data extent + this._extent = {}; + + prepareInvertedIndex(this); + }; + + function prepareInvertedIndex(list) { + var invertedIndicesMap = list._invertedIndicesMap; + each$1(invertedIndicesMap, function(invertedIndices, dim) { + var dimInfo = list._dimensionInfos[dim]; + + // Currently, only dimensions that has ordinalMeta can create inverted indices. + var ordinalMeta = dimInfo.ordinalMeta; + if (ordinalMeta) { + invertedIndices = invertedIndicesMap[dim] = new CtorUint32Array( + ordinalMeta.categories.length + ); + // The default value of TypedArray is 0. To avoid miss + // mapping to 0, we should set it as NaN. + for (var i = 0; i < invertedIndices.length; i++) { + invertedIndices[i] = NaN; + } + for (var i = 0; i < list._count; i++) { + // Only support the case that all values are distinct. + invertedIndices[list.get(dim, i)] = i; + } + } + }); + } + + function getRawValueFromStore(list, dimIndex, rawIndex) { + var val; + if (dimIndex != null) { + var chunkSize = list._chunkSize; + var chunkIndex = Math.floor(rawIndex / chunkSize); + var chunkOffset = rawIndex % chunkSize; + var dim = list.dimensions[dimIndex]; + var chunk = list._storage[dim][chunkIndex]; + if (chunk) { + val = chunk[chunkOffset]; + var ordinalMeta = list._dimensionInfos[dim].ordinalMeta; + if (ordinalMeta && ordinalMeta.categories.length) { + val = ordinalMeta.categories[val]; + } + } + } + return val; + } + + /** + * @return {number} + */ + listProto.count = function() { + return this._count; + }; + + listProto.getIndices = function() { + var newIndices; + + var indices = this._indices; + if (indices) { + var Ctor = indices.constructor; + var thisCount = this._count; + // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`. + if (Ctor === Array) { + newIndices = new Ctor(thisCount); + for (var i = 0; i < thisCount; i++) { + newIndices[i] = indices[i]; + } + } else { + newIndices = new Ctor(indices.buffer, 0, thisCount); + } + } else { + var Ctor = getIndicesCtor(this); + var newIndices = new Ctor(this.count()); + for (var i = 0; i < newIndices.length; i++) { + newIndices[i] = i; + } + } + + return newIndices; + }; + + /** + * Get value. Return NaN if idx is out of range. + * @param {string} dim Dim must be concrete name. + * @param {number} idx + * @param {boolean} stack + * @return {number} + */ + listProto.get = function(dim, idx /*, stack */ ) { + if (!(idx >= 0 && idx < this._count)) { + return NaN; + } + var storage = this._storage; + if (!storage[dim]) { + // TODO Warn ? + return NaN; + } + + idx = this.getRawIndex(idx); + + var chunkIndex = Math.floor(idx / this._chunkSize); + var chunkOffset = idx % this._chunkSize; + + var chunkStore = storage[dim][chunkIndex]; + var value = chunkStore[chunkOffset]; + // FIXME ordinal data type is not stackable + // if (stack) { + // var dimensionInfo = this._dimensionInfos[dim]; + // if (dimensionInfo && dimensionInfo.stackable) { + // var stackedOn = this.stackedOn; + // while (stackedOn) { + // // Get no stacked data of stacked on + // var stackedValue = stackedOn.get(dim, idx); + // // Considering positive stack, negative stack and empty data + // if ((value >= 0 && stackedValue > 0) // Positive stack + // || (value <= 0 && stackedValue < 0) // Negative stack + // ) { + // value += stackedValue; + // } + // stackedOn = stackedOn.stackedOn; + // } + // } + // } + + return value; + }; + + /** + * @param {string} dim concrete dim + * @param {number} rawIndex + * @return {number|string} + */ + listProto.getByRawIndex = function(dim, rawIdx) { + if (!(rawIdx >= 0 && rawIdx < this._rawCount)) { + return NaN; + } + var dimStore = this._storage[dim]; + if (!dimStore) { + // TODO Warn ? + return NaN; + } + + var chunkIndex = Math.floor(rawIdx / this._chunkSize); + var chunkOffset = rawIdx % this._chunkSize; + var chunkStore = dimStore[chunkIndex]; + return chunkStore[chunkOffset]; + }; + + /** + * FIXME Use `get` on chrome maybe slow(in filterSelf and selectRange). + * Hack a much simpler _getFast + * @private + */ + listProto._getFast = function(dim, rawIdx) { + var chunkIndex = Math.floor(rawIdx / this._chunkSize); + var chunkOffset = rawIdx % this._chunkSize; + var chunkStore = this._storage[dim][chunkIndex]; + return chunkStore[chunkOffset]; + }; + + /** + * Get value for multi dimensions. + * @param {Array.} [dimensions] If ignored, using all dimensions. + * @param {number} idx + * @return {number} + */ + listProto.getValues = function(dimensions, idx /*, stack */ ) { + var values = []; + + if (!isArray(dimensions)) { + // stack = idx; + idx = dimensions; + dimensions = this.dimensions; + } + + for (var i = 0, len = dimensions.length; i < len; i++) { + values.push(this.get(dimensions[i], idx /*, stack */ )); + } + + return values; + }; + + /** + * If value is NaN. Inlcuding '-' + * Only check the coord dimensions. + * @param {string} dim + * @param {number} idx + * @return {number} + */ + listProto.hasValue = function(idx) { + var dataDimsOnCoord = this._dimensionsSummary.dataDimsOnCoord; + var dimensionInfos = this._dimensionInfos; + for (var i = 0, len = dataDimsOnCoord.length; i < len; i++) { + if ( + // Ordinal type can be string or number + dimensionInfos[dataDimsOnCoord[i]].type !== 'ordinal' + // FIXME check ordinal when using index? + && + isNaN(this.get(dataDimsOnCoord[i], idx)) + ) { + return false; + } + } + return true; + }; + + /** + * Get extent of data in one dimension + * @param {string} dim + * @param {boolean} stack + */ + listProto.getDataExtent = function(dim /*, stack */ ) { + // Make sure use concrete dim as cache name. + dim = this.getDimension(dim); + var dimData = this._storage[dim]; + var initialExtent = getInitialExtent(); + + // stack = !!((stack || false) && this.getCalculationInfo(dim)); + + if (!dimData) { + return initialExtent; + } + + // Make more strict checkings to ensure hitting cache. + var currEnd = this.count(); + // var cacheName = [dim, !!stack].join('_'); + // var cacheName = dim; + + // Consider the most cases when using data zoom, `getDataExtent` + // happened before filtering. We cache raw extent, which is not + // necessary to be cleared and recalculated when restore data. + var useRaw = !this._indices; // && !stack; + var dimExtent; + + if (useRaw) { + return this._rawExtent[dim].slice(); + } + dimExtent = this._extent[dim]; + if (dimExtent) { + return dimExtent.slice(); + } + dimExtent = initialExtent; + + var min = dimExtent[0]; + var max = dimExtent[1]; + + for (var i = 0; i < currEnd; i++) { + // var value = stack ? this.get(dim, i, true) : this._getFast(dim, this.getRawIndex(i)); + var value = this._getFast(dim, this.getRawIndex(i)); + value < min && (min = value); + value > max && (max = value); + } + + dimExtent = [min, max]; + + this._extent[dim] = dimExtent; + + return dimExtent; + }; + + /** + * Optimize for the scenario that data is filtered by a given extent. + * Consider that if data amount is more than hundreds of thousand, + * extent calculation will cost more than 10ms and the cache will + * be erased because of the filtering. + */ + listProto.getApproximateExtent = function(dim /*, stack */ ) { + dim = this.getDimension(dim); + return this._approximateExtent[dim] || this.getDataExtent(dim /*, stack */ ); + }; + + listProto.setApproximateExtent = function(extent, dim /*, stack */ ) { + dim = this.getDimension(dim); + this._approximateExtent[dim] = extent.slice(); + }; + + /** + * @param {string} key + * @return {*} + */ + listProto.getCalculationInfo = function(key) { + return this._calculationInfo[key]; + }; + + /** + * @param {string|Object} key or k-v object + * @param {*} [value] + */ + listProto.setCalculationInfo = function(key, value) { + isObject$4(key) ? + extend(this._calculationInfo, key) : + (this._calculationInfo[key] = value); + }; + + /** + * Get sum of data in one dimension + * @param {string} dim + */ + listProto.getSum = function(dim /*, stack */ ) { + var dimData = this._storage[dim]; + var sum = 0; + if (dimData) { + for (var i = 0, len = this.count(); i < len; i++) { + var value = this.get(dim, i /*, stack */ ); + if (!isNaN(value)) { + sum += value; + } + } + } + return sum; + }; + + /** + * Get median of data in one dimension + * @param {string} dim + */ + listProto.getMedian = function(dim /*, stack */ ) { + var dimDataArray = []; + // map all data of one dimension + this.each(dim, function(val, idx) { + if (!isNaN(val)) { + dimDataArray.push(val); + } + }); + + // TODO + // Use quick select? + + // immutability & sort + var sortedDimDataArray = [].concat(dimDataArray).sort(function(a, b) { + return a - b; + }); + var len = this.count(); + // calculate median + return len === 0 ? 0 : + len % 2 === 1 ? sortedDimDataArray[(len - 1) / 2] : + (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2; + }; + + // /** + // * Retreive the index with given value + // * @param {string} dim Concrete dimension. + // * @param {number} value + // * @return {number} + // */ + // Currently incorrect: should return dataIndex but not rawIndex. + // Do not fix it until this method is to be used somewhere. + // FIXME Precision of float value + // listProto.indexOf = function (dim, value) { + // var storage = this._storage; + // var dimData = storage[dim]; + // var chunkSize = this._chunkSize; + // if (dimData) { + // for (var i = 0, len = this.count(); i < len; i++) { + // var chunkIndex = Math.floor(i / chunkSize); + // var chunkOffset = i % chunkSize; + // if (dimData[chunkIndex][chunkOffset] === value) { + // return i; + // } + // } + // } + // return -1; + // }; + + /** + * Only support the dimension which inverted index created. + * Do not support other cases until required. + * @param {string} concrete dim + * @param {number|string} value + * @return {number} rawIndex + */ + listProto.rawIndexOf = function(dim, value) { + var invertedIndices = dim && this._invertedIndicesMap[dim]; + if (__DEV__) { + if (!invertedIndices) { + throw new Error('Do not supported yet'); + } + } + var rawIndex = invertedIndices[value]; + if (rawIndex == null || isNaN(rawIndex)) { + return -1; + } + return rawIndex; + }; + + /** + * Retreive the index with given name + * @param {number} idx + * @param {number} name + * @return {number} + */ + listProto.indexOfName = function(name) { + for (var i = 0, len = this.count(); i < len; i++) { + if (this.getName(i) === name) { + return i; + } + } + + return -1; + }; + + /** + * Retreive the index with given raw data index + * @param {number} idx + * @param {number} name + * @return {number} + */ + listProto.indexOfRawIndex = function(rawIndex) { + if (!this._indices) { + return rawIndex; + } + + if (rawIndex >= this._rawCount || rawIndex < 0) { + return -1; + } + + // Indices are ascending + var indices = this._indices; + + // If rawIndex === dataIndex + var rawDataIndex = indices[rawIndex]; + if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) { + return rawIndex; + } + + var left = 0; + var right = this._count - 1; + while (left <= right) { + var mid = (left + right) / 2 | 0; + if (indices[mid] < rawIndex) { + left = mid + 1; + } else if (indices[mid] > rawIndex) { + right = mid - 1; + } else { + return mid; + } + } + return -1; + }; + + /** + * Retreive the index of nearest value + * @param {string} dim + * @param {number} value + * @param {number} [maxDistance=Infinity] + * @return {Array.} Considere multiple points has the same value. + */ + listProto.indicesOfNearest = function(dim, value, maxDistance) { + var storage = this._storage; + var dimData = storage[dim]; + var nearestIndices = []; + + if (!dimData) { + return nearestIndices; + } + + if (maxDistance == null) { + maxDistance = Infinity; + } + + var minDist = Number.MAX_VALUE; + var minDiff = -1; + for (var i = 0, len = this.count(); i < len; i++) { + var diff = value - this.get(dim, i /*, stack */ ); + var dist = Math.abs(diff); + if (diff <= maxDistance && dist <= minDist) { + // For the case of two data are same on xAxis, which has sequence data. + // Show the nearest index + // https://github.com/ecomfe/echarts/issues/2869 + if (dist < minDist || (diff >= 0 && minDiff < 0)) { + minDist = dist; + minDiff = diff; + nearestIndices.length = 0; + } + nearestIndices.push(i); + } + } + return nearestIndices; + }; + + /** + * Get raw data index + * @param {number} idx + * @return {number} + */ + listProto.getRawIndex = getRawIndexWithoutIndices; + + function getRawIndexWithoutIndices(idx) { + return idx; + } + + function getRawIndexWithIndices(idx) { + if (idx < this._count && idx >= 0) { + return this._indices[idx]; + } + return -1; + } + + /** + * Get raw data item + * @param {number} idx + * @return {number} + */ + listProto.getRawDataItem = function(idx) { + if (!this._rawData.persistent) { + var val = []; + for (var i = 0; i < this.dimensions.length; i++) { + var dim = this.dimensions[i]; + val.push(this.get(dim, idx)); + } + return val; + } else { + return this._rawData.getItem(this.getRawIndex(idx)); + } + }; + + /** + * @param {number} idx + * @param {boolean} [notDefaultIdx=false] + * @return {string} + */ + listProto.getName = function(idx) { + var rawIndex = this.getRawIndex(idx); + return this._nameList[rawIndex] || + getRawValueFromStore(this, this._nameDimIdx, rawIndex) || + ''; + }; + + /** + * @param {number} idx + * @param {boolean} [notDefaultIdx=false] + * @return {string} + */ + listProto.getId = function(idx) { + return getId(this, this.getRawIndex(idx)); + }; + + function getId(list, rawIndex) { + var id = list._idList[rawIndex]; + if (id == null) { + id = getRawValueFromStore(list, list._idDimIdx, rawIndex); + } + if (id == null) { + // FIXME Check the usage in graph, should not use prefix. + id = ID_PREFIX + rawIndex; + } + return id; + } + + function normalizeDimensions(dimensions) { + if (!isArray(dimensions)) { + dimensions = [dimensions]; + } + return dimensions; + } + + function validateDimensions(list, dims) { + for (var i = 0; i < dims.length; i++) { + // stroage may be empty when no data, so use + // dimensionInfos to check. + if (!list._dimensionInfos[dims[i]]) { + console.error('Unkown dimension ' + dims[i]); + } + } + } + + /** + * Data iteration + * @param {string|Array.} + * @param {Function} cb + * @param {*} [context=this] + * + * @example + * list.each('x', function (x, idx) {}); + * list.each(['x', 'y'], function (x, y, idx) {}); + * list.each(function (idx) {}) + */ + listProto.each = function(dims, cb, context, contextCompat) { + 'use strict'; + + if (!this._count) { + return; + } + + if (typeof dims === 'function') { + contextCompat = context; + context = cb; + cb = dims; + dims = []; + } + + // contextCompat just for compat echarts3 + context = context || contextCompat || this; + + dims = map(normalizeDimensions(dims), this.getDimension, this); + + if (__DEV__) { + validateDimensions(this, dims); + } + + var dimSize = dims.length; + + for (var i = 0; i < this.count(); i++) { + // Simple optimization + switch (dimSize) { + case 0: + cb.call(context, i); + break; + case 1: + cb.call(context, this.get(dims[0], i), i); + break; + case 2: + cb.call(context, this.get(dims[0], i), this.get(dims[1], i), i); + break; + default: + var k = 0; + var value = []; + for (; k < dimSize; k++) { + value[k] = this.get(dims[k], i); + } + // Index + value[k] = i; + cb.apply(context, value); + } + } + }; + + /** + * Data filter + * @param {string|Array.} + * @param {Function} cb + * @param {*} [context=this] + */ + listProto.filterSelf = function(dimensions, cb, context, contextCompat) { + 'use strict'; + + if (!this._count) { + return; + } + + if (typeof dimensions === 'function') { + contextCompat = context; + context = cb; + cb = dimensions; + dimensions = []; + } + + // contextCompat just for compat echarts3 + context = context || contextCompat || this; + + dimensions = map( + normalizeDimensions(dimensions), this.getDimension, this + ); + + if (__DEV__) { + validateDimensions(this, dimensions); + } + + + var count = this.count(); + var Ctor = getIndicesCtor(this); + var newIndices = new Ctor(count); + var value = []; + var dimSize = dimensions.length; + + var offset = 0; + var dim0 = dimensions[0]; + + for (var i = 0; i < count; i++) { + var keep; + var rawIdx = this.getRawIndex(i); + // Simple optimization + if (dimSize === 0) { + keep = cb.call(context, i); + } else if (dimSize === 1) { + var val = this._getFast(dim0, rawIdx); + keep = cb.call(context, val, i); + } else { + for (var k = 0; k < dimSize; k++) { + value[k] = this._getFast(dim0, rawIdx); + } + value[k] = i; + keep = cb.apply(context, value); + } + if (keep) { + newIndices[offset++] = rawIdx; + } + } + + // Set indices after filtered. + if (offset < count) { + this._indices = newIndices; + } + this._count = offset; + // Reset data extent + this._extent = {}; + + this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices; + + return this; + }; + + /** + * Select data in range. (For optimization of filter) + * (Manually inline code, support 5 million data filtering in data zoom.) + */ + listProto.selectRange = function(range) { + 'use strict'; + + if (!this._count) { + return; + } + + var dimensions = []; + for (var dim in range) { + if (range.hasOwnProperty(dim)) { + dimensions.push(dim); + } + } + + if (__DEV__) { + validateDimensions(this, dimensions); + } + + var dimSize = dimensions.length; + if (!dimSize) { + return; + } + + var originalCount = this.count(); + var Ctor = getIndicesCtor(this); + var newIndices = new Ctor(originalCount); + + var offset = 0; + var dim0 = dimensions[0]; + + var min = range[dim0][0]; + var max = range[dim0][1]; + + var quickFinished = false; + if (!this._indices) { + // Extreme optimization for common case. About 2x faster in chrome. + var idx = 0; + if (dimSize === 1) { + var dimStorage = this._storage[dimensions[0]]; + for (var k = 0; k < this._chunkCount; k++) { + var chunkStorage = dimStorage[k]; + var len = Math.min(this._count - k * this._chunkSize, this._chunkSize); + for (var i = 0; i < len; i++) { + var val = chunkStorage[i]; + // NaN will not be filtered. Consider the case, in line chart, empty + // value indicates the line should be broken. But for the case like + // scatter plot, a data item with empty value will not be rendered, + // but the axis extent may be effected if some other dim of the data + // item has value. Fortunately it is not a significant negative effect. + if ( + (val >= min && val <= max) || isNaN(val) + ) { + newIndices[offset++] = idx; + } + idx++; + } + } + quickFinished = true; + } else if (dimSize === 2) { + var dimStorage = this._storage[dim0]; + var dimStorage2 = this._storage[dimensions[1]]; + var min2 = range[dimensions[1]][0]; + var max2 = range[dimensions[1]][1]; + for (var k = 0; k < this._chunkCount; k++) { + var chunkStorage = dimStorage[k]; + var chunkStorage2 = dimStorage2[k]; + var len = Math.min(this._count - k * this._chunkSize, this._chunkSize); + for (var i = 0; i < len; i++) { + var val = chunkStorage[i]; + var val2 = chunkStorage2[i]; + // Do not filter NaN, see comment above. + if (( + (val >= min && val <= max) || isNaN(val) + ) && + ( + (val2 >= min2 && val2 <= max2) || isNaN(val2) + ) + ) { + newIndices[offset++] = idx; + } + idx++; + } + } + quickFinished = true; + } + } + if (!quickFinished) { + if (dimSize === 1) { + for (var i = 0; i < originalCount; i++) { + var rawIndex = this.getRawIndex(i); + var val = this._getFast(dim0, rawIndex); + // Do not filter NaN, see comment above. + if ( + (val >= min && val <= max) || isNaN(val) + ) { + newIndices[offset++] = rawIndex; + } + } + } else { + for (var i = 0; i < originalCount; i++) { + var keep = true; + var rawIndex = this.getRawIndex(i); + for (var k = 0; k < dimSize; k++) { + var dimk = dimensions[k]; + var val = this._getFast(dim, rawIndex); + // Do not filter NaN, see comment above. + if (val < range[dimk][0] || val > range[dimk][1]) { + keep = false; + } + } + if (keep) { + newIndices[offset++] = this.getRawIndex(i); + } + } + } + } + + // Set indices after filtered. + if (offset < originalCount) { + this._indices = newIndices; + } + this._count = offset; + // Reset data extent + this._extent = {}; + + this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices; + + return this; + }; + + /** + * Data mapping to a plain array + * @param {string|Array.} [dimensions] + * @param {Function} cb + * @param {*} [context=this] + * @return {Array} + */ + listProto.mapArray = function(dimensions, cb, context, contextCompat) { + 'use strict'; + + if (typeof dimensions === 'function') { + contextCompat = context; + context = cb; + cb = dimensions; + dimensions = []; + } + + // contextCompat just for compat echarts3 + context = context || contextCompat || this; + + var result = []; + this.each(dimensions, function() { + result.push(cb && cb.apply(this, arguments)); + }, context); + return result; + }; + + // Data in excludeDimensions is copied, otherwise transfered. + function cloneListForMapAndSample(original, excludeDimensions) { + var allDimensions = original.dimensions; + var list = new List( + map(allDimensions, original.getDimensionInfo, original), + original.hostModel + ); + // FIXME If needs stackedOn, value may already been stacked + transferProperties(list, original); + + var storage = list._storage = {}; + var originalStorage = original._storage; + + // Init storage + for (var i = 0; i < allDimensions.length; i++) { + var dim = allDimensions[i]; + if (originalStorage[dim]) { + // Notice that we do not reset invertedIndicesMap here, becuase + // there is no scenario of mapping or sampling ordinal dimension. + if (indexOf(excludeDimensions, dim) >= 0) { + storage[dim] = cloneDimStore(originalStorage[dim]); + list._rawExtent[dim] = getInitialExtent(); + list._extent[dim] = null; + } else { + // Direct reference for other dimensions + storage[dim] = originalStorage[dim]; + } + } + } + return list; + } + + function cloneDimStore(originalDimStore) { + var newDimStore = new Array(originalDimStore.length); + for (var j = 0; j < originalDimStore.length; j++) { + newDimStore[j] = cloneChunk(originalDimStore[j]); + } + return newDimStore; + } + + function getInitialExtent() { + return [Infinity, -Infinity]; + } + + /** + * Data mapping to a new List with given dimensions + * @param {string|Array.} dimensions + * @param {Function} cb + * @param {*} [context=this] + * @return {Array} + */ + listProto.map = function(dimensions, cb, context, contextCompat) { + 'use strict'; + + // contextCompat just for compat echarts3 + context = context || contextCompat || this; + + dimensions = map( + normalizeDimensions(dimensions), this.getDimension, this + ); + + if (__DEV__) { + validateDimensions(this, dimensions); + } + + var list = cloneListForMapAndSample(this, dimensions); + + // Following properties are all immutable. + // So we can reference to the same value + list._indices = this._indices; + list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices; + + var storage = list._storage; + + var tmpRetValue = []; + var chunkSize = this._chunkSize; + var dimSize = dimensions.length; + var dataCount = this.count(); + var values = []; + var rawExtent = list._rawExtent; + + for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) { + for (var dimIndex = 0; dimIndex < dimSize; dimIndex++) { + values[dimIndex] = this.get(dimensions[dimIndex], dataIndex /*, stack */ ); + } + values[dimSize] = dataIndex; + + var retValue = cb && cb.apply(context, values); + if (retValue != null) { + // a number or string (in oridinal dimension)? + if (typeof retValue !== 'object') { + tmpRetValue[0] = retValue; + retValue = tmpRetValue; + } + + var rawIndex = this.getRawIndex(dataIndex); + var chunkIndex = Math.floor(rawIndex / chunkSize); + var chunkOffset = rawIndex % chunkSize; + + for (var i = 0; i < retValue.length; i++) { + var dim = dimensions[i]; + var val = retValue[i]; + var rawExtentOnDim = rawExtent[dim]; + + var dimStore = storage[dim]; + if (dimStore) { + dimStore[chunkIndex][chunkOffset] = val; + } + + if (val < rawExtentOnDim[0]) { + rawExtentOnDim[0] = val; + } + if (val > rawExtentOnDim[1]) { + rawExtentOnDim[1] = val; + } + } + } + } + + return list; + }; + + /** + * Large data down sampling on given dimension + * @param {string} dimension + * @param {number} rate + * @param {Function} sampleValue + * @param {Function} sampleIndex Sample index for name and id + */ + listProto.downSample = function(dimension, rate, sampleValue, sampleIndex) { + var list = cloneListForMapAndSample(this, [dimension]); + var targetStorage = list._storage; + + var frameValues = []; + var frameSize = Math.floor(1 / rate); + + var dimStore = targetStorage[dimension]; + var len = this.count(); + var chunkSize = this._chunkSize; + var rawExtentOnDim = list._rawExtent[dimension]; + + var newIndices = new(getIndicesCtor(this))(len); + + var offset = 0; + for (var i = 0; i < len; i += frameSize) { + // Last frame + if (frameSize > len - i) { + frameSize = len - i; + frameValues.length = frameSize; + } + for (var k = 0; k < frameSize; k++) { + var dataIdx = this.getRawIndex(i + k); + var originalChunkIndex = Math.floor(dataIdx / chunkSize); + var originalChunkOffset = dataIdx % chunkSize; + frameValues[k] = dimStore[originalChunkIndex][originalChunkOffset]; + } + var value = sampleValue(frameValues); + var sampleFrameIdx = this.getRawIndex( + Math.min(i + sampleIndex(frameValues, value) || 0, len - 1) + ); + var sampleChunkIndex = Math.floor(sampleFrameIdx / chunkSize); + var sampleChunkOffset = sampleFrameIdx % chunkSize; + // Only write value on the filtered data + dimStore[sampleChunkIndex][sampleChunkOffset] = value; + + if (value < rawExtentOnDim[0]) { + rawExtentOnDim[0] = value; + } + if (value > rawExtentOnDim[1]) { + rawExtentOnDim[1] = value; + } + + newIndices[offset++] = sampleFrameIdx; + } + + list._count = offset; + list._indices = newIndices; + + list.getRawIndex = getRawIndexWithIndices; + + return list; + }; + + /** + * Get model of one data item. + * + * @param {number} idx + */ + // FIXME Model proxy ? + listProto.getItemModel = function(idx) { + var hostModel = this.hostModel; + return new Model(this.getRawDataItem(idx), hostModel, hostModel && hostModel.ecModel); + }; + + /** + * Create a data differ + * @param {module:echarts/data/List} otherList + * @return {module:echarts/data/DataDiffer} + */ + listProto.diff = function(otherList) { + var thisList = this; + + return new DataDiffer( + otherList ? otherList.getIndices() : [], + this.getIndices(), + function(idx) { + return getId(otherList, idx); + }, + function(idx) { + return getId(thisList, idx); + } + ); + }; + /** + * Get visual property. + * @param {string} key + */ + listProto.getVisual = function(key) { + var visual = this._visual; + return visual && visual[key]; + }; + + /** + * Set visual property + * @param {string|Object} key + * @param {*} [value] + * + * @example + * setVisual('color', color); + * setVisual({ + * 'color': color + * }); + */ + listProto.setVisual = function(key, val) { + if (isObject$4(key)) { + for (var name in key) { + if (key.hasOwnProperty(name)) { + this.setVisual(name, key[name]); + } + } + return; + } + this._visual = this._visual || {}; + this._visual[key] = val; + }; + + /** + * Set layout property. + * @param {string|Object} key + * @param {*} [val] + */ + listProto.setLayout = function(key, val) { + if (isObject$4(key)) { + for (var name in key) { + if (key.hasOwnProperty(name)) { + this.setLayout(name, key[name]); + } + } + return; + } + this._layout[key] = val; + }; + + /** + * Get layout property. + * @param {string} key. + * @return {*} + */ + listProto.getLayout = function(key) { + return this._layout[key]; + }; + + /** + * Get layout of single data item + * @param {number} idx + */ + listProto.getItemLayout = function(idx) { + return this._itemLayouts[idx]; + }; + + /** + * Set layout of single data item + * @param {number} idx + * @param {Object} layout + * @param {boolean=} [merge=false] + */ + listProto.setItemLayout = function(idx, layout, merge$$1) { + this._itemLayouts[idx] = merge$$1 ? + extend(this._itemLayouts[idx] || {}, layout) : + layout; + }; + + /** + * Clear all layout of single data item + */ + listProto.clearItemLayouts = function() { + this._itemLayouts.length = 0; + }; + + /** + * Get visual property of single data item + * @param {number} idx + * @param {string} key + * @param {boolean} [ignoreParent=false] + */ + listProto.getItemVisual = function(idx, key, ignoreParent) { + var itemVisual = this._itemVisuals[idx]; + var val = itemVisual && itemVisual[key]; + if (val == null && !ignoreParent) { + // Use global visual property + return this.getVisual(key); + } + return val; + }; + + /** + * Set visual property of single data item + * + * @param {number} idx + * @param {string|Object} key + * @param {*} [value] + * + * @example + * setItemVisual(0, 'color', color); + * setItemVisual(0, { + * 'color': color + * }); + */ + listProto.setItemVisual = function(idx, key, value) { + var itemVisual = this._itemVisuals[idx] || {}; + var hasItemVisual = this.hasItemVisual; + this._itemVisuals[idx] = itemVisual; + + if (isObject$4(key)) { + for (var name in key) { + if (key.hasOwnProperty(name)) { + itemVisual[name] = key[name]; + hasItemVisual[name] = true; + } + } + return; + } + itemVisual[key] = value; + hasItemVisual[key] = true; + }; + + /** + * Clear itemVisuals and list visual. + */ + listProto.clearAllVisual = function() { + this._visual = {}; + this._itemVisuals = []; + this.hasItemVisual = {}; + }; + + var setItemDataAndSeriesIndex = function(child) { + child.seriesIndex = this.seriesIndex; + child.dataIndex = this.dataIndex; + child.dataType = this.dataType; + }; + /** + * Set graphic element relative to data. It can be set as null + * @param {number} idx + * @param {module:zrender/Element} [el] + */ + listProto.setItemGraphicEl = function(idx, el) { + var hostModel = this.hostModel; + + if (el) { + // Add data index and series index for indexing the data by element + // Useful in tooltip + el.dataIndex = idx; + el.dataType = this.dataType; + el.seriesIndex = hostModel && hostModel.seriesIndex; + if (el.type === 'group') { + el.traverse(setItemDataAndSeriesIndex, el); + } + } + + this._graphicEls[idx] = el; + }; + + /** + * @param {number} idx + * @return {module:zrender/Element} + */ + listProto.getItemGraphicEl = function(idx) { + return this._graphicEls[idx]; + }; + + /** + * @param {Function} cb + * @param {*} context + */ + listProto.eachItemGraphicEl = function(cb, context) { + each$1(this._graphicEls, function(el, idx) { + if (el) { + cb && cb.call(context, el, idx); + } + }); + }; + + /** + * Shallow clone a new list except visual and layout properties, and graph elements. + * New list only change the indices. + */ + listProto.cloneShallow = function(list) { + if (!list) { + var dimensionInfoList = map(this.dimensions, this.getDimensionInfo, this); + list = new List(dimensionInfoList, this.hostModel); + } + + // FIXME + list._storage = this._storage; + + transferProperties(list, this); + + // Clone will not change the data extent and indices + if (this._indices) { + var Ctor = this._indices.constructor; + list._indices = new Ctor(this._indices); + } else { + list._indices = null; + } + list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices; + + return list; + }; + + /** + * Wrap some method to add more feature + * @param {string} methodName + * @param {Function} injectFunction + */ + listProto.wrapMethod = function(methodName, injectFunction) { + var originalMethod = this[methodName]; + if (typeof originalMethod !== 'function') { + return; + } + this.__wrappedMethods = this.__wrappedMethods || []; + this.__wrappedMethods.push(methodName); + this[methodName] = function() { + var res = originalMethod.apply(this, arguments); + return injectFunction.apply(this, [res].concat(slice(arguments))); + }; + }; + + // Methods that create a new list based on this list should be listed here. + // Notice that those method should `RETURN` the new list. + listProto.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'map']; + // Methods that change indices of this list should be listed here. + listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange']; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @deprecated + * Use `echarts/data/helper/createDimensions` instead. + */ + + /** + * @see {module:echarts/test/ut/spec/data/completeDimensions} + * + * Complete the dimensions array, by user defined `dimension` and `encode`, + * and guessing from the data structure. + * If no 'value' dimension specified, the first no-named dimension will be + * named as 'value'. + * + * @param {Array.} sysDims Necessary dimensions, like ['x', 'y'], which + * provides not only dim template, but also default order. + * properties: 'name', 'type', 'displayName'. + * `name` of each item provides default coord name. + * [{dimsDef: [string|Object, ...]}, ...] dimsDef of sysDim item provides default dim name, and + * provide dims count that the sysDim required. + * [{ordinalMeta}] can be specified. + * @param {module:echarts/data/Source|Array|Object} source or data (for compatibal with pervious) + * @param {Object} [opt] + * @param {Array.} [opt.dimsDef] option.series.dimensions User defined dimensions + * For example: ['asdf', {name, type}, ...]. + * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3} + * @param {string} [opt.generateCoord] Generate coord dim with the given name. + * If not specified, extra dim names will be: + * 'value', 'value0', 'value1', ... + * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`. + * If `generateCoordCount` specified, the generated dim names will be: + * `generateCoord` + 0, `generateCoord` + 1, ... + * can be Infinity, indicate that use all of the remain columns. + * @param {number} [opt.dimCount] If not specified, guess by the first data item. + * @param {number} [opt.encodeDefaulter] If not specified, auto find the next available data dim. + * @return {Array.} [{ + * name: string mandatory, + * displayName: string, the origin name in dimsDef, see source helper. + * If displayName given, the tooltip will displayed vertically. + * coordDim: string mandatory, + * coordDimIndex: number mandatory, + * type: string optional, + * otherDims: { never null/undefined + * tooltip: number optional, + * label: number optional, + * itemName: number optional, + * seriesName: number optional, + * }, + * isExtraCoord: boolean true if coord is generated + * (not specified in encode and not series specified) + * other props ... + * }] + */ + function completeDimensions(sysDims, source, opt) { + if (!Source.isInstance(source)) { + source = Source.seriesDataToSource(source); + } + + opt = opt || {}; + sysDims = (sysDims || []).slice(); + var dimsDef = (opt.dimsDef || []).slice(); + var encodeDef = createHashMap(opt.encodeDef); + var dataDimNameMap = createHashMap(); + var coordDimNameMap = createHashMap(); + // var valueCandidate; + var result = []; + + var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimCount); + + // Apply user defined dims (`name` and `type`) and init result. + for (var i = 0; i < dimCount; i++) { + var dimDefItem = dimsDef[i] = extend({}, isObject$1(dimsDef[i]) ? dimsDef[i] : { + name: dimsDef[i] + }); + var userDimName = dimDefItem.name; + var resultItem = result[i] = { + otherDims: {} + }; + // Name will be applied later for avoiding duplication. + if (userDimName != null && dataDimNameMap.get(userDimName) == null) { + // Only if `series.dimensions` is defined in option + // displayName, will be set, and dimension will be diplayed vertically in + // tooltip by default. + resultItem.name = resultItem.displayName = userDimName; + dataDimNameMap.set(userDimName, i); + } + dimDefItem.type != null && (resultItem.type = dimDefItem.type); + dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName); + } + + // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`. + encodeDef.each(function(dataDims, coordDim) { + dataDims = normalizeToArray(dataDims).slice(); + var validDataDims = encodeDef.set(coordDim, []); + each$1(dataDims, function(resultDimIdx, idx) { + // The input resultDimIdx can be dim name or index. + isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx)); + if (resultDimIdx != null && resultDimIdx < dimCount) { + validDataDims[idx] = resultDimIdx; + applyDim(result[resultDimIdx], coordDim, idx); + } + }); + }); + + // Apply templetes and default order from `sysDims`. + var availDimIdx = 0; + each$1(sysDims, function(sysDimItem, sysDimIndex) { + var coordDim; + var sysDimItem; + var sysDimItemDimsDef; + var sysDimItemOtherDims; + if (isString(sysDimItem)) { + coordDim = sysDimItem; + sysDimItem = {}; + } else { + coordDim = sysDimItem.name; + var ordinalMeta = sysDimItem.ordinalMeta; + sysDimItem.ordinalMeta = null; + sysDimItem = clone(sysDimItem); + sysDimItem.ordinalMeta = ordinalMeta; + // `coordDimIndex` should not be set directly. + sysDimItemDimsDef = sysDimItem.dimsDef; + sysDimItemOtherDims = sysDimItem.otherDims; + sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = + null; + } + + var dataDims = normalizeToArray(encodeDef.get(coordDim)); + // dimensions provides default dim sequences. + if (!dataDims.length) { + for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) { + while (availDimIdx < result.length && result[availDimIdx].coordDim != null) { + availDimIdx++; + } + availDimIdx < result.length && dataDims.push(availDimIdx++); + } + } + + // Apply templates. + each$1(dataDims, function(resultDimIdx, coordDimIndex) { + var resultItem = result[resultDimIdx]; + applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex); + if (resultItem.name == null && sysDimItemDimsDef) { + var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex]; + !isObject$1(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = { + name: sysDimItemDimsDefItem + }); + resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name; + resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip; + } + // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}} + sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims); + }); + }); + + function applyDim(resultItem, coordDim, coordDimIndex) { + if (OTHER_DIMENSIONS.get(coordDim) != null) { + resultItem.otherDims[coordDim] = coordDimIndex; + } else { + resultItem.coordDim = coordDim; + resultItem.coordDimIndex = coordDimIndex; + coordDimNameMap.set(coordDim, true); + } + } + + // Make sure the first extra dim is 'value'. + var generateCoord = opt.generateCoord; + var generateCoordCount = opt.generateCoordCount; + var fromZero = generateCoordCount != null; + generateCoordCount = generateCoord ? (generateCoordCount || 1) : 0; + var extra = generateCoord || 'value'; + + // Set dim `name` and other `coordDim` and other props. + for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) { + var resultItem = result[resultDimIdx] = result[resultDimIdx] || {}; + var coordDim = resultItem.coordDim; + + if (coordDim == null) { + resultItem.coordDim = genName( + extra, coordDimNameMap, fromZero + ); + resultItem.coordDimIndex = 0; + if (!generateCoord || generateCoordCount <= 0) { + resultItem.isExtraCoord = true; + } + generateCoordCount--; + } + + resultItem.name == null && (resultItem.name = genName( + resultItem.coordDim, + dataDimNameMap + )); + + if (resultItem.type == null && guessOrdinal(source, resultDimIdx, resultItem.name)) { + resultItem.type = 'ordinal'; + } + } + + return result; + } + + // ??? TODO + // Originally detect dimCount by data[0]. Should we + // optimize it to only by sysDims and dimensions and encode. + // So only necessary dims will be initialized. + // But + // (1) custom series should be considered. where other dims + // may be visited. + // (2) sometimes user need to calcualte bubble size or use visualMap + // on other dimensions besides coordSys needed. + // So, dims that is not used by system, should be shared in storage? + function getDimCount(source, sysDims, dimsDef, optDimCount) { + // Note that the result dimCount should not small than columns count + // of data, otherwise `dataDimNameMap` checking will be incorrect. + var dimCount = Math.max( + source.dimensionsDetectCount || 1, + sysDims.length, + dimsDef.length, + optDimCount || 0 + ); + each$1(sysDims, function(sysDimItem) { + var sysDimItemDimsDef = sysDimItem.dimsDef; + sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length)); + }); + return dimCount; + } + + function genName(name, map$$1, fromZero) { + if (fromZero || map$$1.get(name) != null) { + var i = 0; + while (map$$1.get(name + i) != null) { + i++; + } + name += i; + } + map$$1.set(name, true); + return name; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Substitute `completeDimensions`. + * `completeDimensions` is to be deprecated. + */ + /** + * @param {module:echarts/data/Source|module:echarts/data/List} source or data. + * @param {Object|Array} [opt] + * @param {Array.} [opt.coordDimensions=[]] + * @param {number} [opt.dimensionsCount] + * @param {string} [opt.generateCoord] + * @param {string} [opt.generateCoordCount] + * @param {Array.} [opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define. + * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite source define. + * @return {Array.} dimensionsInfo + */ + var createDimensions = function(source, opt) { + opt = opt || {}; + return completeDimensions(opt.coordDimensions || [], source, { + dimsDef: opt.dimensionsDefine || source.dimensionsDefine, + encodeDef: opt.encodeDefine || source.encodeDefine, + dimCount: opt.dimensionsCount, + generateCoord: opt.generateCoord, + generateCoordCount: opt.generateCoordCount + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Note that it is too complicated to support 3d stack by value + * (have to create two-dimension inverted index), so in 3d case + * we just support that stacked by index. + * + * @param {module:echarts/model/Series} seriesModel + * @param {Array.} dimensionInfoList The same as the input of . + * The input dimensionInfoList will be modified. + * @param {Object} [opt] + * @param {boolean} [opt.stackedCoordDimension=''] Specify a coord dimension if needed. + * @param {boolean} [opt.byIndex=false] + * @return {Object} calculationInfo + * { + * stackedDimension: string + * stackedByDimension: string + * isStackedByIndex: boolean + * stackedOverDimension: string + * stackResultDimension: string + * } + */ + function enableDataStack(seriesModel, dimensionInfoList, opt) { + opt = opt || {}; + var byIndex = opt.byIndex; + var stackedCoordDimension = opt.stackedCoordDimension; + + // Compatibal: when `stack` is set as '', do not stack. + var mayStack = !!(seriesModel && seriesModel.get('stack')); + var stackedByDimInfo; + var stackedDimInfo; + var stackResultDimension; + var stackedOverDimension; + + each$1(dimensionInfoList, function(dimensionInfo, index) { + if (isString(dimensionInfo)) { + dimensionInfoList[index] = dimensionInfo = { + name: dimensionInfo + }; + } + + if (mayStack && !dimensionInfo.isExtraCoord) { + // Find the first ordinal dimension as the stackedByDimInfo. + if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) { + stackedByDimInfo = dimensionInfo; + } + // Find the first stackable dimension as the stackedDimInfo. + if (!stackedDimInfo && + dimensionInfo.type !== 'ordinal' && + dimensionInfo.type !== 'time' && + (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim) + ) { + stackedDimInfo = dimensionInfo; + } + } + }); + + if (stackedDimInfo && !byIndex && !stackedByDimInfo) { + // Compatible with previous design, value axis (time axis) only stack by index. + // It may make sense if the user provides elaborately constructed data. + byIndex = true; + } + + // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`. + // That put stack logic in List is for using conveniently in echarts extensions, but it + // might not be a good way. + if (stackedDimInfo) { + // Use a weird name that not duplicated with other names. + stackResultDimension = '__\0ecstackresult'; + stackedOverDimension = '__\0ecstackedover'; + + // Create inverted index to fast query index by value. + if (stackedByDimInfo) { + stackedByDimInfo.createInvertedIndices = true; + } + + var stackedDimCoordDim = stackedDimInfo.coordDim; + var stackedDimType = stackedDimInfo.type; + var stackedDimCoordIndex = 0; + + each$1(dimensionInfoList, function(dimensionInfo) { + if (dimensionInfo.coordDim === stackedDimCoordDim) { + stackedDimCoordIndex++; + } + }); + + dimensionInfoList.push({ + name: stackResultDimension, + coordDim: stackedDimCoordDim, + coordDimIndex: stackedDimCoordIndex, + type: stackedDimType, + isExtraCoord: true, + isCalculationCoord: true + }); + + stackedDimCoordIndex++; + + dimensionInfoList.push({ + name: stackedOverDimension, + // This dimension contains stack base (generally, 0), so do not set it as + // `stackedDimCoordDim` to avoid extent calculation, consider log scale. + coordDim: stackedOverDimension, + coordDimIndex: stackedDimCoordIndex, + type: stackedDimType, + isExtraCoord: true, + isCalculationCoord: true + }); + } + + return { + stackedDimension: stackedDimInfo && stackedDimInfo.name, + stackedByDimension: stackedByDimInfo && stackedByDimInfo.name, + isStackedByIndex: byIndex, + stackedOverDimension: stackedOverDimension, + stackResultDimension: stackResultDimension + }; + } + + /** + * @param {module:echarts/data/List} data + * @param {string} stackedDim + */ + function isDimensionStacked(data, stackedDim /*, stackedByDim*/ ) { + // Each single series only maps to one pair of axis. So we do not need to + // check stackByDim, whatever stacked by a dimension or stacked by index. + return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension'); + // && ( + // stackedByDim != null + // ? stackedByDim === data.getCalculationInfo('stackedByDimension') + // : data.getCalculationInfo('isStackedByIndex') + // ); + } + + /** + * @param {module:echarts/data/List} data + * @param {string} targetDim + * @param {string} [stackedByDim] If not input this parameter, check whether + * stacked by index. + * @return {string} dimension + */ + function getStackedDimension(data, targetDim) { + return isDimensionStacked(data, targetDim) ? + data.getCalculationInfo('stackResultDimension') : + targetDim; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/data/Source|Array} source Or raw data. + * @param {module:echarts/model/Series} seriesModel + * @param {Object} [opt] + * @param {string} [opt.generateCoord] + */ + function createListFromArray(source, seriesModel, opt) { + opt = opt || {}; + + if (!Source.isInstance(source)) { + source = Source.seriesDataToSource(source); + } + + var coordSysName = seriesModel.get('coordinateSystem'); + var registeredCoordSys = CoordinateSystemManager.get(coordSysName); + + var coordSysDefine = getCoordSysDefineBySeries(seriesModel); + + var coordSysDimDefs; + + if (coordSysDefine) { + coordSysDimDefs = map(coordSysDefine.coordSysDims, function(dim) { + var dimInfo = { + name: dim + }; + var axisModel = coordSysDefine.axisMap.get(dim); + if (axisModel) { + var axisType = axisModel.get('type'); + dimInfo.type = getDimensionTypeByAxis(axisType); + // dimInfo.stackable = isStackable(axisType); + } + return dimInfo; + }); + } + + if (!coordSysDimDefs) { + // Get dimensions from registered coordinate system + coordSysDimDefs = (registeredCoordSys && ( + registeredCoordSys.getDimensionsInfo ? + registeredCoordSys.getDimensionsInfo() : + registeredCoordSys.dimensions.slice() + )) || ['x', 'y']; + } + + var dimInfoList = createDimensions(source, { + coordDimensions: coordSysDimDefs, + generateCoord: opt.generateCoord + }); + + var firstCategoryDimIndex; + var hasNameEncode; + coordSysDefine && each$1(dimInfoList, function(dimInfo, dimIndex) { + var coordDim = dimInfo.coordDim; + var categoryAxisModel = coordSysDefine.categoryAxisMap.get(coordDim); + if (categoryAxisModel) { + if (firstCategoryDimIndex == null) { + firstCategoryDimIndex = dimIndex; + } + dimInfo.ordinalMeta = categoryAxisModel.getOrdinalMeta(); + } + if (dimInfo.otherDims.itemName != null) { + hasNameEncode = true; + } + }); + if (!hasNameEncode && firstCategoryDimIndex != null) { + dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0; + } + + var stackCalculationInfo = enableDataStack(seriesModel, dimInfoList); + + var list = new List(dimInfoList, seriesModel); + + list.setCalculationInfo(stackCalculationInfo); + + var dimValueGetter = (firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source)) ? + function(itemOpt, dimName, dataIndex, dimIndex) { + // Use dataIndex as ordinal value in categoryAxis + return dimIndex === firstCategoryDimIndex ? + dataIndex : + this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex); + } : + null; + + list.hasItemOption = false; + list.initData(source, null, dimValueGetter); + + return list; + } + + function isNeedCompleteOrdinalData(source) { + if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) { + var sampleItem = firstDataNotNull(source.data || []); + return sampleItem != null && + !isArray(getDataItemValue(sampleItem)); + } + } + + function firstDataNotNull(data) { + var i = 0; + while (i < data.length && data[i] == null) { + i++; + } + return data[i]; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * // Scale class management + * @module echarts/scale/Scale + */ + + /** + * @param {Object} [setting] + */ + function Scale(setting) { + this._setting = setting || {}; + + /** + * Extent + * @type {Array.} + * @protected + */ + this._extent = [Infinity, -Infinity]; + + /** + * Step is calculated in adjustExtent + * @type {Array.} + * @protected + */ + this._interval = 0; + + this.init && this.init.apply(this, arguments); + } + + /** + * Parse input val to valid inner number. + * @param {*} val + * @return {number} + */ + Scale.prototype.parse = function(val) { + // Notice: This would be a trap here, If the implementation + // of this method depends on extent, and this method is used + // before extent set (like in dataZoom), it would be wrong. + // Nevertheless, parse does not depend on extent generally. + return val; + }; + + Scale.prototype.getSetting = function(name) { + return this._setting[name]; + }; + + Scale.prototype.contain = function(val) { + var extent = this._extent; + return val >= extent[0] && val <= extent[1]; + }; + + /** + * Normalize value to linear [0, 1], return 0.5 if extent span is 0 + * @param {number} val + * @return {number} + */ + Scale.prototype.normalize = function(val) { + var extent = this._extent; + if (extent[1] === extent[0]) { + return 0.5; + } + return (val - extent[0]) / (extent[1] - extent[0]); + }; + + /** + * Scale normalized value + * @param {number} val + * @return {number} + */ + Scale.prototype.scale = function(val) { + var extent = this._extent; + return val * (extent[1] - extent[0]) + extent[0]; + }; + + /** + * Set extent from data + * @param {Array.} other + */ + Scale.prototype.unionExtent = function(other) { + var extent = this._extent; + other[0] < extent[0] && (extent[0] = other[0]); + other[1] > extent[1] && (extent[1] = other[1]); + // not setExtent because in log axis it may transformed to power + // this.setExtent(extent[0], extent[1]); + }; + + /** + * Set extent from data + * @param {module:echarts/data/List} data + * @param {string} dim + */ + Scale.prototype.unionExtentFromData = function(data, dim) { + this.unionExtent(data.getApproximateExtent(dim)); + }; + + /** + * Get extent + * @return {Array.} + */ + Scale.prototype.getExtent = function() { + return this._extent.slice(); + }; + + /** + * Set extent + * @param {number} start + * @param {number} end + */ + Scale.prototype.setExtent = function(start, end) { + var thisExtent = this._extent; + if (!isNaN(start)) { + thisExtent[0] = start; + } + if (!isNaN(end)) { + thisExtent[1] = end; + } + }; + + /** + * When axis extent depends on data and no data exists, + * axis ticks should not be drawn, which is named 'blank'. + */ + Scale.prototype.isBlank = function() { + return this._isBlank; + }, + + /** + * When axis extent depends on data and no data exists, + * axis ticks should not be drawn, which is named 'blank'. + */ + Scale.prototype.setBlank = function(isBlank) { + this._isBlank = isBlank; + }; + + /** + * @abstract + * @param {*} tick + * @return {string} label of the tick. + */ + Scale.prototype.getLabel = null; + + + enableClassExtend(Scale); + enableClassManagement(Scale, { + registerWhenExtend: true + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @constructor + * @param {Object} [opt] + * @param {Object} [opt.categories=[]] + * @param {Object} [opt.needCollect=false] + * @param {Object} [opt.deduplication=false] + */ + function OrdinalMeta(opt) { + + /** + * @readOnly + * @type {Array.} + */ + this.categories = opt.categories || []; + + /** + * @private + * @type {boolean} + */ + this._needCollect = opt.needCollect; + + /** + * @private + * @type {boolean} + */ + this._deduplication = opt.deduplication; + + /** + * @private + * @type {boolean} + */ + this._map; + } + + /** + * @param {module:echarts/model/Model} axisModel + * @return {module:echarts/data/OrdinalMeta} + */ + OrdinalMeta.createByAxisModel = function(axisModel) { + var option = axisModel.option; + var data = option.data; + var categories = data && map(data, getName); + + return new OrdinalMeta({ + categories: categories, + needCollect: !categories, + // deduplication is default in axis. + deduplication: option.dedplication !== false + }); + }; + + var proto$1 = OrdinalMeta.prototype; + + /** + * @param {string} category + * @return {number} ordinal + */ + proto$1.getOrdinal = function(category) { + return getOrCreateMap(this).get(category); + }; + + /** + * @param {*} category + * @return {number} The ordinal. If not found, return NaN. + */ + proto$1.parseAndCollect = function(category) { + var index; + var needCollect = this._needCollect; + + // The value of category dim can be the index of the given category set. + // This feature is only supported when !needCollect, because we should + // consider a common case: a value is 2017, which is a number but is + // expected to be tread as a category. This case usually happen in dataset, + // where it happent to be no need of the index feature. + if (typeof category !== 'string' && !needCollect) { + return category; + } + + // Optimize for the scenario: + // category is ['2012-01-01', '2012-01-02', ...], where the input + // data has been ensured not duplicate and is large data. + // Notice, if a dataset dimension provide categroies, usually echarts + // should remove duplication except user tell echarts dont do that + // (set axis.deduplication = false), because echarts do not know whether + // the values in the category dimension has duplication (consider the + // parallel-aqi example) + if (needCollect && !this._deduplication) { + index = this.categories.length; + this.categories[index] = category; + return index; + } + + var map$$1 = getOrCreateMap(this); + index = map$$1.get(category); + + if (index == null) { + if (needCollect) { + index = this.categories.length; + this.categories[index] = category; + map$$1.set(category, index); + } else { + index = NaN; + } + } + + return index; + }; + + // Consider big data, do not create map until needed. + function getOrCreateMap(ordinalMeta) { + return ordinalMeta._map || ( + ordinalMeta._map = createHashMap(ordinalMeta.categories) + ); + } + + function getName(obj) { + if (isObject$1(obj) && obj.value != null) { + return obj.value; + } else { + return obj + ''; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Linear continuous scale + * @module echarts/coord/scale/Ordinal + * + * http://en.wikipedia.org/wiki/Level_of_measurement + */ + + // FIXME only one data + + var scaleProto = Scale.prototype; + + var OrdinalScale = Scale.extend({ + + type: 'ordinal', + + /** + * @param {module:echarts/data/OrdianlMeta|Array.} ordinalMeta + */ + init: function(ordinalMeta, extent) { + // Caution: Should not use instanceof, consider ec-extensions using + // import approach to get OrdinalMeta class. + if (!ordinalMeta || isArray(ordinalMeta)) { + ordinalMeta = new OrdinalMeta({ + categories: ordinalMeta + }); + } + this._ordinalMeta = ordinalMeta; + this._extent = extent || [0, ordinalMeta.categories.length - 1]; + }, + + parse: function(val) { + return typeof val === 'string' ? + this._ordinalMeta.getOrdinal(val) + // val might be float. + : + Math.round(val); + }, + + contain: function(rank) { + rank = this.parse(rank); + return scaleProto.contain.call(this, rank) && + this._ordinalMeta.categories[rank] != null; + }, + + /** + * Normalize given rank or name to linear [0, 1] + * @param {number|string} [val] + * @return {number} + */ + normalize: function(val) { + return scaleProto.normalize.call(this, this.parse(val)); + }, + + scale: function(val) { + return Math.round(scaleProto.scale.call(this, val)); + }, + + /** + * @return {Array} + */ + getTicks: function() { + var ticks = []; + var extent = this._extent; + var rank = extent[0]; + + while (rank <= extent[1]) { + ticks.push(rank); + rank++; + } + + return ticks; + }, + + /** + * Get item on rank n + * @param {number} n + * @return {string} + */ + getLabel: function(n) { + if (!this.isBlank()) { + // Note that if no data, ordinalMeta.categories is an empty array. + return this._ordinalMeta.categories[n]; + } + }, + + /** + * @return {number} + */ + count: function() { + return this._extent[1] - this._extent[0] + 1; + }, + + /** + * @override + */ + unionExtentFromData: function(data, dim) { + this.unionExtent(data.getApproximateExtent(dim)); + }, + + getOrdinalMeta: function() { + return this._ordinalMeta; + }, + + niceTicks: noop, + niceExtent: noop + }); + + /** + * @return {module:echarts/scale/Time} + */ + OrdinalScale.create = function() { + return new OrdinalScale(); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * For testable. + */ + + var roundNumber$1 = round$1; + + /** + * @param {Array.} extent Both extent[0] and extent[1] should be valid number. + * Should be extent[0] < extent[1]. + * @param {number} splitNumber splitNumber should be >= 1. + * @param {number} [minInterval] + * @param {number} [maxInterval] + * @return {Object} {interval, intervalPrecision, niceTickExtent} + */ + function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) { + var result = {}; + var span = extent[1] - extent[0]; + + var interval = result.interval = nice(span / splitNumber, true); + if (minInterval != null && interval < minInterval) { + interval = result.interval = minInterval; + } + if (maxInterval != null && interval > maxInterval) { + interval = result.interval = maxInterval; + } + // Tow more digital for tick. + var precision = result.intervalPrecision = getIntervalPrecision(interval); + // Niced extent inside original extent + var niceTickExtent = result.niceTickExtent = [ + roundNumber$1(Math.ceil(extent[0] / interval) * interval, precision), + roundNumber$1(Math.floor(extent[1] / interval) * interval, precision) + ]; + + fixExtent(niceTickExtent, extent); + + return result; + } + + /** + * @param {number} interval + * @return {number} interval precision + */ + function getIntervalPrecision(interval) { + // Tow more digital for tick. + return getPrecisionSafe(interval) + 2; + } + + function clamp(niceTickExtent, idx, extent) { + niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]); + } + + // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent. + function fixExtent(niceTickExtent, extent) { + !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]); + !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]); + clamp(niceTickExtent, 0, extent); + clamp(niceTickExtent, 1, extent); + if (niceTickExtent[0] > niceTickExtent[1]) { + niceTickExtent[0] = niceTickExtent[1]; + } + } + + function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecision) { + var ticks = []; + + // If interval is 0, return []; + if (!interval) { + return ticks; + } + + // Consider this case: using dataZoom toolbox, zoom and zoom. + var safeLimit = 10000; + + if (extent[0] < niceTickExtent[0]) { + ticks.push(extent[0]); + } + var tick = niceTickExtent[0]; + + while (tick <= niceTickExtent[1]) { + ticks.push(tick); + // Avoid rounding error + tick = roundNumber$1(tick + interval, intervalPrecision); + if (tick === ticks[ticks.length - 1]) { + // Consider out of safe float point, e.g., + // -3711126.9907707 + 2e-10 === -3711126.9907707 + break; + } + if (ticks.length > safeLimit) { + return []; + } + } + // Consider this case: the last item of ticks is smaller + // than niceTickExtent[1] and niceTickExtent[1] === extent[1]. + if (extent[1] > (ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1])) { + ticks.push(extent[1]); + } + + return ticks; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Interval scale + * @module echarts/scale/Interval + */ + + + var roundNumber = round$1; + + /** + * @alias module:echarts/coord/scale/Interval + * @constructor + */ + var IntervalScale = Scale.extend({ + + type: 'interval', + + _interval: 0, + + _intervalPrecision: 2, + + setExtent: function(start, end) { + var thisExtent = this._extent; + //start,end may be a Number like '25',so... + if (!isNaN(start)) { + thisExtent[0] = parseFloat(start); + } + if (!isNaN(end)) { + thisExtent[1] = parseFloat(end); + } + }, + + unionExtent: function(other) { + var extent = this._extent; + other[0] < extent[0] && (extent[0] = other[0]); + other[1] > extent[1] && (extent[1] = other[1]); + + // unionExtent may called by it's sub classes + IntervalScale.prototype.setExtent.call(this, extent[0], extent[1]); + }, + /** + * Get interval + */ + getInterval: function() { + return this._interval; + }, + + /** + * Set interval + */ + setInterval: function(interval) { + this._interval = interval; + // Dropped auto calculated niceExtent and use user setted extent + // We assume user wan't to set both interval, min, max to get a better result + this._niceExtent = this._extent.slice(); + + this._intervalPrecision = getIntervalPrecision(interval); + }, + + /** + * @return {Array.} + */ + getTicks: function() { + return intervalScaleGetTicks( + this._interval, this._extent, this._niceExtent, this._intervalPrecision + ); + }, + + /** + * @param {number} data + * @param {Object} [opt] + * @param {number|string} [opt.precision] If 'auto', use nice presision. + * @param {boolean} [opt.pad] returns 1.50 but not 1.5 if precision is 2. + * @return {string} + */ + getLabel: function(data, opt) { + if (data == null) { + return ''; + } + + var precision = opt && opt.precision; + + if (precision == null) { + precision = getPrecisionSafe(data) || 0; + } else if (precision === 'auto') { + // Should be more precise then tick. + precision = this._intervalPrecision; + } + + // (1) If `precision` is set, 12.005 should be display as '12.00500'. + // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'. + data = roundNumber(data, precision, true); + + return addCommas(data); + }, + + /** + * Update interval and extent of intervals for nice ticks + * + * @param {number} [splitNumber = 5] Desired number of ticks + * @param {number} [minInterval] + * @param {number} [maxInterval] + */ + niceTicks: function(splitNumber, minInterval, maxInterval) { + splitNumber = splitNumber || 5; + var extent = this._extent; + var span = extent[1] - extent[0]; + if (!isFinite(span)) { + return; + } + // User may set axis min 0 and data are all negative + // FIXME If it needs to reverse ? + if (span < 0) { + span = -span; + extent.reverse(); + } + + var result = intervalScaleNiceTicks( + extent, splitNumber, minInterval, maxInterval + ); + + this._intervalPrecision = result.intervalPrecision; + this._interval = result.interval; + this._niceExtent = result.niceTickExtent; + }, + + /** + * Nice extent. + * @param {Object} opt + * @param {number} [opt.splitNumber = 5] Given approx tick number + * @param {boolean} [opt.fixMin=false] + * @param {boolean} [opt.fixMax=false] + * @param {boolean} [opt.minInterval] + * @param {boolean} [opt.maxInterval] + */ + niceExtent: function(opt) { + var extent = this._extent; + // If extent start and end are same, expand them + if (extent[0] === extent[1]) { + if (extent[0] !== 0) { + // Expand extent + var expandSize = extent[0]; + // In the fowllowing case + // Axis has been fixed max 100 + // Plus data are all 100 and axis extent are [100, 100]. + // Extend to the both side will cause expanded max is larger than fixed max. + // So only expand to the smaller side. + if (!opt.fixMax) { + extent[1] += expandSize / 2; + extent[0] -= expandSize / 2; + } else { + extent[0] -= expandSize / 2; + } + } else { + extent[1] = 1; + } + } + var span = extent[1] - extent[0]; + // If there are no data and extent are [Infinity, -Infinity] + if (!isFinite(span)) { + extent[0] = 0; + extent[1] = 1; + } + + this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); + + // var extent = this._extent; + var interval = this._interval; + + if (!opt.fixMin) { + extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval); + } + if (!opt.fixMax) { + extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval); + } + } + }); + + /** + * @return {module:echarts/scale/Time} + */ + IntervalScale.create = function() { + return new IntervalScale(); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var STACK_PREFIX = '__ec_stack_'; + var LARGE_BAR_MIN_WIDTH = 0.5; + + var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array; + + function getSeriesStackId(seriesModel) { + return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex; + } + + function getAxisKey(axis) { + return axis.dim + axis.index; + } + + /** + * @param {Object} opt + * @param {module:echarts/coord/Axis} opt.axis Only support category axis currently. + * @param {number} opt.count Positive interger. + * @param {number} [opt.barWidth] + * @param {number} [opt.barMaxWidth] + * @param {number} [opt.barGap] + * @param {number} [opt.barCategoryGap] + * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined. + */ + function getLayoutOnAxis(opt) { + var params = []; + var baseAxis = opt.axis; + var axisKey = 'axis0'; + + if (baseAxis.type !== 'category') { + return; + } + var bandWidth = baseAxis.getBandWidth(); + + for (var i = 0; i < opt.count || 0; i++) { + params.push(defaults({ + bandWidth: bandWidth, + axisKey: axisKey, + stackId: STACK_PREFIX + i + }, opt)); + } + var widthAndOffsets = doCalBarWidthAndOffset(params); + + var result = []; + for (var i = 0; i < opt.count; i++) { + var item = widthAndOffsets[axisKey][STACK_PREFIX + i]; + item.offsetCenter = item.offset + item.width / 2; + result.push(item); + } + + return result; + } + + function prepareLayoutBarSeries(seriesType, ecModel) { + var seriesModels = []; + ecModel.eachSeriesByType(seriesType, function(seriesModel) { + // Check series coordinate, do layout for cartesian2d only + if (isOnCartesian(seriesModel) && !isInLargeMode(seriesModel)) { + seriesModels.push(seriesModel); + } + }); + return seriesModels; + } + + function makeColumnLayout(barSeries) { + var seriesInfoList = []; + each$1(barSeries, function(seriesModel) { + var data = seriesModel.getData(); + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var axisExtent = baseAxis.getExtent(); + var bandWidth = baseAxis.type === 'category' ? + baseAxis.getBandWidth() : + (Math.abs(axisExtent[1] - axisExtent[0]) / data.count()); + + var barWidth = parsePercent$1( + seriesModel.get('barWidth'), bandWidth + ); + var barMaxWidth = parsePercent$1( + seriesModel.get('barMaxWidth'), bandWidth + ); + var barGap = seriesModel.get('barGap'); + var barCategoryGap = seriesModel.get('barCategoryGap'); + + seriesInfoList.push({ + bandWidth: bandWidth, + barWidth: barWidth, + barMaxWidth: barMaxWidth, + barGap: barGap, + barCategoryGap: barCategoryGap, + axisKey: getAxisKey(baseAxis), + stackId: getSeriesStackId(seriesModel) + }); + }); + + return doCalBarWidthAndOffset(seriesInfoList); + } + + function doCalBarWidthAndOffset(seriesInfoList) { + // Columns info on each category axis. Key is cartesian name + var columnsMap = {}; + + each$1(seriesInfoList, function(seriesInfo, idx) { + var axisKey = seriesInfo.axisKey; + var bandWidth = seriesInfo.bandWidth; + var columnsOnAxis = columnsMap[axisKey] || { + bandWidth: bandWidth, + remainedWidth: bandWidth, + autoWidthCount: 0, + categoryGap: '20%', + gap: '30%', + stacks: {} + }; + var stacks = columnsOnAxis.stacks; + columnsMap[axisKey] = columnsOnAxis; + + var stackId = seriesInfo.stackId; + + if (!stacks[stackId]) { + columnsOnAxis.autoWidthCount++; + } + stacks[stackId] = stacks[stackId] || { + width: 0, + maxWidth: 0 + }; + + // Caution: In a single coordinate system, these barGrid attributes + // will be shared by series. Consider that they have default values, + // only the attributes set on the last series will work. + // Do not change this fact unless there will be a break change. + + // TODO + var barWidth = seriesInfo.barWidth; + if (barWidth && !stacks[stackId].width) { + // See #6312, do not restrict width. + stacks[stackId].width = barWidth; + barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); + columnsOnAxis.remainedWidth -= barWidth; + } + + var barMaxWidth = seriesInfo.barMaxWidth; + barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); + var barGap = seriesInfo.barGap; + (barGap != null) && (columnsOnAxis.gap = barGap); + var barCategoryGap = seriesInfo.barCategoryGap; + (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap); + }); + + var result = {}; + + each$1(columnsMap, function(columnsOnAxis, coordSysName) { + + result[coordSysName] = {}; + + var stacks = columnsOnAxis.stacks; + var bandWidth = columnsOnAxis.bandWidth; + var categoryGap = parsePercent$1(columnsOnAxis.categoryGap, bandWidth); + var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1); + + var remainedWidth = columnsOnAxis.remainedWidth; + var autoWidthCount = columnsOnAxis.autoWidthCount; + var autoWidth = (remainedWidth - categoryGap) / + (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + + // Find if any auto calculated bar exceeded maxBarWidth + each$1(stacks, function(column, stack) { + var maxWidth = column.maxWidth; + if (maxWidth && maxWidth < autoWidth) { + maxWidth = Math.min(maxWidth, remainedWidth); + if (column.width) { + maxWidth = Math.min(maxWidth, column.width); + } + remainedWidth -= maxWidth; + column.width = maxWidth; + autoWidthCount--; + } + }); + + // Recalculate width again + autoWidth = (remainedWidth - categoryGap) / + (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + + var widthSum = 0; + var lastColumn; + each$1(stacks, function(column, idx) { + if (!column.width) { + column.width = autoWidth; + } + lastColumn = column; + widthSum += column.width * (1 + barGapPercent); + }); + if (lastColumn) { + widthSum -= lastColumn.width * barGapPercent; + } + + var offset = -widthSum / 2; + each$1(stacks, function(column, stackId) { + result[coordSysName][stackId] = result[coordSysName][stackId] || { + offset: offset, + width: column.width + }; + + offset += column.width * (1 + barGapPercent); + }); + }); + + return result; + } + + /** + * @param {Object} barWidthAndOffset The result of makeColumnLayout + * @param {module:echarts/coord/Axis} axis + * @param {module:echarts/model/Series} [seriesModel] If not provided, return all. + * @return {Object} {stackId: {offset, width}} or {offset, width} if seriesModel provided. + */ + function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) { + if (barWidthAndOffset && axis) { + var result = barWidthAndOffset[getAxisKey(axis)]; + if (result != null && seriesModel != null) { + result = result[getSeriesStackId(seriesModel)]; + } + return result; + } + } + + /** + * @param {string} seriesType + * @param {module:echarts/model/Global} ecModel + */ + function layout(seriesType, ecModel) { + + var seriesModels = prepareLayoutBarSeries(seriesType, ecModel); + var barWidthAndOffset = makeColumnLayout(seriesModels); + + var lastStackCoords = {}; + each$1(seriesModels, function(seriesModel) { + + var data = seriesModel.getData(); + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + + var stackId = getSeriesStackId(seriesModel); + var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId]; + var columnOffset = columnLayoutInfo.offset; + var columnWidth = columnLayoutInfo.width; + var valueAxis = cartesian.getOtherAxis(baseAxis); + + var barMinHeight = seriesModel.get('barMinHeight') || 0; + + lastStackCoords[stackId] = lastStackCoords[stackId] || []; + data.setLayout({ + offset: columnOffset, + size: columnWidth + }); + + var valueDim = data.mapDimension(valueAxis.dim); + var baseDim = data.mapDimension(baseAxis.dim); + var stacked = isDimensionStacked(data, valueDim /*, baseDim*/ ); + var isValueAxisH = valueAxis.isHorizontal(); + + var valueAxisStart = getValueAxisStart(baseAxis, valueAxis, stacked); + + for (var idx = 0, len = data.count(); idx < len; idx++) { + var value = data.get(valueDim, idx); + var baseValue = data.get(baseDim, idx); + + if (isNaN(value)) { + continue; + } + + var sign = value >= 0 ? 'p' : 'n'; + var baseCoord = valueAxisStart; + + // Because of the barMinHeight, we can not use the value in + // stackResultDimension directly. + if (stacked) { + // Only ordinal axis can be stacked. + if (!lastStackCoords[stackId][baseValue]) { + lastStackCoords[stackId][baseValue] = { + p: valueAxisStart, // Positive stack + n: valueAxisStart // Negative stack + }; + } + // Should also consider #4243 + baseCoord = lastStackCoords[stackId][baseValue][sign]; + } + + var x; + var y; + var width; + var height; + + if (isValueAxisH) { + var coord = cartesian.dataToPoint([value, baseValue]); + x = baseCoord; + y = coord[1] + columnOffset; + width = coord[0] - valueAxisStart; + height = columnWidth; + + if (Math.abs(width) < barMinHeight) { + width = (width < 0 ? -1 : 1) * barMinHeight; + } + stacked && (lastStackCoords[stackId][baseValue][sign] += width); + } else { + var coord = cartesian.dataToPoint([baseValue, value]); + x = coord[0] + columnOffset; + y = baseCoord; + width = columnWidth; + height = coord[1] - valueAxisStart; + + if (Math.abs(height) < barMinHeight) { + // Include zero to has a positive bar + height = (height <= 0 ? -1 : 1) * barMinHeight; + } + stacked && (lastStackCoords[stackId][baseValue][sign] += height); + } + + data.setItemLayout(idx, { + x: x, + y: y, + width: width, + height: height + }); + } + + }, this); + } + + // TODO: Do not support stack in large mode yet. + var largeLayout = { + + seriesType: 'bar', + + plan: createRenderPlanner(), + + reset: function(seriesModel) { + if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) { + return; + } + + var data = seriesModel.getData(); + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var valueAxis = cartesian.getOtherAxis(baseAxis); + var valueDim = data.mapDimension(valueAxis.dim); + var baseDim = data.mapDimension(baseAxis.dim); + var valueAxisHorizontal = valueAxis.isHorizontal(); + var valueDimIdx = valueAxisHorizontal ? 0 : 1; + + var barWidth = retrieveColumnLayout( + makeColumnLayout([seriesModel]), baseAxis, seriesModel + ).width; + if (!(barWidth > LARGE_BAR_MIN_WIDTH)) { // jshint ignore:line + barWidth = LARGE_BAR_MIN_WIDTH; + } + + return { + progress: progress + }; + + function progress(params, data) { + var largePoints = new LargeArr(params.count * 2); + var dataIndex; + var coord = []; + var valuePair = []; + var offset = 0; + + while ((dataIndex = params.next()) != null) { + valuePair[valueDimIdx] = data.get(valueDim, dataIndex); + valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex); + + coord = cartesian.dataToPoint(valuePair, null, coord); + largePoints[offset++] = coord[0]; + largePoints[offset++] = coord[1]; + } + + data.setLayout({ + largePoints: largePoints, + barWidth: barWidth, + valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false), + valueAxisHorizontal: valueAxisHorizontal + }); + } + } + }; + + function isOnCartesian(seriesModel) { + return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d'; + } + + function isInLargeMode(seriesModel) { + return seriesModel.pipelineContext && seriesModel.pipelineContext.large; + } + + function getValueAxisStart(baseAxis, valueAxis, stacked) { + return ( + indexOf(baseAxis.getAxesOnZeroOf(), valueAxis) >= 0 || + stacked + ) ? + valueAxis.toGlobalCoord(valueAxis.dataToCoord(0)) : + valueAxis.getGlobalExtent()[0]; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * The `scaleLevels` references to d3.js. The use of the source + * code of this file is also subject to the terms and consitions + * of its license (BSD-3Clause, see ). + */ + + // [About UTC and local time zone]: + // In most cases, `number.parseDate` will treat input data string as local time + // (except time zone is specified in time string). And `format.formateTime` returns + // local time by default. option.useUTC is false by default. This design have + // concidered these common case: + // (1) Time that is persistent in server is in UTC, but it is needed to be diplayed + // in local time by default. + // (2) By default, the input data string (e.g., '2011-01-02') should be displayed + // as its original time, without any time difference. + + var intervalScaleProto = IntervalScale.prototype; + + var mathCeil = Math.ceil; + var mathFloor = Math.floor; + var ONE_SECOND = 1000; + var ONE_MINUTE = ONE_SECOND * 60; + var ONE_HOUR = ONE_MINUTE * 60; + var ONE_DAY = ONE_HOUR * 24; + + // FIXME 公用? + var bisect = function(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid][1] < x) { + lo = mid + 1; + } else { + hi = mid; + } + } + return lo; + }; + + /** + * @alias module:echarts/coord/scale/Time + * @constructor + */ + var TimeScale = IntervalScale.extend({ + type: 'time', + + /** + * @override + */ + getLabel: function(val) { + var stepLvl = this._stepLvl; + + var date = new Date(val); + + return formatTime(stepLvl[0], date, this.getSetting('useUTC')); + }, + + /** + * @override + */ + niceExtent: function(opt) { + var extent = this._extent; + // If extent start and end are same, expand them + if (extent[0] === extent[1]) { + // Expand extent + extent[0] -= ONE_DAY; + extent[1] += ONE_DAY; + } + // If there are no data and extent are [Infinity, -Infinity] + if (extent[1] === -Infinity && extent[0] === Infinity) { + var d = new Date(); + extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate()); + extent[0] = extent[1] - ONE_DAY; + } + + this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); + + // var extent = this._extent; + var interval = this._interval; + + if (!opt.fixMin) { + extent[0] = round$1(mathFloor(extent[0] / interval) * interval); + } + if (!opt.fixMax) { + extent[1] = round$1(mathCeil(extent[1] / interval) * interval); + } + }, + + /** + * @override + */ + niceTicks: function(approxTickNum, minInterval, maxInterval) { + approxTickNum = approxTickNum || 10; + + var extent = this._extent; + var span = extent[1] - extent[0]; + var approxInterval = span / approxTickNum; + + if (minInterval != null && approxInterval < minInterval) { + approxInterval = minInterval; + } + if (maxInterval != null && approxInterval > maxInterval) { + approxInterval = maxInterval; + } + + var scaleLevelsLen = scaleLevels.length; + var idx = bisect(scaleLevels, approxInterval, 0, scaleLevelsLen); + + var level = scaleLevels[Math.min(idx, scaleLevelsLen - 1)]; + var interval = level[1]; + // Same with interval scale if span is much larger than 1 year + if (level[0] === 'year') { + var yearSpan = span / interval; + + // From "Nice Numbers for Graph Labels" of Graphic Gems + // var niceYearSpan = numberUtil.nice(yearSpan, false); + var yearStep = nice(yearSpan / approxTickNum, true); + + interval *= yearStep; + } + + var timezoneOffset = this.getSetting('useUTC') ? + 0 : (new Date(+extent[0] || +extent[1])).getTimezoneOffset() * 60 * 1000; + var niceExtent = [ + Math.round(mathCeil((extent[0] - timezoneOffset) / interval) * interval + timezoneOffset), + Math.round(mathFloor((extent[1] - timezoneOffset) / interval) * interval + timezoneOffset) + ]; + + fixExtent(niceExtent, extent); + + this._stepLvl = level; + // Interval will be used in getTicks + this._interval = interval; + this._niceExtent = niceExtent; + }, + + parse: function(val) { + // val might be float. + return +parseDate(val); + } + }); + + each$1(['contain', 'normalize'], function(methodName) { + TimeScale.prototype[methodName] = function(val) { + return intervalScaleProto[methodName].call(this, this.parse(val)); + }; + }); + + // Steps from d3, see the license statement at the top of this file. + var scaleLevels = [ + // Format interval + ['hh:mm:ss', ONE_SECOND], // 1s + ['hh:mm:ss', ONE_SECOND * 5], // 5s + ['hh:mm:ss', ONE_SECOND * 10], // 10s + ['hh:mm:ss', ONE_SECOND * 15], // 15s + ['hh:mm:ss', ONE_SECOND * 30], // 30s + ['hh:mm\nMM-dd', ONE_MINUTE], // 1m + ['hh:mm\nMM-dd', ONE_MINUTE * 5], // 5m + ['hh:mm\nMM-dd', ONE_MINUTE * 10], // 10m + ['hh:mm\nMM-dd', ONE_MINUTE * 15], // 15m + ['hh:mm\nMM-dd', ONE_MINUTE * 30], // 30m + ['hh:mm\nMM-dd', ONE_HOUR], // 1h + ['hh:mm\nMM-dd', ONE_HOUR * 2], // 2h + ['hh:mm\nMM-dd', ONE_HOUR * 6], // 6h + ['hh:mm\nMM-dd', ONE_HOUR * 12], // 12h + ['MM-dd\nyyyy', ONE_DAY], // 1d + ['MM-dd\nyyyy', ONE_DAY * 2], // 2d + ['MM-dd\nyyyy', ONE_DAY * 3], // 3d + ['MM-dd\nyyyy', ONE_DAY * 4], // 4d + ['MM-dd\nyyyy', ONE_DAY * 5], // 5d + ['MM-dd\nyyyy', ONE_DAY * 6], // 6d + ['week', ONE_DAY * 7], // 7d + ['MM-dd\nyyyy', ONE_DAY * 10], // 10d + ['week', ONE_DAY * 14], // 2w + ['week', ONE_DAY * 21], // 3w + ['month', ONE_DAY * 31], // 1M + ['week', ONE_DAY * 42], // 6w + ['month', ONE_DAY * 62], // 2M + ['week', ONE_DAY * 42], // 10w + ['quarter', ONE_DAY * 380 / 4], // 3M + ['month', ONE_DAY * 31 * 4], // 4M + ['month', ONE_DAY * 31 * 5], // 5M + ['half-year', ONE_DAY * 380 / 2], // 6M + ['month', ONE_DAY * 31 * 8], // 8M + ['month', ONE_DAY * 31 * 10], // 10M + ['year', ONE_DAY * 380] // 1Y + ]; + + /** + * @param {module:echarts/model/Model} + * @return {module:echarts/scale/Time} + */ + TimeScale.create = function(model) { + return new TimeScale({ + useUTC: model.ecModel.get('useUTC') + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Log scale + * @module echarts/scale/Log + */ + + // Use some method of IntervalScale + var scaleProto$1 = Scale.prototype; + var intervalScaleProto$1 = IntervalScale.prototype; + + var getPrecisionSafe$1 = getPrecisionSafe; + var roundingErrorFix = round$1; + + var mathFloor$1 = Math.floor; + var mathCeil$1 = Math.ceil; + var mathPow$1 = Math.pow; + + var mathLog = Math.log; + + var LogScale = Scale.extend({ + + type: 'log', + + base: 10, + + $constructor: function() { + Scale.apply(this, arguments); + this._originalScale = new IntervalScale(); + }, + + /** + * @return {Array.} + */ + getTicks: function() { + var originalScale = this._originalScale; + var extent = this._extent; + var originalExtent = originalScale.getExtent(); + + return map(intervalScaleProto$1.getTicks.call(this), function(val) { + var powVal = round$1(mathPow$1(this.base, val)); + + // Fix #4158 + powVal = (val === extent[0] && originalScale.__fixMin) ? + fixRoundingError(powVal, originalExtent[0]) : + powVal; + powVal = (val === extent[1] && originalScale.__fixMax) ? + fixRoundingError(powVal, originalExtent[1]) : + powVal; + + return powVal; + }, this); + }, + + /** + * @param {number} val + * @return {string} + */ + getLabel: intervalScaleProto$1.getLabel, + + /** + * @param {number} val + * @return {number} + */ + scale: function(val) { + val = scaleProto$1.scale.call(this, val); + return mathPow$1(this.base, val); + }, + + /** + * @param {number} start + * @param {number} end + */ + setExtent: function(start, end) { + var base = this.base; + start = mathLog(start) / mathLog(base); + end = mathLog(end) / mathLog(base); + intervalScaleProto$1.setExtent.call(this, start, end); + }, + + /** + * @return {number} end + */ + getExtent: function() { + var base = this.base; + var extent = scaleProto$1.getExtent.call(this); + extent[0] = mathPow$1(base, extent[0]); + extent[1] = mathPow$1(base, extent[1]); + + // Fix #4158 + var originalScale = this._originalScale; + var originalExtent = originalScale.getExtent(); + originalScale.__fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0])); + originalScale.__fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1])); + + return extent; + }, + + /** + * @param {Array.} extent + */ + unionExtent: function(extent) { + this._originalScale.unionExtent(extent); + + var base = this.base; + extent[0] = mathLog(extent[0]) / mathLog(base); + extent[1] = mathLog(extent[1]) / mathLog(base); + scaleProto$1.unionExtent.call(this, extent); + }, + + /** + * @override + */ + unionExtentFromData: function(data, dim) { + // TODO + // filter value that <= 0 + this.unionExtent(data.getApproximateExtent(dim)); + }, + + /** + * Update interval and extent of intervals for nice ticks + * @param {number} [approxTickNum = 10] Given approx tick number + */ + niceTicks: function(approxTickNum) { + approxTickNum = approxTickNum || 10; + var extent = this._extent; + var span = extent[1] - extent[0]; + if (span === Infinity || span <= 0) { + return; + } + + var interval = quantity(span); + var err = approxTickNum / span * interval; + + // Filter ticks to get closer to the desired count. + if (err <= 0.5) { + interval *= 10; + } + + // Interval should be integer + while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) { + interval *= 10; + } + + var niceExtent = [ + round$1(mathCeil$1(extent[0] / interval) * interval), + round$1(mathFloor$1(extent[1] / interval) * interval) + ]; + + this._interval = interval; + this._niceExtent = niceExtent; + }, + + /** + * Nice extent. + * @override + */ + niceExtent: function(opt) { + intervalScaleProto$1.niceExtent.call(this, opt); + + var originalScale = this._originalScale; + originalScale.__fixMin = opt.fixMin; + originalScale.__fixMax = opt.fixMax; + } + + }); + + each$1(['contain', 'normalize'], function(methodName) { + LogScale.prototype[methodName] = function(val) { + val = mathLog(val) / mathLog(this.base); + return scaleProto$1[methodName].call(this, val); + }; + }); + + LogScale.create = function() { + return new LogScale(); + }; + + function fixRoundingError(val, originalVal) { + return roundingErrorFix(val, getPrecisionSafe$1(originalVal)); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Get axis scale extent before niced. + * Item of returned array can only be number (including Infinity and NaN). + */ + function getScaleExtent(scale, model) { + var scaleType = scale.type; + + var min = model.getMin(); + var max = model.getMax(); + var fixMin = min != null; + var fixMax = max != null; + var originalExtent = scale.getExtent(); + + var axisDataLen; + var boundaryGap; + var span; + if (scaleType === 'ordinal') { + axisDataLen = model.getCategories().length; + } else { + boundaryGap = model.get('boundaryGap'); + if (!isArray(boundaryGap)) { + boundaryGap = [boundaryGap || 0, boundaryGap || 0]; + } + if (typeof boundaryGap[0] === 'boolean') { + if (__DEV__) { + console.warn('Boolean type for boundaryGap is only ' + + 'allowed for ordinal axis. Please use string in ' + + 'percentage instead, e.g., "20%". Currently, ' + + 'boundaryGap is set to be 0.'); + } + boundaryGap = [0, 0]; + } + boundaryGap[0] = parsePercent$1(boundaryGap[0], 1); + boundaryGap[1] = parsePercent$1(boundaryGap[1], 1); + span = (originalExtent[1] - originalExtent[0]) || + Math.abs(originalExtent[0]); + } + + // Notice: When min/max is not set (that is, when there are null/undefined, + // which is the most common case), these cases should be ensured: + // (1) For 'ordinal', show all axis.data. + // (2) For others: + // + `boundaryGap` is applied (if min/max set, boundaryGap is + // disabled). + // + If `needCrossZero`, min/max should be zero, otherwise, min/max should + // be the result that originalExtent enlarged by boundaryGap. + // (3) If no data, it should be ensured that `scale.setBlank` is set. + + // FIXME + // (1) When min/max is 'dataMin' or 'dataMax', should boundaryGap be able to used? + // (2) When `needCrossZero` and all data is positive/negative, should it be ensured + // that the results processed by boundaryGap are positive/negative? + + if (min == null) { + min = scaleType === 'ordinal' ? + (axisDataLen ? 0 : NaN) : + originalExtent[0] - boundaryGap[0] * span; + } + if (max == null) { + max = scaleType === 'ordinal' ? + (axisDataLen ? axisDataLen - 1 : NaN) : + originalExtent[1] + boundaryGap[1] * span; + } + + if (min === 'dataMin') { + min = originalExtent[0]; + } else if (typeof min === 'function') { + min = min({ + min: originalExtent[0], + max: originalExtent[1] + }); + } + + if (max === 'dataMax') { + max = originalExtent[1]; + } else if (typeof max === 'function') { + max = max({ + min: originalExtent[0], + max: originalExtent[1] + }); + } + + (min == null || !isFinite(min)) && (min = NaN); + (max == null || !isFinite(max)) && (max = NaN); + + scale.setBlank( + eqNaN(min) || + eqNaN(max) || + (scaleType === 'ordinal' && !scale.getOrdinalMeta().categories.length) + ); + + // Evaluate if axis needs cross zero + if (model.getNeedCrossZero()) { + // Axis is over zero and min is not set + if (min > 0 && max > 0 && !fixMin) { + min = 0; + } + // Axis is under zero and max is not set + if (min < 0 && max < 0 && !fixMax) { + max = 0; + } + } + + // If bars are placed on a base axis of type time or interval account for axis boundary overflow and current axis + // is base axis + // FIXME + // (1) Consider support value axis, where below zero and axis `onZero` should be handled properly. + // (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent? + // Should not depend on series type `bar`? + // (3) Fix that might overlap when using dataZoom. + // (4) Consider other chart types using `barGrid`? + // See #6728, #4862, `test/bar-overflow-time-plot.html` + var ecModel = model.ecModel; + if (ecModel && (scaleType === 'time' /*|| scaleType === 'interval' */ )) { + var barSeriesModels = prepareLayoutBarSeries('bar', ecModel); + var isBaseAxisAndHasBarSeries; + + each$1(barSeriesModels, function(seriesModel) { + isBaseAxisAndHasBarSeries |= seriesModel.getBaseAxis() === model.axis; + }); + + if (isBaseAxisAndHasBarSeries) { + // Calculate placement of bars on axis + var barWidthAndOffset = makeColumnLayout(barSeriesModels); + + // Adjust axis min and max to account for overflow + var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset); + min = adjustedScale.min; + max = adjustedScale.max; + } + } + + return [min, max]; + } + + function adjustScaleForOverflow(min, max, model, barWidthAndOffset) { + + // Get Axis Length + var axisExtent = model.axis.getExtent(); + var axisLength = axisExtent[1] - axisExtent[0]; + + // Get bars on current base axis and calculate min and max overflow + var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis); + if (barsOnCurrentAxis === undefined) { + return { + min: min, + max: max + }; + } + + var minOverflow = Infinity; + each$1(barsOnCurrentAxis, function(item) { + minOverflow = Math.min(item.offset, minOverflow); + }); + var maxOverflow = -Infinity; + each$1(barsOnCurrentAxis, function(item) { + maxOverflow = Math.max(item.offset + item.width, maxOverflow); + }); + minOverflow = Math.abs(minOverflow); + maxOverflow = Math.abs(maxOverflow); + var totalOverFlow = minOverflow + maxOverflow; + + // Calulate required buffer based on old range and overflow + var oldRange = max - min; + var oldRangePercentOfNew = (1 - (minOverflow + maxOverflow) / axisLength); + var overflowBuffer = ((oldRange / oldRangePercentOfNew) - oldRange); + + max += overflowBuffer * (maxOverflow / totalOverFlow); + min -= overflowBuffer * (minOverflow / totalOverFlow); + + return { + min: min, + max: max + }; + } + + function niceScaleExtent(scale, model) { + var extent = getScaleExtent(scale, model); + var fixMin = model.getMin() != null; + var fixMax = model.getMax() != null; + var splitNumber = model.get('splitNumber'); + + if (scale.type === 'log') { + scale.base = model.get('logBase'); + } + + var scaleType = scale.type; + scale.setExtent(extent[0], extent[1]); + scale.niceExtent({ + splitNumber: splitNumber, + fixMin: fixMin, + fixMax: fixMax, + minInterval: (scaleType === 'interval' || scaleType === 'time') ? + model.get('minInterval') : null, + maxInterval: (scaleType === 'interval' || scaleType === 'time') ? + model.get('maxInterval') : null + }); + + // If some one specified the min, max. And the default calculated interval + // is not good enough. He can specify the interval. It is often appeared + // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard + // to be 60. + // FIXME + var interval = model.get('interval'); + if (interval != null) { + scale.setInterval && scale.setInterval(interval); + } + } + + /** + * @param {module:echarts/model/Model} model + * @param {string} [axisType] Default retrieve from model.type + * @return {module:echarts/scale/*} + */ + function createScaleByModel(model, axisType) { + axisType = axisType || model.get('type'); + if (axisType) { + switch (axisType) { + // Buildin scale + case 'category': + return new OrdinalScale( + model.getOrdinalMeta ? + model.getOrdinalMeta() : + model.getCategories(), + [Infinity, -Infinity] + ); + case 'value': + return new IntervalScale(); + // Extended scale, like time and log + default: + return (Scale.getClass(axisType) || IntervalScale).create(model); + } + } + } + + /** + * Check if the axis corss 0 + */ + function ifAxisCrossZero(axis) { + var dataExtent = axis.scale.getExtent(); + var min = dataExtent[0]; + var max = dataExtent[1]; + return !((min > 0 && max > 0) || (min < 0 && max < 0)); + } + + /** + * @param {module:echarts/coord/Axis} axis + * @return {Function} Label formatter function. + * param: {number} tickValue, + * param: {number} idx, the index in all ticks. + * If category axis, this param is not requied. + * return: {string} label string. + */ + function makeLabelFormatter(axis) { + var labelFormatter = axis.getLabelModel().get('formatter'); + var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null; + + if (typeof labelFormatter === 'string') { + labelFormatter = (function(tpl) { + return function(val) { + return tpl.replace('{value}', val != null ? val : ''); + }; + })(labelFormatter); + // Consider empty array + return labelFormatter; + } else if (typeof labelFormatter === 'function') { + return function(tickValue, idx) { + // The original intention of `idx` is "the index of the tick in all ticks". + // But the previous implementation of category axis do not consider the + // `axisLabel.interval`, which cause that, for example, the `interval` is + // `1`, then the ticks "name5", "name7", "name9" are displayed, where the + // corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep + // the definition here for back compatibility. + if (categoryTickStart != null) { + idx = tickValue - categoryTickStart; + } + return labelFormatter(getAxisRawValue(axis, tickValue), idx); + }; + } else { + return function(tick) { + return axis.scale.getLabel(tick); + }; + } + } + + function getAxisRawValue(axis, value) { + // In category axis with data zoom, tick is not the original + // index of axis.data. So tick should not be exposed to user + // in category axis. + return axis.type === 'category' ? axis.scale.getLabel(value) : value; + } + + /** + * @param {module:echarts/coord/Axis} axis + * @return {module:zrender/core/BoundingRect} Be null/undefined if no labels. + */ + function estimateLabelUnionRect(axis) { + var axisModel = axis.model; + var scale = axis.scale; + + if (!axisModel.get('axisLabel.show') || scale.isBlank()) { + return; + } + + var isCategory = axis.type === 'category'; + + var realNumberScaleTicks; + var tickCount; + var categoryScaleExtent = scale.getExtent(); + + // Optimize for large category data, avoid call `getTicks()`. + if (isCategory) { + tickCount = scale.count(); + } else { + realNumberScaleTicks = scale.getTicks(); + tickCount = realNumberScaleTicks.length; + } + + var axisLabelModel = axis.getLabelModel(); + var labelFormatter = makeLabelFormatter(axis); + + var rect; + var step = 1; + // Simple optimization for large amount of labels + if (tickCount > 40) { + step = Math.ceil(tickCount / 40); + } + for (var i = 0; i < tickCount; i += step) { + var tickValue = realNumberScaleTicks ? realNumberScaleTicks[i] : categoryScaleExtent[0] + i; + var label = labelFormatter(tickValue); + var unrotatedSingleRect = axisLabelModel.getTextRect(label); + var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0); + + rect ? rect.union(singleRect) : (rect = singleRect); + } + + return rect; + } + + function rotateTextRect(textRect, rotate) { + var rotateRadians = rotate * Math.PI / 180; + var boundingBox = textRect.plain(); + var beforeWidth = boundingBox.width; + var beforeHeight = boundingBox.height; + var afterWidth = beforeWidth * Math.cos(rotateRadians) + beforeHeight * Math.sin(rotateRadians); + var afterHeight = beforeWidth * Math.sin(rotateRadians) + beforeHeight * Math.cos(rotateRadians); + var rotatedRect = new BoundingRect(boundingBox.x, boundingBox.y, afterWidth, afterHeight); + + return rotatedRect; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var axisModelCommonMixin = { + + /** + * @param {boolean} origin + * @return {number|string} min value or 'dataMin' or null/undefined (means auto) or NaN + */ + getMin: function(origin) { + var option = this.option; + var min = (!origin && option.rangeStart != null) ? + option.rangeStart : option.min; + + if (this.axis && + min != null && + min !== 'dataMin' && + typeof min !== 'function' && + !eqNaN(min) + ) { + min = this.axis.scale.parse(min); + } + return min; + }, + + /** + * @param {boolean} origin + * @return {number|string} max value or 'dataMax' or null/undefined (means auto) or NaN + */ + getMax: function(origin) { + var option = this.option; + var max = (!origin && option.rangeEnd != null) ? + option.rangeEnd : option.max; + + if (this.axis && + max != null && + max !== 'dataMax' && + typeof max !== 'function' && + !eqNaN(max) + ) { + max = this.axis.scale.parse(max); + } + return max; + }, + + /** + * @return {boolean} + */ + getNeedCrossZero: function() { + var option = this.option; + return (option.rangeStart != null || option.rangeEnd != null) ? + false : !option.scale; + }, + + /** + * Should be implemented by each axis model if necessary. + * @return {module:echarts/model/Component} coordinate system model + */ + getCoordSysModel: noop, + + /** + * @param {number} rangeStart Can only be finite number or null/undefined or NaN. + * @param {number} rangeEnd Can only be finite number or null/undefined or NaN. + */ + setRange: function(rangeStart, rangeEnd) { + this.option.rangeStart = rangeStart; + this.option.rangeEnd = rangeEnd; + }, + + /** + * Reset range + */ + resetRange: function() { + // rangeStart and rangeEnd is readonly. + this.option.rangeStart = this.option.rangeEnd = null; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Symbol factory + + /** + * Triangle shape + * @inner + */ + var Triangle = extendShape({ + type: 'triangle', + shape: { + cx: 0, + cy: 0, + width: 0, + height: 0 + }, + buildPath: function(path, shape) { + var cx = shape.cx; + var cy = shape.cy; + var width = shape.width / 2; + var height = shape.height / 2; + path.moveTo(cx, cy - height); + path.lineTo(cx + width, cy + height); + path.lineTo(cx - width, cy + height); + path.closePath(); + } + }); + + /** + * Diamond shape + * @inner + */ + var Diamond = extendShape({ + type: 'diamond', + shape: { + cx: 0, + cy: 0, + width: 0, + height: 0 + }, + buildPath: function(path, shape) { + var cx = shape.cx; + var cy = shape.cy; + var width = shape.width / 2; + var height = shape.height / 2; + path.moveTo(cx, cy - height); + path.lineTo(cx + width, cy); + path.lineTo(cx, cy + height); + path.lineTo(cx - width, cy); + path.closePath(); + } + }); + + /** + * Pin shape + * @inner + */ + var Pin = extendShape({ + type: 'pin', + shape: { + // x, y on the cusp + x: 0, + y: 0, + width: 0, + height: 0 + }, + + buildPath: function(path, shape) { + var x = shape.x; + var y = shape.y; + var w = shape.width / 5 * 3; + // Height must be larger than width + var h = Math.max(w, shape.height); + var r = w / 2; + + // Dist on y with tangent point and circle center + var dy = r * r / (h - r); + var cy = y - h + r + dy; + var angle = Math.asin(dy / r); + // Dist on x with tangent point and circle center + var dx = Math.cos(angle) * r; + + var tanX = Math.sin(angle); + var tanY = Math.cos(angle); + + var cpLen = r * 0.6; + var cpLen2 = r * 0.7; + + path.moveTo(x - dx, cy + dy); + + path.arc( + x, cy, r, + Math.PI - angle, + Math.PI * 2 + angle + ); + path.bezierCurveTo( + x + dx - tanX * cpLen, cy + dy + tanY * cpLen, + x, y - cpLen2, + x, y + ); + path.bezierCurveTo( + x, y - cpLen2, + x - dx + tanX * cpLen, cy + dy + tanY * cpLen, + x - dx, cy + dy + ); + path.closePath(); + } + }); + + /** + * Arrow shape + * @inner + */ + var Arrow = extendShape({ + + type: 'arrow', + + shape: { + x: 0, + y: 0, + width: 0, + height: 0 + }, + + buildPath: function(ctx, shape) { + var height = shape.height; + var width = shape.width; + var x = shape.x; + var y = shape.y; + var dx = width / 3 * 2; + ctx.moveTo(x, y); + ctx.lineTo(x + dx, y + height); + ctx.lineTo(x, y + height / 4 * 3); + ctx.lineTo(x - dx, y + height); + ctx.lineTo(x, y); + ctx.closePath(); + } + }); + + /** + * Map of path contructors + * @type {Object.} + */ + var symbolCtors = { + + line: Line, + + rect: Rect, + + roundRect: Rect, + + square: Rect, + + circle: Circle, + + diamond: Diamond, + + pin: Pin, + + arrow: Arrow, + + triangle: Triangle + }; + + var symbolShapeMakers = { + + line: function(x, y, w, h, shape) { + // FIXME + shape.x1 = x; + shape.y1 = y + h / 2; + shape.x2 = x + w; + shape.y2 = y + h / 2; + }, + + rect: function(x, y, w, h, shape) { + shape.x = x; + shape.y = y; + shape.width = w; + shape.height = h; + }, + + roundRect: function(x, y, w, h, shape) { + shape.x = x; + shape.y = y; + shape.width = w; + shape.height = h; + shape.r = Math.min(w, h) / 4; + }, + + square: function(x, y, w, h, shape) { + var size = Math.min(w, h); + shape.x = x; + shape.y = y; + shape.width = size; + shape.height = size; + }, + + circle: function(x, y, w, h, shape) { + // Put circle in the center of square + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.r = Math.min(w, h) / 2; + }, + + diamond: function(x, y, w, h, shape) { + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.width = w; + shape.height = h; + }, + + pin: function(x, y, w, h, shape) { + shape.x = x + w / 2; + shape.y = y + h / 2; + shape.width = w; + shape.height = h; + }, + + arrow: function(x, y, w, h, shape) { + shape.x = x + w / 2; + shape.y = y + h / 2; + shape.width = w; + shape.height = h; + }, + + triangle: function(x, y, w, h, shape) { + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.width = w; + shape.height = h; + } + }; + + var symbolBuildProxies = {}; + each$1(symbolCtors, function(Ctor, name) { + symbolBuildProxies[name] = new Ctor(); + }); + + var SymbolClz = extendShape({ + + type: 'symbol', + + shape: { + symbolType: '', + x: 0, + y: 0, + width: 0, + height: 0 + }, + + beforeBrush: function() { + var style = this.style; + var shape = this.shape; + // FIXME + if (shape.symbolType === 'pin' && style.textPosition === 'inside') { + style.textPosition = ['50%', '40%']; + style.textAlign = 'center'; + style.textVerticalAlign = 'middle'; + } + }, + + buildPath: function(ctx, shape, inBundle) { + var symbolType = shape.symbolType; + var proxySymbol = symbolBuildProxies[symbolType]; + if (shape.symbolType !== 'none') { + if (!proxySymbol) { + // Default rect + symbolType = 'rect'; + proxySymbol = symbolBuildProxies[symbolType]; + } + symbolShapeMakers[symbolType]( + shape.x, shape.y, shape.width, shape.height, proxySymbol.shape + ); + proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle); + } + } + }); + + // Provide setColor helper method to avoid determine if set the fill or stroke outside + function symbolPathSetColor(color, innerColor) { + if (this.type !== 'image') { + var symbolStyle = this.style; + var symbolShape = this.shape; + if (symbolShape && symbolShape.symbolType === 'line') { + symbolStyle.stroke = color; + } else if (this.__isEmptyBrush) { + symbolStyle.stroke = color; + symbolStyle.fill = innerColor || '#fff'; + } else { + // FIXME 判断图形默认是填充还是描边,使用 onlyStroke ? + symbolStyle.fill && (symbolStyle.fill = color); + symbolStyle.stroke && (symbolStyle.stroke = color); + } + this.dirty(false); + } + } + + /** + * Create a symbol element with given symbol configuration: shape, x, y, width, height, color + * @param {string} symbolType + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * @param {string} color + * @param {boolean} [keepAspect=false] whether to keep the ratio of w/h, + * for path and image only. + */ + function createSymbol(symbolType, x, y, w, h, color, keepAspect) { + // TODO Support image object, DynamicImage. + + var isEmpty = symbolType.indexOf('empty') === 0; + if (isEmpty) { + symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6); + } + var symbolPath; + + if (symbolType.indexOf('image://') === 0) { + symbolPath = makeImage( + symbolType.slice(8), + new BoundingRect(x, y, w, h), + keepAspect ? 'center' : 'cover' + ); + } else if (symbolType.indexOf('path://') === 0) { + symbolPath = makePath( + symbolType.slice(7), {}, + new BoundingRect(x, y, w, h), + keepAspect ? 'center' : 'cover' + ); + } else { + symbolPath = new SymbolClz({ + shape: { + symbolType: symbolType, + x: x, + y: y, + width: w, + height: h + } + }); + } + + symbolPath.__isEmptyBrush = isEmpty; + + symbolPath.setColor = symbolPathSetColor; + + symbolPath.setColor(color); + + return symbolPath; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // import createGraphFromNodeEdge from './chart/helper/createGraphFromNodeEdge'; + /** + * Create a muti dimension List structure from seriesModel. + * @param {module:echarts/model/Model} seriesModel + * @return {module:echarts/data/List} list + */ + function createList(seriesModel) { + return createListFromArray(seriesModel.getSource(), seriesModel); + } + + var dataStack$1 = { + isDimensionStacked: isDimensionStacked, + enableDataStack: enableDataStack, + getStackedDimension: getStackedDimension + }; + + /** + * Create scale + * @param {Array.} dataExtent + * @param {Object|module:echarts/Model} option + */ + function createScale(dataExtent, option) { + var axisModel = option; + if (!Model.isInstance(option)) { + axisModel = new Model(option); + mixin(axisModel, axisModelCommonMixin); + } + + var scale = createScaleByModel(axisModel); + scale.setExtent(dataExtent[0], dataExtent[1]); + + niceScaleExtent(scale, axisModel); + return scale; + } + + /** + * Mixin common methods to axis model, + * + * Inlcude methods + * `getFormattedLabels() => Array.` + * `getCategories() => Array.` + * `getMin(origin: boolean) => number` + * `getMax(origin: boolean) => number` + * `getNeedCrossZero() => boolean` + * `setRange(start: number, end: number)` + * `resetRange()` + */ + function mixinAxisModelCommonMethods(Model$$1) { + mixin(Model$$1, axisModelCommonMixin); + } + + var helper = (Object.freeze || Object)({ + createList: createList, + getLayoutRect: getLayoutRect, + dataStack: dataStack$1, + createScale: createScale, + mixinAxisModelCommonMethods: mixinAxisModelCommonMethods, + completeDimensions: completeDimensions, + createDimensions: createDimensions, + createSymbol: createSymbol + }); + + var EPSILON$3 = 1e-8; + + function isAroundEqual$1(a, b) { + return Math.abs(a - b) < EPSILON$3; + } + + function contain$1(points, x, y) { + var w = 0; + var p = points[0]; + + if (!p) { + return false; + } + + for (var i = 1; i < points.length; i++) { + var p2 = points[i]; + w += windingLine(p[0], p[1], p2[0], p2[1], x, y); + p = p2; + } + + // Close polygon + var p0 = points[0]; + if (!isAroundEqual$1(p[0], p0[0]) || !isAroundEqual$1(p[1], p0[1])) { + w += windingLine(p[0], p[1], p0[0], p0[1], x, y); + } + + return w !== 0; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/coord/geo/Region + */ + + /** + * @param {string} name + * @param {Array} geometries + * @param {Array.} cp + */ + function Region(name, geometries, cp) { + + /** + * @type {string} + * @readOnly + */ + this.name = name; + + /** + * @type {Array.} + * @readOnly + */ + this.geometries = geometries; + + if (!cp) { + var rect = this.getBoundingRect(); + cp = [ + rect.x + rect.width / 2, + rect.y + rect.height / 2 + ]; + } else { + cp = [cp[0], cp[1]]; + } + /** + * @type {Array.} + */ + this.center = cp; + } + + Region.prototype = { + + constructor: Region, + + properties: null, + + /** + * @return {module:zrender/core/BoundingRect} + */ + getBoundingRect: function() { + var rect = this._rect; + if (rect) { + return rect; + } + + var MAX_NUMBER = Number.MAX_VALUE; + var min$$1 = [MAX_NUMBER, MAX_NUMBER]; + var max$$1 = [-MAX_NUMBER, -MAX_NUMBER]; + var min2 = []; + var max2 = []; + var geometries = this.geometries; + for (var i = 0; i < geometries.length; i++) { + // Only support polygon + if (geometries[i].type !== 'polygon') { + continue; + } + // Doesn't consider hole + var exterior = geometries[i].exterior; + fromPoints(exterior, min2, max2); + min(min$$1, min$$1, min2); + max(max$$1, max$$1, max2); + } + // No data + if (i === 0) { + min$$1[0] = min$$1[1] = max$$1[0] = max$$1[1] = 0; + } + + return (this._rect = new BoundingRect( + min$$1[0], min$$1[1], max$$1[0] - min$$1[0], max$$1[1] - min$$1[1] + )); + }, + + /** + * @param {} coord + * @return {boolean} + */ + contain: function(coord) { + var rect = this.getBoundingRect(); + var geometries = this.geometries; + if (!rect.contain(coord[0], coord[1])) { + return false; + } + loopGeo: for (var i = 0, len$$1 = geometries.length; i < len$$1; i++) { + // Only support polygon. + if (geometries[i].type !== 'polygon') { + continue; + } + var exterior = geometries[i].exterior; + var interiors = geometries[i].interiors; + if (contain$1(exterior, coord[0], coord[1])) { + // Not in the region if point is in the hole. + for (var k = 0; k < (interiors ? interiors.length : 0); k++) { + if (contain$1(interiors[k])) { + continue loopGeo; + } + } + return true; + } + } + return false; + }, + + transformTo: function(x, y, width, height) { + var rect = this.getBoundingRect(); + var aspect = rect.width / rect.height; + if (!width) { + width = aspect * height; + } else if (!height) { + height = width / aspect; + } + var target = new BoundingRect(x, y, width, height); + var transform = rect.calculateTransform(target); + var geometries = this.geometries; + for (var i = 0; i < geometries.length; i++) { + // Only support polygon. + if (geometries[i].type !== 'polygon') { + continue; + } + var exterior = geometries[i].exterior; + var interiors = geometries[i].interiors; + for (var p = 0; p < exterior.length; p++) { + applyTransform(exterior[p], exterior[p], transform); + } + for (var h = 0; h < (interiors ? interiors.length : 0); h++) { + for (var p = 0; p < interiors[h].length; p++) { + applyTransform(interiors[h][p], interiors[h][p], transform); + } + } + } + rect = this._rect; + rect.copy(target); + // Update center + this.center = [ + rect.x + rect.width / 2, + rect.y + rect.height / 2 + ]; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Parse and decode geo json + * @module echarts/coord/geo/parseGeoJson + */ + + function decode(json) { + if (!json.UTF8Encoding) { + return json; + } + var encodeScale = json.UTF8Scale; + if (encodeScale == null) { + encodeScale = 1024; + } + + var features = json.features; + + for (var f = 0; f < features.length; f++) { + var feature = features[f]; + var geometry = feature.geometry; + var coordinates = geometry.coordinates; + var encodeOffsets = geometry.encodeOffsets; + + for (var c = 0; c < coordinates.length; c++) { + var coordinate = coordinates[c]; + + if (geometry.type === 'Polygon') { + coordinates[c] = decodePolygon( + coordinate, + encodeOffsets[c], + encodeScale + ); + } else if (geometry.type === 'MultiPolygon') { + for (var c2 = 0; c2 < coordinate.length; c2++) { + var polygon = coordinate[c2]; + coordinate[c2] = decodePolygon( + polygon, + encodeOffsets[c][c2], + encodeScale + ); + } + } + } + } + // Has been decoded + json.UTF8Encoding = false; + return json; + } + + function decodePolygon(coordinate, encodeOffsets, encodeScale) { + var result = []; + var prevX = encodeOffsets[0]; + var prevY = encodeOffsets[1]; + + for (var i = 0; i < coordinate.length; i += 2) { + var x = coordinate.charCodeAt(i) - 64; + var y = coordinate.charCodeAt(i + 1) - 64; + // ZigZag decoding + x = (x >> 1) ^ (-(x & 1)); + y = (y >> 1) ^ (-(y & 1)); + // Delta deocding + x += prevX; + y += prevY; + + prevX = x; + prevY = y; + // Dequantize + result.push([x / encodeScale, y / encodeScale]); + } + + return result; + } + + /** + * @alias module:echarts/coord/geo/parseGeoJson + * @param {Object} geoJson + * @return {module:zrender/container/Group} + */ + var parseGeoJson$1 = function(geoJson) { + + decode(geoJson); + + return map(filter(geoJson.features, function(featureObj) { + // Output of mapshaper may have geometry null + return featureObj.geometry && + featureObj.properties && + featureObj.geometry.coordinates.length > 0; + }), function(featureObj) { + var properties = featureObj.properties; + var geo = featureObj.geometry; + + var coordinates = geo.coordinates; + + var geometries = []; + if (geo.type === 'Polygon') { + geometries.push({ + type: 'polygon', + // According to the GeoJSON specification. + // First must be exterior, and the rest are all interior(holes). + exterior: coordinates[0], + interiors: coordinates.slice(1) + }); + } + if (geo.type === 'MultiPolygon') { + each$1(coordinates, function(item) { + if (item[0]) { + geometries.push({ + type: 'polygon', + exterior: item[0], + interiors: item.slice(1) + }); + } + }); + } + + var region = new Region( + properties.name, + geometries, + properties.cp + ); + region.properties = properties; + return region; + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$6 = makeInner(); + + /** + * @param {module:echats/coord/Axis} axis + * @return {Object} { + * labels: [{ + * formattedLabel: string, + * rawLabel: string, + * tickValue: number + * }, ...], + * labelCategoryInterval: number + * } + */ + function createAxisLabels(axis) { + // Only ordinal scale support tick interval + return axis.type === 'category' ? + makeCategoryLabels(axis) : + makeRealNumberLabels(axis); + } + + /** + * @param {module:echats/coord/Axis} axis + * @param {module:echarts/model/Model} tickModel For example, can be axisTick, splitLine, splitArea. + * @return {Object} { + * ticks: Array. + * tickCategoryInterval: number + * } + */ + function createAxisTicks(axis, tickModel) { + // Only ordinal scale support tick interval + return axis.type === 'category' ? + makeCategoryTicks(axis, tickModel) : + { + ticks: axis.scale.getTicks() + }; + } + + function makeCategoryLabels(axis) { + var labelModel = axis.getLabelModel(); + var result = makeCategoryLabelsActually(axis, labelModel); + + return (!labelModel.get('show') || axis.scale.isBlank()) ? + { + labels: [], + labelCategoryInterval: result.labelCategoryInterval + } : + result; + } + + function makeCategoryLabelsActually(axis, labelModel) { + var labelsCache = getListCache(axis, 'labels'); + var optionLabelInterval = getOptionCategoryInterval(labelModel); + var result = listCacheGet(labelsCache, optionLabelInterval); + + if (result) { + return result; + } + + var labels; + var numericLabelInterval; + + if (isFunction$1(optionLabelInterval)) { + labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval); + } else { + numericLabelInterval = optionLabelInterval === 'auto' ? + makeAutoCategoryInterval(axis) : optionLabelInterval; + labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval); + } + + // Cache to avoid calling interval function repeatly. + return listCacheSet(labelsCache, optionLabelInterval, { + labels: labels, + labelCategoryInterval: numericLabelInterval + }); + } + + function makeCategoryTicks(axis, tickModel) { + var ticksCache = getListCache(axis, 'ticks'); + var optionTickInterval = getOptionCategoryInterval(tickModel); + var result = listCacheGet(ticksCache, optionTickInterval); + + if (result) { + return result; + } + + var ticks; + var tickCategoryInterval; + + // Optimize for the case that large category data and no label displayed, + // we should not return all ticks. + if (!tickModel.get('show') || axis.scale.isBlank()) { + ticks = []; + } + + if (isFunction$1(optionTickInterval)) { + ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true); + } + // Always use label interval by default despite label show. Consider this + // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows + // labels. `splitLine` and `axisTick` should be consistent in this case. + else if (optionTickInterval === 'auto') { + var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel()); + tickCategoryInterval = labelsResult.labelCategoryInterval; + ticks = map(labelsResult.labels, function(labelItem) { + return labelItem.tickValue; + }); + } else { + tickCategoryInterval = optionTickInterval; + ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true); + } + + // Cache to avoid calling interval function repeatly. + return listCacheSet(ticksCache, optionTickInterval, { + ticks: ticks, + tickCategoryInterval: tickCategoryInterval + }); + } + + function makeRealNumberLabels(axis) { + var ticks = axis.scale.getTicks(); + var labelFormatter = makeLabelFormatter(axis); + return { + labels: map(ticks, function(tickValue, idx) { + return { + formattedLabel: labelFormatter(tickValue, idx), + rawLabel: axis.scale.getLabel(tickValue), + tickValue: tickValue + }; + }) + }; + } + + // Large category data calculation is performence sensitive, and ticks and label + // probably be fetched by multiple times. So we cache the result. + // axis is created each time during a ec process, so we do not need to clear cache. + function getListCache(axis, prop) { + // Because key can be funciton, and cache size always be small, we use array cache. + return inner$6(axis)[prop] || (inner$6(axis)[prop] = []); + } + + function listCacheGet(cache, key) { + for (var i = 0; i < cache.length; i++) { + if (cache[i].key === key) { + return cache[i].value; + } + } + } + + function listCacheSet(cache, key, value) { + cache.push({ + key: key, + value: value + }); + return value; + } + + function makeAutoCategoryInterval(axis) { + var result = inner$6(axis).autoInterval; + return result != null ? + result : + (inner$6(axis).autoInterval = axis.calculateCategoryInterval()); + } + + /** + * Calculate interval for category axis ticks and labels. + * To get precise result, at least one of `getRotate` and `isHorizontal` + * should be implemented in axis. + */ + function calculateCategoryInterval(axis) { + var params = fetchAutoCategoryIntervalCalculationParams(axis); + var labelFormatter = makeLabelFormatter(axis); + var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI; + + var ordinalScale = axis.scale; + var ordinalExtent = ordinalScale.getExtent(); + // Providing this method is for optimization: + // avoid generating a long array by `getTicks` + // in large category data case. + var tickCount = ordinalScale.count(); + + if (ordinalExtent[1] - ordinalExtent[0] < 1) { + return 0; + } + + var step = 1; + // Simple optimization. Empirical value: tick count should less than 40. + if (tickCount > 40) { + step = Math.max(1, Math.floor(tickCount / 40)); + } + var tickValue = ordinalExtent[0]; + var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue); + var unitW = Math.abs(unitSpan * Math.cos(rotation)); + var unitH = Math.abs(unitSpan * Math.sin(rotation)); + + var maxW = 0; + var maxH = 0; + + // Caution: Performance sensitive for large category data. + // Consider dataZoom, we should make appropriate step to avoid O(n) loop. + for (; tickValue <= ordinalExtent[1]; tickValue += step) { + var width = 0; + var height = 0; + + // Polar is also calculated in assumptive linear layout here. + // Not precise, do not consider align and vertical align + // and each distance from axis line yet. + var rect = getBoundingRect( + labelFormatter(tickValue), params.font, 'center', 'top' + ); + // Magic number + width = rect.width * 1.3; + height = rect.height * 1.3; + + // Min size, void long loop. + maxW = Math.max(maxW, width, 7); + maxH = Math.max(maxH, height, 7); + } + + var dw = maxW / unitW; + var dh = maxH / unitH; + // 0/0 is NaN, 1/0 is Infinity. + isNaN(dw) && (dw = Infinity); + isNaN(dh) && (dh = Infinity); + var interval = Math.max(0, Math.floor(Math.min(dw, dh))); + + var cache = inner$6(axis.model); + var lastAutoInterval = cache.lastAutoInterval; + var lastTickCount = cache.lastTickCount; + + // Use cache to keep interval stable while moving zoom window, + // otherwise the calculated interval might jitter when the zoom + // window size is close to the interval-changing size. + if (lastAutoInterval != null && + lastTickCount != null && + Math.abs(lastAutoInterval - interval) <= 1 && + Math.abs(lastTickCount - tickCount) <= 1 + // Always choose the bigger one, otherwise the critical + // point is not the same when zooming in or zooming out. + && + lastAutoInterval > interval + ) { + interval = lastAutoInterval; + } + // Only update cache if cache not used, otherwise the + // changing of interval is too insensitive. + else { + cache.lastTickCount = tickCount; + cache.lastAutoInterval = interval; + } + + return interval; + } + + function fetchAutoCategoryIntervalCalculationParams(axis) { + var labelModel = axis.getLabelModel(); + return { + axisRotate: axis.getRotate ? + axis.getRotate() : + (axis.isHorizontal && !axis.isHorizontal()) ? + 90 : + 0, + labelRotate: labelModel.get('rotate') || 0, + font: labelModel.getFont() + }; + } + + function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) { + var labelFormatter = makeLabelFormatter(axis); + var ordinalScale = axis.scale; + var ordinalExtent = ordinalScale.getExtent(); + var labelModel = axis.getLabelModel(); + var result = []; + + // TODO: axisType: ordinalTime, pick the tick from each month/day/year/... + + var step = Math.max((categoryInterval || 0) + 1, 1); + var startTick = ordinalExtent[0]; + var tickCount = ordinalScale.count(); + + // Calculate start tick based on zero if possible to keep label consistent + // while zooming and moving while interval > 0. Otherwise the selection + // of displayable ticks and symbols probably keep changing. + // 3 is empirical value. + if (startTick !== 0 && step > 1 && tickCount / step > 2) { + startTick = Math.round(Math.ceil(startTick / step) * step); + } + + // (1) Only add min max label here but leave overlap checking + // to render stage, which also ensure the returned list + // suitable for splitLine and splitArea rendering. + // (2) Scales except category always contain min max label so + // do not need to perform this process. + var showMinMax = { + min: labelModel.get('showMinLabel'), + max: labelModel.get('showMaxLabel') + }; + + if (showMinMax.min && startTick !== ordinalExtent[0]) { + addItem(ordinalExtent[0]); + } + + // Optimize: avoid generating large array by `ordinalScale.getTicks()`. + var tickValue = startTick; + for (; tickValue <= ordinalExtent[1]; tickValue += step) { + addItem(tickValue); + } + + if (showMinMax.max && tickValue !== ordinalExtent[1]) { + addItem(ordinalExtent[1]); + } + + function addItem(tVal) { + result.push(onlyTick ? + tVal : + { + formattedLabel: labelFormatter(tVal), + rawLabel: ordinalScale.getLabel(tVal), + tickValue: tVal + } + ); + } + + return result; + } + + // When interval is function, the result `false` means ignore the tick. + // It is time consuming for large category data. + function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) { + var ordinalScale = axis.scale; + var labelFormatter = makeLabelFormatter(axis); + var result = []; + + each$1(ordinalScale.getTicks(), function(tickValue) { + var rawLabel = ordinalScale.getLabel(tickValue); + if (categoryInterval(tickValue, rawLabel)) { + result.push(onlyTick ? + tickValue : + { + formattedLabel: labelFormatter(tickValue), + rawLabel: rawLabel, + tickValue: tickValue + } + ); + } + }); + + return result; + } + + // Can be null|'auto'|number|function + function getOptionCategoryInterval(model) { + var interval = model.get('interval'); + return interval == null ? 'auto' : interval; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var NORMALIZED_EXTENT = [0, 1]; + + /** + * Base class of Axis. + * @constructor + */ + var Axis = function(dim, scale, extent) { + + /** + * Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius'. + * @type {string} + */ + this.dim = dim; + + /** + * Axis scale + * @type {module:echarts/coord/scale/*} + */ + this.scale = scale; + + /** + * @type {Array.} + * @private + */ + this._extent = extent || [0, 0]; + + /** + * @type {boolean} + */ + this.inverse = false; + + /** + * Usually true when axis has a ordinal scale + * @type {boolean} + */ + this.onBand = false; + }; + + Axis.prototype = { + + constructor: Axis, + + /** + * If axis extent contain given coord + * @param {number} coord + * @return {boolean} + */ + contain: function(coord) { + var extent = this._extent; + var min = Math.min(extent[0], extent[1]); + var max = Math.max(extent[0], extent[1]); + return coord >= min && coord <= max; + }, + + /** + * If axis extent contain given data + * @param {number} data + * @return {boolean} + */ + containData: function(data) { + return this.contain(this.dataToCoord(data)); + }, + + /** + * Get coord extent. + * @return {Array.} + */ + getExtent: function() { + return this._extent.slice(); + }, + + /** + * Get precision used for formatting + * @param {Array.} [dataExtent] + * @return {number} + */ + getPixelPrecision: function(dataExtent) { + return getPixelPrecision( + dataExtent || this.scale.getExtent(), + this._extent + ); + }, + + /** + * Set coord extent + * @param {number} start + * @param {number} end + */ + setExtent: function(start, end) { + var extent = this._extent; + extent[0] = start; + extent[1] = end; + }, + + /** + * Convert data to coord. Data is the rank if it has an ordinal scale + * @param {number} data + * @param {boolean} clamp + * @return {number} + */ + dataToCoord: function(data, clamp) { + var extent = this._extent; + var scale = this.scale; + data = scale.normalize(data); + + if (this.onBand && scale.type === 'ordinal') { + extent = extent.slice(); + fixExtentWithBands(extent, scale.count()); + } + + return linearMap(data, NORMALIZED_EXTENT, extent, clamp); + }, + + /** + * Convert coord to data. Data is the rank if it has an ordinal scale + * @param {number} coord + * @param {boolean} clamp + * @return {number} + */ + coordToData: function(coord, clamp) { + var extent = this._extent; + var scale = this.scale; + + if (this.onBand && scale.type === 'ordinal') { + extent = extent.slice(); + fixExtentWithBands(extent, scale.count()); + } + + var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp); + + return this.scale.scale(t); + }, + + /** + * Convert pixel point to data in axis + * @param {Array.} point + * @param {boolean} clamp + * @return {number} data + */ + pointToData: function(point, clamp) { + // Should be implemented in derived class if necessary. + }, + + /** + * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`, + * `axis.getTicksCoords` considers `onBand`, which is used by + * `boundaryGap:true` of category axis and splitLine and splitArea. + * @param {Object} [opt] + * @param {number} [opt.tickModel=axis.model.getModel('axisTick')] + * @param {boolean} [opt.clamp] If `true`, the first and the last + * tick must be at the axis end points. Otherwise, clip ticks + * that outside the axis extent. + * @return {Array.} [{ + * coord: ..., + * tickValue: ... + * }, ...] + */ + getTicksCoords: function(opt) { + opt = opt || {}; + + var tickModel = opt.tickModel || this.getTickModel(); + + var result = createAxisTicks(this, tickModel); + var ticks = result.ticks; + + var ticksCoords = map(ticks, function(tickValue) { + return { + coord: this.dataToCoord(tickValue), + tickValue: tickValue + }; + }, this); + + var alignWithLabel = tickModel.get('alignWithLabel'); + fixOnBandTicksCoords( + this, ticksCoords, result.tickCategoryInterval, alignWithLabel, opt.clamp + ); + + return ticksCoords; + }, + + /** + * @return {Array.} [{ + * formattedLabel: string, + * rawLabel: axis.scale.getLabel(tickValue) + * tickValue: number + * }, ...] + */ + getViewLabels: function() { + return createAxisLabels(this).labels; + }, + + /** + * @return {module:echarts/coord/model/Model} + */ + getLabelModel: function() { + return this.model.getModel('axisLabel'); + }, + + /** + * Notice here we only get the default tick model. For splitLine + * or splitArea, we should pass the splitLineModel or splitAreaModel + * manually when calling `getTicksCoords`. + * In GL, this method may be overrided to: + * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));` + * @return {module:echarts/coord/model/Model} + */ + getTickModel: function() { + return this.model.getModel('axisTick'); + }, + + /** + * Get width of band + * @return {number} + */ + getBandWidth: function() { + var axisExtent = this._extent; + var dataExtent = this.scale.getExtent(); + + var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0); + // Fix #2728, avoid NaN when only one data. + len === 0 && (len = 1); + + var size = Math.abs(axisExtent[1] - axisExtent[0]); + + return Math.abs(size) / len; + }, + + /** + * @abstract + * @return {boolean} Is horizontal + */ + isHorizontal: null, + + /** + * @abstract + * @return {number} Get axis rotate, by degree. + */ + getRotate: null, + + /** + * Only be called in category axis. + * Can be overrided, consider other axes like in 3D. + * @return {number} Auto interval for cateogry axis tick and label + */ + calculateCategoryInterval: function() { + return calculateCategoryInterval(this); + } + + }; + + function fixExtentWithBands(extent, nTick) { + var size = extent[1] - extent[0]; + var len = nTick; + var margin = size / len / 2; + extent[0] += margin; + extent[1] -= margin; + } + + // If axis has labels [1, 2, 3, 4]. Bands on the axis are + // |---1---|---2---|---3---|---4---|. + // So the displayed ticks and splitLine/splitArea should between + // each data item, otherwise cause misleading (e.g., split tow bars + // of a single data item when there are two bar series). + // Also consider if tickCategoryInterval > 0 and onBand, ticks and + // splitLine/spliteArea should layout appropriately corresponding + // to displayed labels. (So we should not use `getBandWidth` in this + // case). + function fixOnBandTicksCoords(axis, ticksCoords, tickCategoryInterval, alignWithLabel, clamp) { + var ticksLen = ticksCoords.length; + + if (!axis.onBand || alignWithLabel || !ticksLen) { + return; + } + + var axisExtent = axis.getExtent(); + var last; + if (ticksLen === 1) { + ticksCoords[0].coord = axisExtent[0]; + last = ticksCoords[1] = { + coord: axisExtent[0] + }; + } else { + var shift = (ticksCoords[1].coord - ticksCoords[0].coord); + each$1(ticksCoords, function(ticksItem) { + ticksItem.coord -= shift / 2; + var tickCategoryInterval = tickCategoryInterval || 0; + // Avoid split a single data item when odd interval. + if (tickCategoryInterval % 2 > 0) { + ticksItem.coord -= shift / ((tickCategoryInterval + 1) * 2); + } + }); + last = { + coord: ticksCoords[ticksLen - 1].coord + shift + }; + ticksCoords.push(last); + } + + var inverse = axisExtent[0] > axisExtent[1]; + + if (littleThan(ticksCoords[0].coord, axisExtent[0])) { + clamp ? (ticksCoords[0].coord = axisExtent[0]) : ticksCoords.shift(); + } + if (clamp && littleThan(axisExtent[0], ticksCoords[0].coord)) { + ticksCoords.unshift({ + coord: axisExtent[0] + }); + } + if (littleThan(axisExtent[1], last.coord)) { + clamp ? (last.coord = axisExtent[1]) : ticksCoords.pop(); + } + if (clamp && littleThan(last.coord, axisExtent[1])) { + ticksCoords.push({ + coord: axisExtent[1] + }); + } + + function littleThan(a, b) { + return inverse ? a > b : a < b; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Do not mount those modules on 'src/echarts' for better tree shaking. + */ + + var parseGeoJson = parseGeoJson$1; + + var ecUtil = {}; + each$1([ + 'map', 'each', 'filter', 'indexOf', 'inherits', 'reduce', 'filter', + 'bind', 'curry', 'isArray', 'isString', 'isObject', 'isFunction', + 'extend', 'defaults', 'clone', 'merge' + ], + function(name) { + ecUtil[name] = zrUtil[name]; + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.line', + + dependencies: ['grid', 'polar'], + + getInitialData: function(option, ecModel) { + if (__DEV__) { + var coordSys = option.coordinateSystem; + if (coordSys !== 'polar' && coordSys !== 'cartesian2d') { + throw new Error('Line not support coordinateSystem besides cartesian and polar'); + } + } + return createListFromArray(this.getSource(), this); + }, + + defaultOption: { + zlevel: 0, + z: 2, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + + hoverAnimation: true, + // stack: null + // xAxisIndex: 0, + // yAxisIndex: 0, + + // polarIndex: 0, + + // If clip the overflow value + clipOverflow: true, + // cursor: null, + + label: { + position: 'top' + }, + // itemStyle: { + // }, + + lineStyle: { + width: 2, + type: 'solid' + }, + // areaStyle: { + // origin of areaStyle. Valid values: + // `'auto'/null/undefined`: from axisLine to data + // `'start'`: from min to data + // `'end'`: from data to max + // origin: 'auto' + // }, + // false, 'start', 'end', 'middle' + step: false, + + // Disabled if step is true + smooth: false, + smoothMonotone: null, + symbol: 'emptyCircle', + symbolSize: 4, + symbolRotate: null, + + showSymbol: true, + // `false`: follow the label interval strategy. + // `true`: show all symbols. + // `'auto'`: If possible, show all symbols, otherwise + // follow the label interval strategy. + showAllSymbol: 'auto', + + // Whether to connect break point. + connectNulls: false, + + // Sampling for large data. Can be: 'average', 'max', 'min', 'sum'. + sampling: 'none', + + animationEasing: 'linear', + + // Disable progressive + progressive: 0, + hoverLayerThreshold: Infinity + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/data/List} data + * @param {number} dataIndex + * @return {string} label string. Not null/undefined + */ + function getDefaultLabel(data, dataIndex) { + var labelDims = data.mapDimension('defaultedLabel', true); + var len = labelDims.length; + + // Simple optimization (in lots of cases, label dims length is 1) + if (len === 1) { + return retrieveRawValue(data, dataIndex, labelDims[0]); + } else if (len) { + var vals = []; + for (var i = 0; i < labelDims.length; i++) { + var val = retrieveRawValue(data, dataIndex, labelDims[i]); + vals.push(val); + } + return vals.join(' '); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/chart/helper/Symbol + */ + + /** + * @constructor + * @alias {module:echarts/chart/helper/Symbol} + * @param {module:echarts/data/List} data + * @param {number} idx + * @extends {module:zrender/graphic/Group} + */ + function SymbolClz$1(data, idx, seriesScope) { + Group.call(this); + this.updateData(data, idx, seriesScope); + } + + var symbolProto = SymbolClz$1.prototype; + + /** + * @public + * @static + * @param {module:echarts/data/List} data + * @param {number} dataIndex + * @return {Array.} [width, height] + */ + var getSymbolSize = SymbolClz$1.getSymbolSize = function(data, idx) { + var symbolSize = data.getItemVisual(idx, 'symbolSize'); + return symbolSize instanceof Array ? + symbolSize.slice() : + [+symbolSize, +symbolSize]; + }; + + function getScale(symbolSize) { + return [symbolSize[0] / 2, symbolSize[1] / 2]; + } + + function driftSymbol(dx, dy) { + this.parent.drift(dx, dy); + } + + symbolProto._createSymbol = function( + symbolType, + data, + idx, + symbolSize, + keepAspect + ) { + // Remove paths created before + this.removeAll(); + + var color = data.getItemVisual(idx, 'color'); + + // var symbolPath = createSymbol( + // symbolType, -0.5, -0.5, 1, 1, color + // ); + // If width/height are set too small (e.g., set to 1) on ios10 + // and macOS Sierra, a circle stroke become a rect, no matter what + // the scale is set. So we set width/height as 2. See #4150. + var symbolPath = createSymbol( + symbolType, -1, -1, 2, 2, color, keepAspect + ); + + symbolPath.attr({ + z2: 100, + culling: true, + scale: getScale(symbolSize) + }); + // Rewrite drift method + symbolPath.drift = driftSymbol; + + this._symbolType = symbolType; + + this.add(symbolPath); + }; + + /** + * Stop animation + * @param {boolean} toLastFrame + */ + symbolProto.stopSymbolAnimation = function(toLastFrame) { + this.childAt(0).stopAnimation(toLastFrame); + }; + + /** + * FIXME: + * Caution: This method breaks the encapsulation of this module, + * but it indeed brings convenience. So do not use the method + * unless you detailedly know all the implements of `Symbol`, + * especially animation. + * + * Get symbol path element. + */ + symbolProto.getSymbolPath = function() { + return this.childAt(0); + }; + + /** + * Get scale(aka, current symbol size). + * Including the change caused by animation + */ + symbolProto.getScale = function() { + return this.childAt(0).scale; + }; + + /** + * Highlight symbol + */ + symbolProto.highlight = function() { + this.childAt(0).trigger('emphasis'); + }; + + /** + * Downplay symbol + */ + symbolProto.downplay = function() { + this.childAt(0).trigger('normal'); + }; + + /** + * @param {number} zlevel + * @param {number} z + */ + symbolProto.setZ = function(zlevel, z) { + var symbolPath = this.childAt(0); + symbolPath.zlevel = zlevel; + symbolPath.z = z; + }; + + symbolProto.setDraggable = function(draggable) { + var symbolPath = this.childAt(0); + symbolPath.draggable = draggable; + symbolPath.cursor = draggable ? 'move' : 'pointer'; + }; + + /** + * Update symbol properties + * @param {module:echarts/data/List} data + * @param {number} idx + * @param {Object} [seriesScope] + * @param {Object} [seriesScope.itemStyle] + * @param {Object} [seriesScope.hoverItemStyle] + * @param {Object} [seriesScope.symbolRotate] + * @param {Object} [seriesScope.symbolOffset] + * @param {module:echarts/model/Model} [seriesScope.labelModel] + * @param {module:echarts/model/Model} [seriesScope.hoverLabelModel] + * @param {boolean} [seriesScope.hoverAnimation] + * @param {Object} [seriesScope.cursorStyle] + * @param {module:echarts/model/Model} [seriesScope.itemModel] + * @param {string} [seriesScope.symbolInnerColor] + * @param {Object} [seriesScope.fadeIn=false] + */ + symbolProto.updateData = function(data, idx, seriesScope) { + this.silent = false; + + var symbolType = data.getItemVisual(idx, 'symbol') || 'circle'; + var seriesModel = data.hostModel; + var symbolSize = getSymbolSize(data, idx); + var isInit = symbolType !== this._symbolType; + + if (isInit) { + var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect'); + this._createSymbol(symbolType, data, idx, symbolSize, keepAspect); + } else { + var symbolPath = this.childAt(0); + symbolPath.silent = false; + updateProps(symbolPath, { + scale: getScale(symbolSize) + }, seriesModel, idx); + } + + this._updateCommon(data, idx, symbolSize, seriesScope); + + if (isInit) { + var symbolPath = this.childAt(0); + var fadeIn = seriesScope && seriesScope.fadeIn; + + var target = { + scale: symbolPath.scale.slice() + }; + fadeIn && (target.style = { + opacity: symbolPath.style.opacity + }); + + symbolPath.scale = [0, 0]; + fadeIn && (symbolPath.style.opacity = 0); + + initProps(symbolPath, target, seriesModel, idx); + } + + this._seriesModel = seriesModel; + }; + + // Update common properties + var normalStyleAccessPath = ['itemStyle']; + var emphasisStyleAccessPath = ['emphasis', 'itemStyle']; + var normalLabelAccessPath = ['label']; + var emphasisLabelAccessPath = ['emphasis', 'label']; + + /** + * @param {module:echarts/data/List} data + * @param {number} idx + * @param {Array.} symbolSize + * @param {Object} [seriesScope] + */ + symbolProto._updateCommon = function(data, idx, symbolSize, seriesScope) { + var symbolPath = this.childAt(0); + var seriesModel = data.hostModel; + var color = data.getItemVisual(idx, 'color'); + + // Reset style + if (symbolPath.type !== 'image') { + symbolPath.useStyle({ + strokeNoScale: true + }); + } + + var itemStyle = seriesScope && seriesScope.itemStyle; + var hoverItemStyle = seriesScope && seriesScope.hoverItemStyle; + var symbolRotate = seriesScope && seriesScope.symbolRotate; + var symbolOffset = seriesScope && seriesScope.symbolOffset; + var labelModel = seriesScope && seriesScope.labelModel; + var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel; + var hoverAnimation = seriesScope && seriesScope.hoverAnimation; + var cursorStyle = seriesScope && seriesScope.cursorStyle; + + if (!seriesScope || data.hasItemOption) { + var itemModel = (seriesScope && seriesScope.itemModel) ? + seriesScope.itemModel : data.getItemModel(idx); + + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + itemStyle = itemModel.getModel(normalStyleAccessPath).getItemStyle(['color']); + hoverItemStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle(); + + symbolRotate = itemModel.getShallow('symbolRotate'); + symbolOffset = itemModel.getShallow('symbolOffset'); + + labelModel = itemModel.getModel(normalLabelAccessPath); + hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath); + hoverAnimation = itemModel.getShallow('hoverAnimation'); + cursorStyle = itemModel.getShallow('cursor'); + } else { + hoverItemStyle = extend({}, hoverItemStyle); + } + + var elStyle = symbolPath.style; + + symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0); + + if (symbolOffset) { + symbolPath.attr('position', [ + parsePercent$1(symbolOffset[0], symbolSize[0]), + parsePercent$1(symbolOffset[1], symbolSize[1]) + ]); + } + + cursorStyle && symbolPath.attr('cursor', cursorStyle); + + // PENDING setColor before setStyle!!! + symbolPath.setColor(color, seriesScope && seriesScope.symbolInnerColor); + + symbolPath.setStyle(itemStyle); + + var opacity = data.getItemVisual(idx, 'opacity'); + if (opacity != null) { + elStyle.opacity = opacity; + } + + var liftZ = data.getItemVisual(idx, 'liftZ'); + var z2Origin = symbolPath.__z2Origin; + if (liftZ != null) { + if (z2Origin == null) { + symbolPath.__z2Origin = symbolPath.z2; + symbolPath.z2 += liftZ; + } + } else if (z2Origin != null) { + symbolPath.z2 = z2Origin; + symbolPath.__z2Origin = null; + } + + var useNameLabel = seriesScope && seriesScope.useNameLabel; + + setLabelStyle( + elStyle, hoverItemStyle, labelModel, hoverLabelModel, { + labelFetcher: seriesModel, + labelDataIndex: idx, + defaultText: getLabelDefaultText, + isRectText: true, + autoColor: color + } + ); + + // Do not execute util needed. + function getLabelDefaultText(idx, opt) { + return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx); + } + + symbolPath.off('mouseover') + .off('mouseout') + .off('emphasis') + .off('normal'); + + symbolPath.hoverStyle = hoverItemStyle; + + // FIXME + // Do not use symbol.trigger('emphasis'), but use symbol.highlight() instead. + setHoverStyle(symbolPath); + + var scale = getScale(symbolSize); + + if (hoverAnimation && seriesModel.isAnimationEnabled()) { + var onEmphasis = function() { + // Do not support this hover animation util some scenario required. + // Animation can only be supported in hover layer when using `el.incremetal`. + if (this.incremental) { + return; + } + var ratio = scale[1] / scale[0]; + this.animateTo({ + scale: [ + Math.max(scale[0] * 1.1, scale[0] + 3), + Math.max(scale[1] * 1.1, scale[1] + 3 * ratio) + ] + }, 400, 'elasticOut'); + }; + var onNormal = function() { + if (this.incremental) { + return; + } + this.animateTo({ + scale: scale + }, 400, 'elasticOut'); + }; + symbolPath.on('mouseover', onEmphasis) + .on('mouseout', onNormal) + .on('emphasis', onEmphasis) + .on('normal', onNormal); + } + }; + + /** + * @param {Function} cb + * @param {Object} [opt] + * @param {Object} [opt.keepLabel=true] + */ + symbolProto.fadeOut = function(cb, opt) { + var symbolPath = this.childAt(0); + // Avoid mistaken hover when fading out + this.silent = symbolPath.silent = true; + // Not show text when animating + !(opt && opt.keepLabel) && (symbolPath.style.text = null); + + updateProps( + symbolPath, { + style: { + opacity: 0 + }, + scale: [0, 0] + }, + this._seriesModel, + this.dataIndex, + cb + ); + }; + + inherits(SymbolClz$1, Group); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/chart/helper/SymbolDraw + */ + + /** + * @constructor + * @alias module:echarts/chart/helper/SymbolDraw + * @param {module:zrender/graphic/Group} [symbolCtor] + */ + function SymbolDraw(symbolCtor) { + this.group = new Group(); + + this._symbolCtor = symbolCtor || SymbolClz$1; + } + + var symbolDrawProto = SymbolDraw.prototype; + + function symbolNeedsDraw(data, point, idx, opt) { + return point && !isNaN(point[0]) && !isNaN(point[1]) && + !(opt.isIgnore && opt.isIgnore(idx)) + // We do not set clipShape on group, because it will cut part of + // the symbol element shape. We use the same clip shape here as + // the line clip. + && + !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && + data.getItemVisual(idx, 'symbol') !== 'none'; + } + + /** + * Update symbols draw by new data + * @param {module:echarts/data/List} data + * @param {Object} [opt] Or isIgnore + * @param {Function} [opt.isIgnore] + * @param {Object} [opt.clipShape] + */ + symbolDrawProto.updateData = function(data, opt) { + opt = normalizeUpdateOpt(opt); + + var group = this.group; + var seriesModel = data.hostModel; + var oldData = this._data; + var SymbolCtor = this._symbolCtor; + + var seriesScope = makeSeriesScope(data); + + // There is no oldLineData only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!oldData) { + group.removeAll(); + } + + data.diff(oldData) + .add(function(newIdx) { + var point = data.getItemLayout(newIdx); + if (symbolNeedsDraw(data, point, newIdx, opt)) { + var symbolEl = new SymbolCtor(data, newIdx, seriesScope); + symbolEl.attr('position', point); + data.setItemGraphicEl(newIdx, symbolEl); + group.add(symbolEl); + } + }) + .update(function(newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + var point = data.getItemLayout(newIdx); + if (!symbolNeedsDraw(data, point, newIdx, opt)) { + group.remove(symbolEl); + return; + } + if (!symbolEl) { + symbolEl = new SymbolCtor(data, newIdx); + symbolEl.attr('position', point); + } else { + symbolEl.updateData(data, newIdx, seriesScope); + updateProps(symbolEl, { + position: point + }, seriesModel); + } + + // Add back + group.add(symbolEl); + + data.setItemGraphicEl(newIdx, symbolEl); + }) + .remove(function(oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && el.fadeOut(function() { + group.remove(el); + }); + }) + .execute(); + + this._data = data; + }; + + symbolDrawProto.isPersistent = function() { + return true; + }; + + symbolDrawProto.updateLayout = function() { + var data = this._data; + if (data) { + // Not use animation + data.eachItemGraphicEl(function(el, idx) { + var point = data.getItemLayout(idx); + el.attr('position', point); + }); + } + }; + + symbolDrawProto.incrementalPrepareUpdate = function(data) { + this._seriesScope = makeSeriesScope(data); + this._data = null; + this.group.removeAll(); + }; + + /** + * Update symbols draw by new data + * @param {module:echarts/data/List} data + * @param {Object} [opt] Or isIgnore + * @param {Function} [opt.isIgnore] + * @param {Object} [opt.clipShape] + */ + symbolDrawProto.incrementalUpdate = function(taskParams, data, opt) { + opt = normalizeUpdateOpt(opt); + + function updateIncrementalAndHover(el) { + if (!el.isGroup) { + el.incremental = el.useHoverLayer = true; + } + } + for (var idx = taskParams.start; idx < taskParams.end; idx++) { + var point = data.getItemLayout(idx); + if (symbolNeedsDraw(data, point, idx, opt)) { + var el = new this._symbolCtor(data, idx, this._seriesScope); + el.traverse(updateIncrementalAndHover); + el.attr('position', point); + this.group.add(el); + data.setItemGraphicEl(idx, el); + } + } + }; + + function normalizeUpdateOpt(opt) { + if (opt != null && !isObject$1(opt)) { + opt = { + isIgnore: opt + }; + } + return opt || {}; + } + + symbolDrawProto.remove = function(enableAnimation) { + var group = this.group; + var data = this._data; + // Incremental model do not have this._data. + if (data && enableAnimation) { + data.eachItemGraphicEl(function(el) { + el.fadeOut(function() { + group.remove(el); + }); + }); + } else { + group.removeAll(); + } + }; + + function makeSeriesScope(data) { + var seriesModel = data.hostModel; + return { + itemStyle: seriesModel.getModel('itemStyle').getItemStyle(['color']), + hoverItemStyle: seriesModel.getModel('emphasis.itemStyle').getItemStyle(), + symbolRotate: seriesModel.get('symbolRotate'), + symbolOffset: seriesModel.get('symbolOffset'), + hoverAnimation: seriesModel.get('hoverAnimation'), + labelModel: seriesModel.getModel('label'), + hoverLabelModel: seriesModel.getModel('emphasis.label'), + cursorStyle: seriesModel.get('cursor') + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {Object} coordSys + * @param {module:echarts/data/List} data + * @param {string} valueOrigin lineSeries.option.areaStyle.origin + */ + function prepareDataCoordInfo(coordSys, data, valueOrigin) { + var baseAxis = coordSys.getBaseAxis(); + var valueAxis = coordSys.getOtherAxis(baseAxis); + var valueStart = getValueStart(valueAxis, valueOrigin); + + var baseAxisDim = baseAxis.dim; + var valueAxisDim = valueAxis.dim; + var valueDim = data.mapDimension(valueAxisDim); + var baseDim = data.mapDimension(baseAxisDim); + var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0; + + var dims = map(coordSys.dimensions, function(coordDim) { + return data.mapDimension(coordDim); + }); + + var stacked; + var stackResultDim = data.getCalculationInfo('stackResultDimension'); + if (stacked |= isDimensionStacked(data, dims[0] /*, dims[1]*/ )) { // jshint ignore:line + dims[0] = stackResultDim; + } + if (stacked |= isDimensionStacked(data, dims[1] /*, dims[0]*/ )) { // jshint ignore:line + dims[1] = stackResultDim; + } + + return { + dataDimsForPoint: dims, + valueStart: valueStart, + valueAxisDim: valueAxisDim, + baseAxisDim: baseAxisDim, + stacked: !!stacked, + valueDim: valueDim, + baseDim: baseDim, + baseDataOffset: baseDataOffset, + stackedOverDimension: data.getCalculationInfo('stackedOverDimension') + }; + } + + function getValueStart(valueAxis, valueOrigin) { + var valueStart = 0; + var extent = valueAxis.scale.getExtent(); + + if (valueOrigin === 'start') { + valueStart = extent[0]; + } else if (valueOrigin === 'end') { + valueStart = extent[1]; + } + // auto + else { + // Both positive + if (extent[0] > 0) { + valueStart = extent[0]; + } + // Both negative + else if (extent[1] < 0) { + valueStart = extent[1]; + } + // If is one positive, and one negative, onZero shall be true + } + + return valueStart; + } + + function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) { + var value = NaN; + if (dataCoordInfo.stacked) { + value = data.get(data.getCalculationInfo('stackedOverDimension'), idx); + } + if (isNaN(value)) { + value = dataCoordInfo.valueStart; + } + + var baseDataOffset = dataCoordInfo.baseDataOffset; + var stackedData = []; + stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx); + stackedData[1 - baseDataOffset] = value; + + return coordSys.dataToPoint(stackedData); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // var arrayDiff = require('zrender/src/core/arrayDiff'); + // 'zrender/src/core/arrayDiff' has been used before, but it did + // not do well in performance when roam with fixed dataZoom window. + + // function convertToIntId(newIdList, oldIdList) { + // // Generate int id instead of string id. + // // Compare string maybe slow in score function of arrDiff + + // // Assume id in idList are all unique + // var idIndicesMap = {}; + // var idx = 0; + // for (var i = 0; i < newIdList.length; i++) { + // idIndicesMap[newIdList[i]] = idx; + // newIdList[i] = idx++; + // } + // for (var i = 0; i < oldIdList.length; i++) { + // var oldId = oldIdList[i]; + // // Same with newIdList + // if (idIndicesMap[oldId]) { + // oldIdList[i] = idIndicesMap[oldId]; + // } + // else { + // oldIdList[i] = idx++; + // } + // } + // } + + function diffData(oldData, newData) { + var diffResult = []; + + newData.diff(oldData) + .add(function(idx) { + diffResult.push({ + cmd: '+', + idx: idx + }); + }) + .update(function(newIdx, oldIdx) { + diffResult.push({ + cmd: '=', + idx: oldIdx, + idx1: newIdx + }); + }) + .remove(function(idx) { + diffResult.push({ + cmd: '-', + idx: idx + }); + }) + .execute(); + + return diffResult; + } + + var lineAnimationDiff = function( + oldData, newData, + oldStackedOnPoints, newStackedOnPoints, + oldCoordSys, newCoordSys, + oldValueOrigin, newValueOrigin + ) { + var diff = diffData(oldData, newData); + + // var newIdList = newData.mapArray(newData.getId); + // var oldIdList = oldData.mapArray(oldData.getId); + + // convertToIntId(newIdList, oldIdList); + + // // FIXME One data ? + // diff = arrayDiff(oldIdList, newIdList); + + var currPoints = []; + var nextPoints = []; + // Points for stacking base line + var currStackedPoints = []; + var nextStackedPoints = []; + + var status = []; + var sortedIndices = []; + var rawIndices = []; + + var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); + var oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin); + + for (var i = 0; i < diff.length; i++) { + var diffItem = diff[i]; + var pointAdded = true; + + // FIXME, animation is not so perfect when dataZoom window moves fast + // Which is in case remvoing or add more than one data in the tail or head + switch (diffItem.cmd) { + case '=': + var currentPt = oldData.getItemLayout(diffItem.idx); + var nextPt = newData.getItemLayout(diffItem.idx1); + // If previous data is NaN, use next point directly + if (isNaN(currentPt[0]) || isNaN(currentPt[1])) { + currentPt = nextPt.slice(); + } + currPoints.push(currentPt); + nextPoints.push(nextPt); + + currStackedPoints.push(oldStackedOnPoints[diffItem.idx]); + nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]); + + rawIndices.push(newData.getRawIndex(diffItem.idx1)); + break; + case '+': + var idx = diffItem.idx; + currPoints.push( + oldCoordSys.dataToPoint([ + newData.get(newDataOldCoordInfo.dataDimsForPoint[0], idx), + newData.get(newDataOldCoordInfo.dataDimsForPoint[1], idx) + ]) + ); + + nextPoints.push(newData.getItemLayout(idx).slice()); + + currStackedPoints.push( + getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, idx) + ); + nextStackedPoints.push(newStackedOnPoints[idx]); + + rawIndices.push(newData.getRawIndex(idx)); + break; + case '-': + var idx = diffItem.idx; + var rawIndex = oldData.getRawIndex(idx); + // Data is replaced. In the case of dynamic data queue + // FIXME FIXME FIXME + if (rawIndex !== idx) { + currPoints.push(oldData.getItemLayout(idx)); + nextPoints.push(newCoordSys.dataToPoint([ + oldData.get(oldDataNewCoordInfo.dataDimsForPoint[0], idx), + oldData.get(oldDataNewCoordInfo.dataDimsForPoint[1], idx) + ])); + + currStackedPoints.push(oldStackedOnPoints[idx]); + nextStackedPoints.push( + getStackedOnPoint(oldDataNewCoordInfo, newCoordSys, oldData, idx) + ); + + rawIndices.push(rawIndex); + } else { + pointAdded = false; + } + } + + // Original indices + if (pointAdded) { + status.push(diffItem); + sortedIndices.push(sortedIndices.length); + } + } + + // Diff result may be crossed if all items are changed + // Sort by data index + sortedIndices.sort(function(a, b) { + return rawIndices[a] - rawIndices[b]; + }); + + var sortedCurrPoints = []; + var sortedNextPoints = []; + + var sortedCurrStackedPoints = []; + var sortedNextStackedPoints = []; + + var sortedStatus = []; + for (var i = 0; i < sortedIndices.length; i++) { + var idx = sortedIndices[i]; + sortedCurrPoints[i] = currPoints[idx]; + sortedNextPoints[i] = nextPoints[idx]; + + sortedCurrStackedPoints[i] = currStackedPoints[idx]; + sortedNextStackedPoints[i] = nextStackedPoints[idx]; + + sortedStatus[i] = status[idx]; + } + + return { + current: sortedCurrPoints, + next: sortedNextPoints, + + stackedOnCurrent: sortedCurrStackedPoints, + stackedOnNext: sortedNextStackedPoints, + + status: sortedStatus + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Poly path support NaN point + + var vec2Min = min; + var vec2Max = max; + + var scaleAndAdd$1 = scaleAndAdd; + var v2Copy = copy; + + // Temporary variable + var v = []; + var cp0 = []; + var cp1 = []; + + function isPointNull(p) { + return isNaN(p[0]) || isNaN(p[1]); + } + + function drawSegment( + ctx, points, start, segLen, allLen, + dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls + ) { + // if (smoothMonotone == null) { + // if (isMono(points, 'x')) { + // return drawMono(ctx, points, start, segLen, allLen, + // dir, smoothMin, smoothMax, smooth, 'x', connectNulls); + // } + // else if (isMono(points, 'y')) { + // return drawMono(ctx, points, start, segLen, allLen, + // dir, smoothMin, smoothMax, smooth, 'y', connectNulls); + // } + // else { + // return drawNonMono.apply(this, arguments); + // } + // } + // else if (smoothMonotone !== 'none' && isMono(points, smoothMonotone)) { + // return drawMono.apply(this, arguments); + // } + // else { + // return drawNonMono.apply(this, arguments); + // } + if (smoothMonotone === 'none' || !smoothMonotone) { + return drawNonMono.apply(this, arguments); + } else { + return drawMono.apply(this, arguments); + } + } + + /** + * Check if points is in monotone. + * + * @param {number[][]} points Array of points which is in [x, y] form + * @param {string} smoothMonotone 'x', 'y', or 'none', stating for which + * dimension that is checking. + * If is 'none', `drawNonMono` should be + * called. + * If is undefined, either being monotone + * in 'x' or 'y' will call `drawMono`. + */ + // function isMono(points, smoothMonotone) { + // if (points.length <= 1) { + // return true; + // } + + // var dim = smoothMonotone === 'x' ? 0 : 1; + // var last = points[0][dim]; + // var lastDiff = 0; + // for (var i = 1; i < points.length; ++i) { + // var diff = points[i][dim] - last; + // if (!isNaN(diff) && !isNaN(lastDiff) + // && diff !== 0 && lastDiff !== 0 + // && ((diff >= 0) !== (lastDiff >= 0)) + // ) { + // return false; + // } + // if (!isNaN(diff) && diff !== 0) { + // lastDiff = diff; + // last = points[i][dim]; + // } + // } + // return true; + // } + + /** + * Draw smoothed line in monotone, in which only vertical or horizontal bezier + * control points will be used. This should be used when points are monotone + * either in x or y dimension. + */ + function drawMono( + ctx, points, start, segLen, allLen, + dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls + ) { + var prevIdx = 0; + var idx = start; + for (var k = 0; k < segLen; k++) { + var p = points[idx]; + if (idx >= allLen || idx < 0) { + break; + } + if (isPointNull(p)) { + if (connectNulls) { + idx += dir; + continue; + } + break; + } + + if (idx === start) { + ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]); + } else { + if (smooth > 0) { + var prevP = points[prevIdx]; + var dim = smoothMonotone === 'y' ? 1 : 0; + + // Length of control point to p, either in x or y, but not both + var ctrlLen = (p[dim] - prevP[dim]) * smooth; + + v2Copy(cp0, prevP); + cp0[dim] = prevP[dim] + ctrlLen; + + v2Copy(cp1, p); + cp1[dim] = p[dim] - ctrlLen; + + ctx.bezierCurveTo( + cp0[0], cp0[1], + cp1[0], cp1[1], + p[0], p[1] + ); + } else { + ctx.lineTo(p[0], p[1]); + } + } + + prevIdx = idx; + idx += dir; + } + + return k; + } + + /** + * Draw smoothed line in non-monotone, in may cause undesired curve in extreme + * situations. This should be used when points are non-monotone neither in x or + * y dimension. + */ + function drawNonMono( + ctx, points, start, segLen, allLen, + dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls + ) { + var prevIdx = 0; + var idx = start; + for (var k = 0; k < segLen; k++) { + var p = points[idx]; + if (idx >= allLen || idx < 0) { + break; + } + if (isPointNull(p)) { + if (connectNulls) { + idx += dir; + continue; + } + break; + } + + if (idx === start) { + ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]); + v2Copy(cp0, p); + } else { + if (smooth > 0) { + var nextIdx = idx + dir; + var nextP = points[nextIdx]; + if (connectNulls) { + // Find next point not null + while (nextP && isPointNull(points[nextIdx])) { + nextIdx += dir; + nextP = points[nextIdx]; + } + } + + var ratioNextSeg = 0.5; + var prevP = points[prevIdx]; + var nextP = points[nextIdx]; + // Last point + if (!nextP || isPointNull(nextP)) { + v2Copy(cp1, p); + } else { + // If next data is null in not connect case + if (isPointNull(nextP) && !connectNulls) { + nextP = p; + } + + sub(v, nextP, prevP); + + var lenPrevSeg; + var lenNextSeg; + if (smoothMonotone === 'x' || smoothMonotone === 'y') { + var dim = smoothMonotone === 'x' ? 0 : 1; + lenPrevSeg = Math.abs(p[dim] - prevP[dim]); + lenNextSeg = Math.abs(p[dim] - nextP[dim]); + } else { + lenPrevSeg = dist(p, prevP); + lenNextSeg = dist(p, nextP); + } + + // Use ratio of seg length + ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg); + + scaleAndAdd$1(cp1, p, v, -smooth * (1 - ratioNextSeg)); + } + // Smooth constraint + vec2Min(cp0, cp0, smoothMax); + vec2Max(cp0, cp0, smoothMin); + vec2Min(cp1, cp1, smoothMax); + vec2Max(cp1, cp1, smoothMin); + + ctx.bezierCurveTo( + cp0[0], cp0[1], + cp1[0], cp1[1], + p[0], p[1] + ); + // cp0 of next segment + scaleAndAdd$1(cp0, p, v, smooth * ratioNextSeg); + } else { + ctx.lineTo(p[0], p[1]); + } + } + + prevIdx = idx; + idx += dir; + } + + return k; + } + + function getBoundingBox(points, smoothConstraint) { + var ptMin = [Infinity, Infinity]; + var ptMax = [-Infinity, -Infinity]; + if (smoothConstraint) { + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + if (pt[0] < ptMin[0]) { + ptMin[0] = pt[0]; + } + if (pt[1] < ptMin[1]) { + ptMin[1] = pt[1]; + } + if (pt[0] > ptMax[0]) { + ptMax[0] = pt[0]; + } + if (pt[1] > ptMax[1]) { + ptMax[1] = pt[1]; + } + } + } + return { + min: smoothConstraint ? ptMin : ptMax, + max: smoothConstraint ? ptMax : ptMin + }; + } + + var Polyline$1 = Path.extend({ + + type: 'ec-polyline', + + shape: { + points: [], + + smooth: 0, + + smoothConstraint: true, + + smoothMonotone: null, + + connectNulls: false + }, + + style: { + fill: null, + + stroke: '#000' + }, + + brush: fixClipWithShadow(Path.prototype.brush), + + buildPath: function(ctx, shape) { + var points = shape.points; + + var i = 0; + var len$$1 = points.length; + + var result = getBoundingBox(points, shape.smoothConstraint); + + if (shape.connectNulls) { + // Must remove first and last null values avoid draw error in polygon + for (; len$$1 > 0; len$$1--) { + if (!isPointNull(points[len$$1 - 1])) { + break; + } + } + for (; i < len$$1; i++) { + if (!isPointNull(points[i])) { + break; + } + } + } + while (i < len$$1) { + i += drawSegment( + ctx, points, i, len$$1, len$$1, + 1, result.min, result.max, shape.smooth, + shape.smoothMonotone, shape.connectNulls + ) + 1; + } + } + }); + + var Polygon$1 = Path.extend({ + + type: 'ec-polygon', + + shape: { + points: [], + + // Offset between stacked base points and points + stackedOnPoints: [], + + smooth: 0, + + stackedOnSmooth: 0, + + smoothConstraint: true, + + smoothMonotone: null, + + connectNulls: false + }, + + brush: fixClipWithShadow(Path.prototype.brush), + + buildPath: function(ctx, shape) { + var points = shape.points; + var stackedOnPoints = shape.stackedOnPoints; + + var i = 0; + var len$$1 = points.length; + var smoothMonotone = shape.smoothMonotone; + var bbox = getBoundingBox(points, shape.smoothConstraint); + var stackedOnBBox = getBoundingBox(stackedOnPoints, shape.smoothConstraint); + + if (shape.connectNulls) { + // Must remove first and last null values avoid draw error in polygon + for (; len$$1 > 0; len$$1--) { + if (!isPointNull(points[len$$1 - 1])) { + break; + } + } + for (; i < len$$1; i++) { + if (!isPointNull(points[i])) { + break; + } + } + } + while (i < len$$1) { + var k = drawSegment( + ctx, points, i, len$$1, len$$1, + 1, bbox.min, bbox.max, shape.smooth, + smoothMonotone, shape.connectNulls + ); + drawSegment( + ctx, stackedOnPoints, i + k - 1, k, len$$1, + -1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth, + smoothMonotone, shape.connectNulls + ); + i += k + 1; + + ctx.closePath(); + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME step not support polar + + function isPointsSame(points1, points2) { + if (points1.length !== points2.length) { + return; + } + for (var i = 0; i < points1.length; i++) { + var p1 = points1[i]; + var p2 = points2[i]; + if (p1[0] !== p2[0] || p1[1] !== p2[1]) { + return; + } + } + return true; + } + + function getSmooth(smooth) { + return typeof(smooth) === 'number' ? smooth : (smooth ? 0.5 : 0); + } + + function getAxisExtentWithGap(axis) { + var extent = axis.getGlobalExtent(); + if (axis.onBand) { + // Remove extra 1px to avoid line miter in clipped edge + var halfBandWidth = axis.getBandWidth() / 2 - 1; + var dir = extent[1] > extent[0] ? 1 : -1; + extent[0] += dir * halfBandWidth; + extent[1] -= dir * halfBandWidth; + } + return extent; + } + + /** + * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys + * @param {module:echarts/data/List} data + * @param {Object} dataCoordInfo + * @param {Array.>} points + */ + function getStackedOnPoints(coordSys, data, dataCoordInfo) { + if (!dataCoordInfo.valueDim) { + return []; + } + + var points = []; + for (var idx = 0, len = data.count(); idx < len; idx++) { + points.push(getStackedOnPoint(dataCoordInfo, coordSys, data, idx)); + } + + return points; + } + + function createGridClipShape(cartesian, hasAnimation, forSymbol, seriesModel) { + var xExtent = getAxisExtentWithGap(cartesian.getAxis('x')); + var yExtent = getAxisExtentWithGap(cartesian.getAxis('y')); + var isHorizontal = cartesian.getBaseAxis().isHorizontal(); + + var x = Math.min(xExtent[0], xExtent[1]); + var y = Math.min(yExtent[0], yExtent[1]); + var width = Math.max(xExtent[0], xExtent[1]) - x; + var height = Math.max(yExtent[0], yExtent[1]) - y; + + // Avoid float number rounding error for symbol on the edge of axis extent. + // See #7913 and `test/dataZoom-clip.html`. + if (forSymbol) { + x -= 0.5; + width += 0.5; + y -= 0.5; + height += 0.5; + } else { + var lineWidth = seriesModel.get('lineStyle.width') || 2; + // Expand clip shape to avoid clipping when line value exceeds axis + var expandSize = seriesModel.get('clipOverflow') ? lineWidth / 2 : Math.max(width, height); + if (isHorizontal) { + y -= expandSize; + height += expandSize * 2; + } else { + x -= expandSize; + width += expandSize * 2; + } + } + + var clipPath = new Rect({ + shape: { + x: x, + y: y, + width: width, + height: height + } + }); + + if (hasAnimation) { + clipPath.shape[isHorizontal ? 'width' : 'height'] = 0; + initProps(clipPath, { + shape: { + width: width, + height: height + } + }, seriesModel); + } + + return clipPath; + } + + function createPolarClipShape(polar, hasAnimation, forSymbol, seriesModel) { + var angleAxis = polar.getAngleAxis(); + var radiusAxis = polar.getRadiusAxis(); + + var radiusExtent = radiusAxis.getExtent().slice(); + radiusExtent[0] > radiusExtent[1] && radiusExtent.reverse(); + var angleExtent = angleAxis.getExtent(); + + var RADIAN = Math.PI / 180; + + // Avoid float number rounding error for symbol on the edge of axis extent. + if (forSymbol) { + radiusExtent[0] -= 0.5; + radiusExtent[1] += 0.5; + } + + var clipPath = new Sector({ + shape: { + cx: round$1(polar.cx, 1), + cy: round$1(polar.cy, 1), + r0: round$1(radiusExtent[0], 1), + r: round$1(radiusExtent[1], 1), + startAngle: -angleExtent[0] * RADIAN, + endAngle: -angleExtent[1] * RADIAN, + clockwise: angleAxis.inverse + } + }); + + if (hasAnimation) { + clipPath.shape.endAngle = -angleExtent[0] * RADIAN; + initProps(clipPath, { + shape: { + endAngle: -angleExtent[1] * RADIAN + } + }, seriesModel); + } + + return clipPath; + } + + function createClipShape(coordSys, hasAnimation, forSymbol, seriesModel) { + return coordSys.type === 'polar' ? + createPolarClipShape(coordSys, hasAnimation, forSymbol, seriesModel) : + createGridClipShape(coordSys, hasAnimation, forSymbol, seriesModel); + } + + function turnPointsIntoStep(points, coordSys, stepTurnAt) { + var baseAxis = coordSys.getBaseAxis(); + var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1; + + var stepPoints = []; + for (var i = 0; i < points.length - 1; i++) { + var nextPt = points[i + 1]; + var pt = points[i]; + stepPoints.push(pt); + + var stepPt = []; + switch (stepTurnAt) { + case 'end': + stepPt[baseIndex] = nextPt[baseIndex]; + stepPt[1 - baseIndex] = pt[1 - baseIndex]; + // default is start + stepPoints.push(stepPt); + break; + case 'middle': + // default is start + var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2; + var stepPt2 = []; + stepPt[baseIndex] = stepPt2[baseIndex] = middle; + stepPt[1 - baseIndex] = pt[1 - baseIndex]; + stepPt2[1 - baseIndex] = nextPt[1 - baseIndex]; + stepPoints.push(stepPt); + stepPoints.push(stepPt2); + break; + default: + stepPt[baseIndex] = pt[baseIndex]; + stepPt[1 - baseIndex] = nextPt[1 - baseIndex]; + // default is start + stepPoints.push(stepPt); + } + } + // Last points + points[i] && stepPoints.push(points[i]); + return stepPoints; + } + + function getVisualGradient(data, coordSys) { + var visualMetaList = data.getVisual('visualMeta'); + if (!visualMetaList || !visualMetaList.length || !data.count()) { + // When data.count() is 0, gradient range can not be calculated. + return; + } + + if (coordSys.type !== 'cartesian2d') { + if (__DEV__) { + console.warn('Visual map on line style is only supported on cartesian2d.'); + } + return; + } + + var coordDim; + var visualMeta; + + for (var i = visualMetaList.length - 1; i >= 0; i--) { + var dimIndex = visualMetaList[i].dimension; + var dimName = data.dimensions[dimIndex]; + var dimInfo = data.getDimensionInfo(dimName); + coordDim = dimInfo && dimInfo.coordDim; + // Can only be x or y + if (coordDim === 'x' || coordDim === 'y') { + visualMeta = visualMetaList[i]; + break; + } + } + + if (!visualMeta) { + if (__DEV__) { + console.warn('Visual map on line style only support x or y dimension.'); + } + return; + } + + // If the area to be rendered is bigger than area defined by LinearGradient, + // the canvas spec prescribes that the color of the first stop and the last + // stop should be used. But if two stops are added at offset 0, in effect + // browsers use the color of the second stop to render area outside + // LinearGradient. So we can only infinitesimally extend area defined in + // LinearGradient to render `outerColors`. + + var axis = coordSys.getAxis(coordDim); + + // dataToCoor mapping may not be linear, but must be monotonic. + var colorStops = map(visualMeta.stops, function(stop) { + return { + coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)), + color: stop.color + }; + }); + var stopLen = colorStops.length; + var outerColors = visualMeta.outerColors.slice(); + + if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) { + colorStops.reverse(); + outerColors.reverse(); + } + + var tinyExtent = 10; // Arbitrary value: 10px + var minCoord = colorStops[0].coord - tinyExtent; + var maxCoord = colorStops[stopLen - 1].coord + tinyExtent; + var coordSpan = maxCoord - minCoord; + + if (coordSpan < 1e-3) { + return 'transparent'; + } + + each$1(colorStops, function(stop) { + stop.offset = (stop.coord - minCoord) / coordSpan; + }); + colorStops.push({ + offset: stopLen ? colorStops[stopLen - 1].offset : 0.5, + color: outerColors[1] || 'transparent' + }); + colorStops.unshift({ // notice colorStops.length have been changed. + offset: stopLen ? colorStops[0].offset : 0.5, + color: outerColors[0] || 'transparent' + }); + + // zrUtil.each(colorStops, function (colorStop) { + // // Make sure each offset has rounded px to avoid not sharp edge + // colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start); + // }); + + var gradient = new LinearGradient(0, 0, 0, 0, colorStops, true); + gradient[coordDim] = minCoord; + gradient[coordDim + '2'] = maxCoord; + + return gradient; + } + + function getIsIgnoreFunc(seriesModel, data, coordSys) { + var showAllSymbol = seriesModel.get('showAllSymbol'); + var isAuto = showAllSymbol === 'auto'; + + if (showAllSymbol && !isAuto) { + return; + } + + var categoryAxis = coordSys.getAxesByScale('ordinal')[0]; + if (!categoryAxis) { + return; + } + + // Note that category label interval strategy might bring some weird effect + // in some scenario: users may wonder why some of the symbols are not + // displayed. So we show all symbols as possible as we can. + if (isAuto + // Simplify the logic, do not determine label overlap here. + && + canShowAllSymbolForCategory(categoryAxis, data) + ) { + return; + } + + // Otherwise follow the label interval strategy on category axis. + var categoryDataDim = data.mapDimension(categoryAxis.dim); + var labelMap = {}; + + each$1(categoryAxis.getViewLabels(), function(labelItem) { + labelMap[labelItem.tickValue] = 1; + }); + + return function(dataIndex) { + return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex)); + }; + } + + function canShowAllSymbolForCategory(categoryAxis, data) { + // In mose cases, line is monotonous on category axis, and the label size + // is close with each other. So we check the symbol size and some of the + // label size alone with the category axis to estimate whether all symbol + // can be shown without overlap. + var axisExtent = categoryAxis.getExtent(); + var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count(); + isNaN(availSize) && (availSize = 0); // 0/0 is NaN. + + // Sampling some points, max 5. + var dataLen = data.count(); + var step = Math.max(1, Math.round(dataLen / 5)); + for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) { + if (SymbolClz$1.getSymbolSize( + data, dataIndex + // Only for cartesian, where `isHorizontal` exists. + )[categoryAxis.isHorizontal() ? 1 : 0] + // Empirical number + * + 1.5 > availSize + ) { + return false; + } + } + + return true; + } + + Chart.extend({ + + type: 'line', + + init: function() { + var lineGroup = new Group(); + + var symbolDraw = new SymbolDraw(); + this.group.add(symbolDraw.group); + + this._symbolDraw = symbolDraw; + this._lineGroup = lineGroup; + }, + + render: function(seriesModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var group = this.group; + var data = seriesModel.getData(); + var lineStyleModel = seriesModel.getModel('lineStyle'); + var areaStyleModel = seriesModel.getModel('areaStyle'); + + var points = data.mapArray(data.getItemLayout); + + var isCoordSysPolar = coordSys.type === 'polar'; + var prevCoordSys = this._coordSys; + + var symbolDraw = this._symbolDraw; + var polyline = this._polyline; + var polygon = this._polygon; + + var lineGroup = this._lineGroup; + + var hasAnimation = seriesModel.get('animation'); + + var isAreaChart = !areaStyleModel.isEmpty(); + + var valueOrigin = areaStyleModel.get('origin'); + var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin); + + var stackedOnPoints = getStackedOnPoints(coordSys, data, dataCoordInfo); + + var showSymbol = seriesModel.get('showSymbol'); + + var isIgnoreFunc = showSymbol && !isCoordSysPolar && + getIsIgnoreFunc(seriesModel, data, coordSys); + + // Remove temporary symbols + var oldData = this._data; + oldData && oldData.eachItemGraphicEl(function(el, idx) { + if (el.__temp) { + group.remove(el); + oldData.setItemGraphicEl(idx, null); + } + }); + + // Remove previous created symbols if showSymbol changed to false + if (!showSymbol) { + symbolDraw.remove(); + } + + group.add(lineGroup); + + // FIXME step not support polar + var step = !isCoordSysPolar && seriesModel.get('step'); + // Initialization animation or coordinate system changed + if ( + !(polyline && prevCoordSys.type === coordSys.type && step === this._step) + ) { + showSymbol && symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: createClipShape(coordSys, false, true, seriesModel) + }); + + if (step) { + // TODO If stacked series is not step + points = turnPointsIntoStep(points, coordSys, step); + stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step); + } + + polyline = this._newPolyline(points, coordSys, hasAnimation); + if (isAreaChart) { + polygon = this._newPolygon( + points, stackedOnPoints, + coordSys, hasAnimation + ); + } + lineGroup.setClipPath(createClipShape(coordSys, true, false, seriesModel)); + } else { + if (isAreaChart && !polygon) { + // If areaStyle is added + polygon = this._newPolygon( + points, stackedOnPoints, + coordSys, hasAnimation + ); + } else if (polygon && !isAreaChart) { + // If areaStyle is removed + lineGroup.remove(polygon); + polygon = this._polygon = null; + } + + // Update clipPath + lineGroup.setClipPath(createClipShape(coordSys, false, false, seriesModel)); + + // Always update, or it is wrong in the case turning on legend + // because points are not changed + showSymbol && symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: createClipShape(coordSys, false, true, seriesModel) + }); + + // Stop symbol animation and sync with line points + // FIXME performance? + data.eachItemGraphicEl(function(el) { + el.stopAnimation(true); + }); + + // In the case data zoom triggerred refreshing frequently + // Data may not change if line has a category axis. So it should animate nothing + if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || + !isPointsSame(this._points, points) + ) { + if (hasAnimation) { + this._updateAnimation( + data, stackedOnPoints, coordSys, api, step, valueOrigin + ); + } else { + // Not do it in update with animation + if (step) { + // TODO If stacked series is not step + points = turnPointsIntoStep(points, coordSys, step); + stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step); + } + + polyline.setShape({ + points: points + }); + polygon && polygon.setShape({ + points: points, + stackedOnPoints: stackedOnPoints + }); + } + } + } + + var visualColor = getVisualGradient(data, coordSys) || data.getVisual('color'); + + polyline.useStyle(defaults( + // Use color in lineStyle first + lineStyleModel.getLineStyle(), { + fill: 'none', + stroke: visualColor, + lineJoin: 'bevel' + } + )); + + var smooth = seriesModel.get('smooth'); + smooth = getSmooth(seriesModel.get('smooth')); + polyline.setShape({ + smooth: smooth, + smoothMonotone: seriesModel.get('smoothMonotone'), + connectNulls: seriesModel.get('connectNulls') + }); + + if (polygon) { + var stackedOnSeries = data.getCalculationInfo('stackedOnSeries'); + var stackedOnSmooth = 0; + + polygon.useStyle(defaults( + areaStyleModel.getAreaStyle(), { + fill: visualColor, + opacity: 0.7, + lineJoin: 'bevel' + } + )); + + if (stackedOnSeries) { + stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth')); + } + + polygon.setShape({ + smooth: smooth, + stackedOnSmooth: stackedOnSmooth, + smoothMonotone: seriesModel.get('smoothMonotone'), + connectNulls: seriesModel.get('connectNulls') + }); + } + + this._data = data; + // Save the coordinate system for transition animation when data changed + this._coordSys = coordSys; + this._stackedOnPoints = stackedOnPoints; + this._points = points; + this._step = step; + this._valueOrigin = valueOrigin; + }, + + dispose: function() {}, + + highlight: function(seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, payload); + + if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) { + var symbol = data.getItemGraphicEl(dataIndex); + if (!symbol) { + // Create a temporary symbol if it is not exists + var pt = data.getItemLayout(dataIndex); + if (!pt) { + // Null data + return; + } + symbol = new SymbolClz$1(data, dataIndex); + symbol.position = pt; + symbol.setZ( + seriesModel.get('zlevel'), + seriesModel.get('z') + ); + symbol.ignore = isNaN(pt[0]) || isNaN(pt[1]); + symbol.__temp = true; + data.setItemGraphicEl(dataIndex, symbol); + + // Stop scale animation + symbol.stopSymbolAnimation(true); + + this.group.add(symbol); + } + symbol.highlight(); + } else { + // Highlight whole series + Chart.prototype.highlight.call( + this, seriesModel, ecModel, api, payload + ); + } + }, + + downplay: function(seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, payload); + if (dataIndex != null && dataIndex >= 0) { + var symbol = data.getItemGraphicEl(dataIndex); + if (symbol) { + if (symbol.__temp) { + data.setItemGraphicEl(dataIndex, null); + this.group.remove(symbol); + } else { + symbol.downplay(); + } + } + } else { + // FIXME + // can not downplay completely. + // Downplay whole series + Chart.prototype.downplay.call( + this, seriesModel, ecModel, api, payload + ); + } + }, + + /** + * @param {module:zrender/container/Group} group + * @param {Array.>} points + * @private + */ + _newPolyline: function(points) { + var polyline = this._polyline; + // Remove previous created polyline + if (polyline) { + this._lineGroup.remove(polyline); + } + + polyline = new Polyline$1({ + shape: { + points: points + }, + silent: true, + z2: 10 + }); + + this._lineGroup.add(polyline); + + this._polyline = polyline; + + return polyline; + }, + + /** + * @param {module:zrender/container/Group} group + * @param {Array.>} stackedOnPoints + * @param {Array.>} points + * @private + */ + _newPolygon: function(points, stackedOnPoints) { + var polygon = this._polygon; + // Remove previous created polygon + if (polygon) { + this._lineGroup.remove(polygon); + } + + polygon = new Polygon$1({ + shape: { + points: points, + stackedOnPoints: stackedOnPoints + }, + silent: true + }); + + this._lineGroup.add(polygon); + + this._polygon = polygon; + return polygon; + }, + + /** + * @private + */ + // FIXME Two value axis + _updateAnimation: function(data, stackedOnPoints, coordSys, api, step, valueOrigin) { + var polyline = this._polyline; + var polygon = this._polygon; + var seriesModel = data.hostModel; + + var diff = lineAnimationDiff( + this._data, data, + this._stackedOnPoints, stackedOnPoints, + this._coordSys, coordSys, + this._valueOrigin, valueOrigin + ); + + var current = diff.current; + var stackedOnCurrent = diff.stackedOnCurrent; + var next = diff.next; + var stackedOnNext = diff.stackedOnNext; + if (step) { + // TODO If stacked series is not step + current = turnPointsIntoStep(diff.current, coordSys, step); + stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step); + next = turnPointsIntoStep(diff.next, coordSys, step); + stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step); + } + // `diff.current` is subset of `current` (which should be ensured by + // turnPointsIntoStep), so points in `__points` can be updated when + // points in `current` are update during animation. + polyline.shape.__points = diff.current; + polyline.shape.points = current; + + updateProps(polyline, { + shape: { + points: next + } + }, seriesModel); + + if (polygon) { + polygon.setShape({ + points: current, + stackedOnPoints: stackedOnCurrent + }); + updateProps(polygon, { + shape: { + points: next, + stackedOnPoints: stackedOnNext + } + }, seriesModel); + } + + var updatedDataInfo = []; + var diffStatus = diff.status; + + for (var i = 0; i < diffStatus.length; i++) { + var cmd = diffStatus[i].cmd; + if (cmd === '=') { + var el = data.getItemGraphicEl(diffStatus[i].idx1); + if (el) { + updatedDataInfo.push({ + el: el, + ptIdx: i // Index of points + }); + } + } + } + + if (polyline.animators && polyline.animators.length) { + polyline.animators[0].during(function() { + for (var i = 0; i < updatedDataInfo.length; i++) { + var el = updatedDataInfo[i].el; + el.attr('position', polyline.shape.__points[updatedDataInfo[i].ptIdx]); + } + }); + } + }, + + remove: function(ecModel) { + var group = this.group; + var oldData = this._data; + this._lineGroup.removeAll(); + this._symbolDraw.remove(true); + // Remove temporary created elements when highlighting + oldData && oldData.eachItemGraphicEl(function(el, idx) { + if (el.__temp) { + group.remove(el); + oldData.setItemGraphicEl(idx, null); + } + }); + + this._polyline = + this._polygon = + this._coordSys = + this._points = + this._stackedOnPoints = + this._data = null; + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var visualSymbol = function(seriesType, defaultSymbolType, legendSymbol) { + // Encoding visual for all series include which is filtered for legend drawing + return { + seriesType: seriesType, + + // For legend. + performRawSeries: true, + + reset: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + var symbolType = seriesModel.get('symbol') || defaultSymbolType; + var symbolSize = seriesModel.get('symbolSize'); + var keepAspect = seriesModel.get('symbolKeepAspect'); + + data.setVisual({ + legendSymbol: legendSymbol || symbolType, + symbol: symbolType, + symbolSize: symbolSize, + symbolKeepAspect: keepAspect + }); + + // Only visible series has each data be visual encoded + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + + var hasCallback = typeof symbolSize === 'function'; + + function dataEach(data, idx) { + if (typeof symbolSize === 'function') { + var rawValue = seriesModel.getRawValue(idx); + // FIXME + var params = seriesModel.getDataParams(idx); + data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params)); + } + + if (data.hasItemOption) { + var itemModel = data.getItemModel(idx); + var itemSymbolType = itemModel.getShallow('symbol', true); + var itemSymbolSize = itemModel.getShallow('symbolSize', + true); + var itemSymbolKeepAspect = + itemModel.getShallow('symbolKeepAspect', true); + + // If has item symbol + if (itemSymbolType != null) { + data.setItemVisual(idx, 'symbol', itemSymbolType); + } + if (itemSymbolSize != null) { + // PENDING Transform symbolSize ? + data.setItemVisual(idx, 'symbolSize', itemSymbolSize); + } + if (itemSymbolKeepAspect != null) { + data.setItemVisual(idx, 'symbolKeepAspect', + itemSymbolKeepAspect); + } + } + } + + return { + dataEach: (data.hasItemOption || hasCallback) ? dataEach : null + }; + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var pointsLayout = function(seriesType) { + return { + seriesType: seriesType, + + plan: createRenderPlanner(), + + reset: function(seriesModel) { + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var pipelineContext = seriesModel.pipelineContext; + var isLargeRender = pipelineContext.large; + + if (!coordSys) { + return; + } + + var dims = map(coordSys.dimensions, function(dim) { + return data.mapDimension(dim); + }).slice(0, 2); + var dimLen = dims.length; + + var stackResultDim = data.getCalculationInfo('stackResultDimension'); + if (isDimensionStacked(data, dims[0] /*, dims[1]*/ )) { + dims[0] = stackResultDim; + } + if (isDimensionStacked(data, dims[1] /*, dims[0]*/ )) { + dims[1] = stackResultDim; + } + + function progress(params, data) { + var segCount = params.end - params.start; + var points = isLargeRender && new Float32Array(segCount * dimLen); + + for (var i = params.start, offset = 0, tmpIn = [], tmpOut = []; i < params.end; i++) { + var point; + + if (dimLen === 1) { + var x = data.get(dims[0], i); + point = !isNaN(x) && coordSys.dataToPoint(x, null, tmpOut); + } else { + var x = tmpIn[0] = data.get(dims[0], i); + var y = tmpIn[1] = data.get(dims[1], i); + // Also {Array.}, not undefined to avoid if...else... statement + point = !isNaN(x) && !isNaN(y) && coordSys.dataToPoint(tmpIn, null, tmpOut); + } + + if (isLargeRender) { + points[offset++] = point ? point[0] : NaN; + points[offset++] = point ? point[1] : NaN; + } else { + data.setItemLayout(i, (point && point.slice()) || [NaN, NaN]); + } + } + + isLargeRender && data.setLayout('symbolPoints', points); + } + + return dimLen && { + progress: progress + }; + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var samplers = { + average: function(frame) { + var sum = 0; + var count = 0; + for (var i = 0; i < frame.length; i++) { + if (!isNaN(frame[i])) { + sum += frame[i]; + count++; + } + } + // Return NaN if count is 0 + return count === 0 ? NaN : sum / count; + }, + sum: function(frame) { + var sum = 0; + for (var i = 0; i < frame.length; i++) { + // Ignore NaN + sum += frame[i] || 0; + } + return sum; + }, + max: function(frame) { + var max = -Infinity; + for (var i = 0; i < frame.length; i++) { + frame[i] > max && (max = frame[i]); + } + // NaN will cause illegal axis extent. + return isFinite(max) ? max : NaN; + }, + min: function(frame) { + var min = Infinity; + for (var i = 0; i < frame.length; i++) { + frame[i] < min && (min = frame[i]); + } + // NaN will cause illegal axis extent. + return isFinite(min) ? min : NaN; + }, + // TODO + // Median + nearest: function(frame) { + return frame[0]; + } + }; + + var indexSampler = function(frame, value) { + return Math.round(frame.length / 2); + }; + + var dataSample = function(seriesType) { + return { + + seriesType: seriesType, + + modifyOutputEnd: true, + + reset: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var sampling = seriesModel.get('sampling'); + var coordSys = seriesModel.coordinateSystem; + // Only cartesian2d support down sampling + if (coordSys.type === 'cartesian2d' && sampling) { + var baseAxis = coordSys.getBaseAxis(); + var valueAxis = coordSys.getOtherAxis(baseAxis); + var extent = baseAxis.getExtent(); + // Coordinste system has been resized + var size = extent[1] - extent[0]; + var rate = Math.round(data.count() / size); + if (rate > 1) { + var sampler; + if (typeof sampling === 'string') { + sampler = samplers[sampling]; + } else if (typeof sampling === 'function') { + sampler = sampling; + } + if (sampler) { + // Only support sample the first dim mapped from value axis. + seriesModel.setData(data.downSample( + data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler + )); + } + } + } + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Cartesian coordinate system + * @module echarts/coord/Cartesian + * + */ + + function dimAxisMapper(dim) { + return this._axes[dim]; + } + + /** + * @alias module:echarts/coord/Cartesian + * @constructor + */ + var Cartesian = function(name) { + this._axes = {}; + + this._dimList = []; + + /** + * @type {string} + */ + this.name = name || ''; + }; + + Cartesian.prototype = { + + constructor: Cartesian, + + type: 'cartesian', + + /** + * Get axis + * @param {number|string} dim + * @return {module:echarts/coord/Cartesian~Axis} + */ + getAxis: function(dim) { + return this._axes[dim]; + }, + + /** + * Get axes list + * @return {Array.} + */ + getAxes: function() { + return map(this._dimList, dimAxisMapper, this); + }, + + /** + * Get axes list by given scale type + */ + getAxesByScale: function(scaleType) { + scaleType = scaleType.toLowerCase(); + return filter( + this.getAxes(), + function(axis) { + return axis.scale.type === scaleType; + } + ); + }, + + /** + * Add axis + * @param {module:echarts/coord/Cartesian.Axis} + */ + addAxis: function(axis) { + var dim = axis.dim; + + this._axes[dim] = axis; + + this._dimList.push(dim); + }, + + /** + * Convert data to coord in nd space + * @param {Array.|Object.} val + * @return {Array.|Object.} + */ + dataToCoord: function(val) { + return this._dataCoordConvert(val, 'dataToCoord'); + }, + + /** + * Convert coord in nd space to data + * @param {Array.|Object.} val + * @return {Array.|Object.} + */ + coordToData: function(val) { + return this._dataCoordConvert(val, 'coordToData'); + }, + + _dataCoordConvert: function(input, method) { + var dimList = this._dimList; + + var output = input instanceof Array ? [] : {}; + + for (var i = 0; i < dimList.length; i++) { + var dim = dimList[i]; + var axis = this._axes[dim]; + + output[dim] = axis[method](input[dim]); + } + + return output; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + function Cartesian2D(name) { + + Cartesian.call(this, name); + } + + Cartesian2D.prototype = { + + constructor: Cartesian2D, + + type: 'cartesian2d', + + /** + * @type {Array.} + * @readOnly + */ + dimensions: ['x', 'y'], + + /** + * Base axis will be used on stacking. + * + * @return {module:echarts/coord/cartesian/Axis2D} + */ + getBaseAxis: function() { + return this.getAxesByScale('ordinal')[0] || + this.getAxesByScale('time')[0] || + this.getAxis('x'); + }, + + /** + * If contain point + * @param {Array.} point + * @return {boolean} + */ + containPoint: function(point) { + var axisX = this.getAxis('x'); + var axisY = this.getAxis('y'); + return axisX.contain(axisX.toLocalCoord(point[0])) && + axisY.contain(axisY.toLocalCoord(point[1])); + }, + + /** + * If contain data + * @param {Array.} data + * @return {boolean} + */ + containData: function(data) { + return this.getAxis('x').containData(data[0]) && + this.getAxis('y').containData(data[1]); + }, + + /** + * @param {Array.} data + * @param {Array.} out + * @return {Array.} + */ + dataToPoint: function(data, reserved, out) { + var xAxis = this.getAxis('x'); + var yAxis = this.getAxis('y'); + out = out || []; + out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(data[0])); + out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(data[1])); + return out; + }, + + /** + * @param {Array.} data + * @param {Array.} out + * @return {Array.} + */ + clampData: function(data, out) { + var xScale = this.getAxis('x').scale; + var yScale = this.getAxis('y').scale; + var xAxisExtent = xScale.getExtent(); + var yAxisExtent = yScale.getExtent(); + var x = xScale.parse(data[0]); + var y = yScale.parse(data[1]); + out = out || []; + out[0] = Math.min( + Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x), + Math.max(xAxisExtent[0], xAxisExtent[1]) + ); + out[1] = Math.min( + Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y), + Math.max(yAxisExtent[0], yAxisExtent[1]) + ); + + return out; + }, + + /** + * @param {Array.} point + * @param {Array.} out + * @return {Array.} + */ + pointToData: function(point, out) { + var xAxis = this.getAxis('x'); + var yAxis = this.getAxis('y'); + out = out || []; + out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0])); + out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1])); + return out; + }, + + /** + * Get other axis + * @param {module:echarts/coord/cartesian/Axis2D} axis + */ + getOtherAxis: function(axis) { + return this.getAxis(axis.dim === 'x' ? 'y' : 'x'); + } + + }; + + inherits(Cartesian2D, Cartesian); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Extend axis 2d + * @constructor module:echarts/coord/cartesian/Axis2D + * @extends {module:echarts/coord/cartesian/Axis} + * @param {string} dim + * @param {*} scale + * @param {Array.} coordExtent + * @param {string} axisType + * @param {string} position + */ + var Axis2D = function(dim, scale, coordExtent, axisType, position) { + Axis.call(this, dim, scale, coordExtent); + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = axisType || 'value'; + + /** + * Axis position + * - 'top' + * - 'bottom' + * - 'left' + * - 'right' + */ + this.position = position || 'bottom'; + }; + + Axis2D.prototype = { + + constructor: Axis2D, + + /** + * Index of axis, can be used as key + */ + index: 0, + + /** + * Implemented in . + * @return {Array.} + * If not on zero of other axis, return null/undefined. + * If no axes, return an empty array. + */ + getAxesOnZeroOf: null, + + /** + * Axis model + * @param {module:echarts/coord/cartesian/AxisModel} + */ + model: null, + + isHorizontal: function() { + var position = this.position; + return position === 'top' || position === 'bottom'; + }, + + /** + * Each item cooresponds to this.getExtent(), which + * means globalExtent[0] may greater than globalExtent[1], + * unless `asc` is input. + * + * @param {boolean} [asc] + * @return {Array.} + */ + getGlobalExtent: function(asc) { + var ret = this.getExtent(); + ret[0] = this.toGlobalCoord(ret[0]); + ret[1] = this.toGlobalCoord(ret[1]); + asc && ret[0] > ret[1] && ret.reverse(); + return ret; + }, + + getOtherAxis: function() { + this.grid.getOtherAxis(); + }, + + /** + * @override + */ + pointToData: function(point, clamp) { + return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp); + }, + + /** + * Transform global coord to local coord, + * i.e. var localCoord = axis.toLocalCoord(80); + * designate by module:echarts/coord/cartesian/Grid. + * @type {Function} + */ + toLocalCoord: null, + + /** + * Transform global coord to local coord, + * i.e. var globalCoord = axis.toLocalCoord(40); + * designate by module:echarts/coord/cartesian/Grid. + * @type {Function} + */ + toGlobalCoord: null + + }; + + inherits(Axis2D, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var defaultOption = { + show: true, + zlevel: 0, + z: 0, + // Inverse the axis. + inverse: false, + + // Axis name displayed. + name: '', + // 'start' | 'middle' | 'end' + nameLocation: 'end', + // By degree. By defualt auto rotate by nameLocation. + nameRotate: null, + nameTruncate: { + maxWidth: null, + ellipsis: '...', + placeholder: '.' + }, + // Use global text style by default. + nameTextStyle: {}, + // The gap between axisName and axisLine. + nameGap: 15, + + // Default `false` to support tooltip. + silent: false, + // Default `false` to avoid legacy user event listener fail. + triggerEvent: false, + + tooltip: { + show: false + }, + + axisPointer: {}, + + axisLine: { + show: true, + onZero: true, + onZeroAxisIndex: null, + lineStyle: { + color: '#333', + width: 1, + type: 'solid' + }, + // The arrow at both ends the the axis. + symbol: ['none', 'none'], + symbolSize: [10, 15] + }, + axisTick: { + show: true, + // Whether axisTick is inside the grid or outside the grid. + inside: false, + // The length of axisTick. + length: 5, + lineStyle: { + width: 1 + } + }, + axisLabel: { + show: true, + // Whether axisLabel is inside the grid or outside the grid. + inside: false, + rotate: 0, + // true | false | null/undefined (auto) + showMinLabel: null, + // true | false | null/undefined (auto) + showMaxLabel: null, + margin: 8, + // formatter: null, + fontSize: 12 + }, + splitLine: { + show: true, + lineStyle: { + color: ['#ccc'], + width: 1, + type: 'solid' + } + }, + splitArea: { + show: false, + areaStyle: { + color: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'] + } + } + }; + + var axisDefault = {}; + + axisDefault.categoryAxis = merge({ + // The gap at both ends of the axis. For categoryAxis, boolean. + boundaryGap: true, + // Set false to faster category collection. + // Only usefull in the case like: category is + // ['2012-01-01', '2012-01-02', ...], where the input + // data has been ensured not duplicate and is large data. + // null means "auto": + // if axis.data provided, do not deduplication, + // else do deduplication. + deduplication: null, + // splitArea: { + // show: false + // }, + splitLine: { + show: false + }, + axisTick: { + // If tick is align with label when boundaryGap is true + alignWithLabel: false, + interval: 'auto' + }, + axisLabel: { + interval: 'auto' + } + }, defaultOption); + + axisDefault.valueAxis = merge({ + // The gap at both ends of the axis. For value axis, [GAP, GAP], where + // `GAP` can be an absolute pixel number (like `35`), or percent (like `'30%'`) + boundaryGap: [0, 0], + + // TODO + // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60] + + // Min value of the axis. can be: + // + a number + // + 'dataMin': use the min value in data. + // + null/undefined: auto decide min value (consider pretty look and boundaryGap). + // min: null, + + // Max value of the axis. can be: + // + a number + // + 'dataMax': use the max value in data. + // + null/undefined: auto decide max value (consider pretty look and boundaryGap). + // max: null, + + // Readonly prop, specifies start value of the range when using data zoom. + // rangeStart: null + + // Readonly prop, specifies end value of the range when using data zoom. + // rangeEnd: null + + // Optional value can be: + // + `false`: always include value 0. + // + `true`: the extent do not consider value 0. + // scale: false, + + // AxisTick and axisLabel and splitLine are caculated based on splitNumber. + splitNumber: 5 + + // Interval specifies the span of the ticks is mandatorily. + // interval: null + + // Specify min interval when auto calculate tick interval. + // minInterval: null + + // Specify max interval when auto calculate tick interval. + // maxInterval: null + + }, defaultOption); + + axisDefault.timeAxis = defaults({ + scale: true, + min: 'dataMin', + max: 'dataMax' + }, axisDefault.valueAxis); + + axisDefault.logAxis = defaults({ + scale: true, + logBase: 10 + }, axisDefault.valueAxis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME axisType is fixed ? + var AXIS_TYPES = ['value', 'category', 'time', 'log']; + + /** + * Generate sub axis model class + * @param {string} axisName 'x' 'y' 'radius' 'angle' 'parallel' + * @param {module:echarts/model/Component} BaseAxisModelClass + * @param {Function} axisTypeDefaulter + * @param {Object} [extraDefaultOption] + */ + var axisModelCreator = function(axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) { + + each$1(AXIS_TYPES, function(axisType) { + + BaseAxisModelClass.extend({ + + /** + * @readOnly + */ + type: axisName + 'Axis.' + axisType, + + mergeDefaultAndTheme: function(option, ecModel) { + var layoutMode = this.layoutMode; + var inputPositionParams = layoutMode ? + getLayoutParams(option) : {}; + + var themeModel = ecModel.getTheme(); + merge(option, themeModel.get(axisType + 'Axis')); + merge(option, this.getDefaultOption()); + + option.type = axisTypeDefaulter(axisName, option); + + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }, + + /** + * @override + */ + optionUpdated: function() { + var thisOption = this.option; + if (thisOption.type === 'category') { + this.__ordinalMeta = OrdinalMeta.createByAxisModel(this); + } + }, + + /** + * Should not be called before all of 'getInitailData' finished. + * Because categories are collected during initializing data. + */ + getCategories: function(rawData) { + var option = this.option; + // FIXME + // warning if called before all of 'getInitailData' finished. + if (option.type === 'category') { + if (rawData) { + return option.data; + } + return this.__ordinalMeta.categories; + } + }, + + getOrdinalMeta: function() { + return this.__ordinalMeta; + }, + + defaultOption: mergeAll( + [{}, + axisDefault[axisType + 'Axis'], + extraDefaultOption + ], + true + ) + }); + }); + + ComponentModel.registerSubTypeDefaulter( + axisName + 'Axis', + curry(axisTypeDefaulter, axisName) + ); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AxisModel = ComponentModel.extend({ + + type: 'cartesian2dAxis', + + /** + * @type {module:echarts/coord/cartesian/Axis2D} + */ + axis: null, + + /** + * @override + */ + init: function() { + AxisModel.superApply(this, 'init', arguments); + this.resetRange(); + }, + + /** + * @override + */ + mergeOption: function() { + AxisModel.superApply(this, 'mergeOption', arguments); + this.resetRange(); + }, + + /** + * @override + */ + restoreData: function() { + AxisModel.superApply(this, 'restoreData', arguments); + this.resetRange(); + }, + + /** + * @override + * @return {module:echarts/model/Component} + */ + getCoordSysModel: function() { + return this.ecModel.queryComponents({ + mainType: 'grid', + index: this.option.gridIndex, + id: this.option.gridId + })[0]; + } + + }); + + function getAxisType(axisDim, option) { + // Default axis with data is category axis + return option.type || (option.data ? 'category' : 'value'); + } + + merge(AxisModel.prototype, axisModelCommonMixin); + + var extraOption = { + // gridIndex: 0, + // gridId: '', + + // Offset is for multiple axis on the same position + offset: 0 + }; + + axisModelCreator('x', AxisModel, getAxisType, extraOption); + axisModelCreator('y', AxisModel, getAxisType, extraOption); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Grid 是在有直角坐标系的时候必须要存在的 + // 所以这里也要被 Cartesian2D 依赖 + + ComponentModel.extend({ + + type: 'grid', + + dependencies: ['xAxis', 'yAxis'], + + layoutMode: 'box', + + /** + * @type {module:echarts/coord/cartesian/Grid} + */ + coordinateSystem: null, + + defaultOption: { + show: false, + zlevel: 0, + z: 0, + left: '10%', + top: 60, + right: '10%', + bottom: 60, + // If grid size contain label + containLabel: false, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 1, + borderColor: '#ccc' + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Grid is a region which contains at most 4 cartesian systems + * + * TODO Default cartesian + */ + + // Depends on GridModel, AxisModel, which performs preprocess. + /** + * Check if the axis is used in the specified grid + * @inner + */ + function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) { + return axisModel.getCoordSysModel() === gridModel; + } + + function Grid(gridModel, ecModel, api) { + /** + * @type {Object.} + * @private + */ + this._coordsMap = {}; + + /** + * @type {Array.} + * @private + */ + this._coordsList = []; + + /** + * @type {Object.} + * @private + */ + this._axesMap = {}; + + /** + * @type {Array.} + * @private + */ + this._axesList = []; + + this._initCartesian(gridModel, ecModel, api); + + this.model = gridModel; + } + + var gridProto = Grid.prototype; + + gridProto.type = 'grid'; + + gridProto.axisPointerEnabled = true; + + gridProto.getRect = function() { + return this._rect; + }; + + gridProto.update = function(ecModel, api) { + + var axesMap = this._axesMap; + + this._updateScale(ecModel, this.model); + + each$1(axesMap.x, function(xAxis) { + niceScaleExtent(xAxis.scale, xAxis.model); + }); + each$1(axesMap.y, function(yAxis) { + niceScaleExtent(yAxis.scale, yAxis.model); + }); + each$1(axesMap.x, function(xAxis) { + fixAxisOnZero(axesMap, 'y', xAxis); + }); + each$1(axesMap.y, function(yAxis) { + fixAxisOnZero(axesMap, 'x', yAxis); + }); + + // Resize again if containLabel is enabled + // FIXME It may cause getting wrong grid size in data processing stage + this.resize(this.model, api); + }; + + function fixAxisOnZero(axesMap, otherAxisDim, axis) { + + axis.getAxesOnZeroOf = function() { + // TODO: onZero of multiple axes. + return otherAxis ? [otherAxis] : []; + }; + + // onZero can not be enabled in these two situations: + // 1. When any other axis is a category axis. + // 2. When no axis is cross 0 point. + var otherAxes = axesMap[otherAxisDim]; + + var otherAxis; + var axisModel = axis.model; + var onZero = axisModel.get('axisLine.onZero'); + var onZeroAxisIndex = axisModel.get('axisLine.onZeroAxisIndex'); + + if (!onZero) { + return; + } + + // If target axis is specified. + if (onZeroAxisIndex != null) { + if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) { + otherAxis = otherAxes[onZeroAxisIndex]; + } + return; + } + + // Find the first available other axis. + for (var idx in otherAxes) { + if (otherAxes.hasOwnProperty(idx) && canOnZeroToAxis(otherAxes[idx])) { + otherAxis = otherAxes[idx]; + break; + } + } + } + + function canOnZeroToAxis(axis) { + return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis); + } + + /** + * Resize the grid + * @param {module:echarts/coord/cartesian/GridModel} gridModel + * @param {module:echarts/ExtensionAPI} api + */ + gridProto.resize = function(gridModel, api, ignoreContainLabel) { + + var gridRect = getLayoutRect( + gridModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + + this._rect = gridRect; + + var axesList = this._axesList; + + adjustAxes(); + + // Minus label size + if (!ignoreContainLabel && gridModel.get('containLabel')) { + each$1(axesList, function(axis) { + if (!axis.model.get('axisLabel.inside')) { + var labelUnionRect = estimateLabelUnionRect(axis); + if (labelUnionRect) { + var dim = axis.isHorizontal() ? 'height' : 'width'; + var margin = axis.model.get('axisLabel.margin'); + gridRect[dim] -= labelUnionRect[dim] + margin; + if (axis.position === 'top') { + gridRect.y += labelUnionRect.height + margin; + } else if (axis.position === 'left') { + gridRect.x += labelUnionRect.width + margin; + } + } + } + }); + + adjustAxes(); + } + + function adjustAxes() { + each$1(axesList, function(axis) { + var isHorizontal = axis.isHorizontal(); + var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height]; + var idx = axis.inverse ? 1 : 0; + axis.setExtent(extent[idx], extent[1 - idx]); + updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y); + }); + } + }; + + /** + * @param {string} axisType + * @param {number} [axisIndex] + */ + gridProto.getAxis = function(axisType, axisIndex) { + var axesMapOnDim = this._axesMap[axisType]; + if (axesMapOnDim != null) { + if (axisIndex == null) { + // Find first axis + for (var name in axesMapOnDim) { + if (axesMapOnDim.hasOwnProperty(name)) { + return axesMapOnDim[name]; + } + } + } + return axesMapOnDim[axisIndex]; + } + }; + + /** + * @return {Array.} + */ + gridProto.getAxes = function() { + return this._axesList.slice(); + }; + + /** + * Usage: + * grid.getCartesian(xAxisIndex, yAxisIndex); + * grid.getCartesian(xAxisIndex); + * grid.getCartesian(null, yAxisIndex); + * grid.getCartesian({xAxisIndex: ..., yAxisIndex: ...}); + * + * @param {number|Object} [xAxisIndex] + * @param {number} [yAxisIndex] + */ + gridProto.getCartesian = function(xAxisIndex, yAxisIndex) { + if (xAxisIndex != null && yAxisIndex != null) { + var key = 'x' + xAxisIndex + 'y' + yAxisIndex; + return this._coordsMap[key]; + } + + if (isObject$1(xAxisIndex)) { + yAxisIndex = xAxisIndex.yAxisIndex; + xAxisIndex = xAxisIndex.xAxisIndex; + } + // When only xAxisIndex or yAxisIndex given, find its first cartesian. + for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) { + if (coordList[i].getAxis('x').index === xAxisIndex || + coordList[i].getAxis('y').index === yAxisIndex + ) { + return coordList[i]; + } + } + }; + + gridProto.getCartesians = function() { + return this._coordsList.slice(); + }; + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + gridProto.convertToPixel = function(ecModel, finder, value) { + var target = this._findConvertTarget(ecModel, finder); + + return target.cartesian ? + target.cartesian.dataToPoint(value) : + target.axis ? + target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : + null; + }; + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + gridProto.convertFromPixel = function(ecModel, finder, value) { + var target = this._findConvertTarget(ecModel, finder); + + return target.cartesian ? + target.cartesian.pointToData(value) : + target.axis ? + target.axis.coordToData(target.axis.toLocalCoord(value)) : + null; + }; + + /** + * @inner + */ + gridProto._findConvertTarget = function(ecModel, finder) { + var seriesModel = finder.seriesModel; + var xAxisModel = finder.xAxisModel || + (seriesModel && seriesModel.getReferringComponents('xAxis')[0]); + var yAxisModel = finder.yAxisModel || + (seriesModel && seriesModel.getReferringComponents('yAxis')[0]); + var gridModel = finder.gridModel; + var coordsList = this._coordsList; + var cartesian; + var axis; + + if (seriesModel) { + cartesian = seriesModel.coordinateSystem; + indexOf(coordsList, cartesian) < 0 && (cartesian = null); + } else if (xAxisModel && yAxisModel) { + cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex); + } else if (xAxisModel) { + axis = this.getAxis('x', xAxisModel.componentIndex); + } else if (yAxisModel) { + axis = this.getAxis('y', yAxisModel.componentIndex); + } + // Lowest priority. + else if (gridModel) { + var grid = gridModel.coordinateSystem; + if (grid === this) { + cartesian = this._coordsList[0]; + } + } + + return { + cartesian: cartesian, + axis: axis + }; + }; + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + gridProto.containPoint = function(point) { + var coord = this._coordsList[0]; + if (coord) { + return coord.containPoint(point); + } + }; + + /** + * Initialize cartesian coordinate systems + * @private + */ + gridProto._initCartesian = function(gridModel, ecModel, api) { + var axisPositionUsed = { + left: false, + right: false, + top: false, + bottom: false + }; + + var axesMap = { + x: {}, + y: {} + }; + var axesCount = { + x: 0, + y: 0 + }; + + /// Create axis + ecModel.eachComponent('xAxis', createAxisCreator('x'), this); + ecModel.eachComponent('yAxis', createAxisCreator('y'), this); + + if (!axesCount.x || !axesCount.y) { + // Roll back when there no either x or y axis + this._axesMap = {}; + this._axesList = []; + return; + } + + this._axesMap = axesMap; + + /// Create cartesian2d + each$1(axesMap.x, function(xAxis, xAxisIndex) { + each$1(axesMap.y, function(yAxis, yAxisIndex) { + var key = 'x' + xAxisIndex + 'y' + yAxisIndex; + var cartesian = new Cartesian2D(key); + + cartesian.grid = this; + cartesian.model = gridModel; + + this._coordsMap[key] = cartesian; + this._coordsList.push(cartesian); + + cartesian.addAxis(xAxis); + cartesian.addAxis(yAxis); + }, this); + }, this); + + function createAxisCreator(axisType) { + return function(axisModel, idx) { + if (!isAxisUsedInTheGrid(axisModel, gridModel, ecModel)) { + return; + } + + var axisPosition = axisModel.get('position'); + if (axisType === 'x') { + // Fix position + if (axisPosition !== 'top' && axisPosition !== 'bottom') { + // Default bottom of X + axisPosition = 'bottom'; + if (axisPositionUsed[axisPosition]) { + axisPosition = axisPosition === 'top' ? 'bottom' : 'top'; + } + } + } else { + // Fix position + if (axisPosition !== 'left' && axisPosition !== 'right') { + // Default left of Y + axisPosition = 'left'; + if (axisPositionUsed[axisPosition]) { + axisPosition = axisPosition === 'left' ? 'right' : 'left'; + } + } + } + axisPositionUsed[axisPosition] = true; + + var axis = new Axis2D( + axisType, createScaleByModel(axisModel), + [0, 0], + axisModel.get('type'), + axisPosition + ); + + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + + // Inject axis into axisModel + axisModel.axis = axis; + + // Inject axisModel into axis + axis.model = axisModel; + + // Inject grid info axis + axis.grid = this; + + // Index of axis, can be used as key + axis.index = idx; + + this._axesList.push(axis); + + axesMap[axisType][idx] = axis; + axesCount[axisType]++; + }; + } + }; + + /** + * Update cartesian properties from series + * @param {module:echarts/model/Option} option + * @private + */ + gridProto._updateScale = function(ecModel, gridModel) { + // Reset scale + each$1(this._axesList, function(axis) { + axis.scale.setExtent(Infinity, -Infinity); + }); + ecModel.eachSeries(function(seriesModel) { + if (isCartesian2D(seriesModel)) { + var axesModels = findAxesModels(seriesModel, ecModel); + var xAxisModel = axesModels[0]; + var yAxisModel = axesModels[1]; + + if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel) || + !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel) + ) { + return; + } + + var cartesian = this.getCartesian( + xAxisModel.componentIndex, yAxisModel.componentIndex + ); + var data = seriesModel.getData(); + var xAxis = cartesian.getAxis('x'); + var yAxis = cartesian.getAxis('y'); + + if (data.type === 'list') { + unionExtent(data, xAxis, seriesModel); + unionExtent(data, yAxis, seriesModel); + } + } + }, this); + + function unionExtent(data, axis, seriesModel) { + each$1(data.mapDimension(axis.dim, true), function(dim) { + axis.scale.unionExtentFromData( + // For example, the extent of the orginal dimension + // is [0.1, 0.5], the extent of the `stackResultDimension` + // is [7, 9], the final extent should not include [0.1, 0.5]. + data, getStackedDimension(data, dim) + ); + }); + } + }; + + /** + * @param {string} [dim] 'x' or 'y' or 'auto' or null/undefined + * @return {Object} {baseAxes: [], otherAxes: []} + */ + gridProto.getTooltipAxes = function(dim) { + var baseAxes = []; + var otherAxes = []; + + each$1(this.getCartesians(), function(cartesian) { + var baseAxis = (dim != null && dim !== 'auto') ? + cartesian.getAxis(dim) : cartesian.getBaseAxis(); + var otherAxis = cartesian.getOtherAxis(baseAxis); + indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis); + indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis); + }); + + return { + baseAxes: baseAxes, + otherAxes: otherAxes + }; + }; + + /** + * @inner + */ + function updateAxisTransform(axis, coordBase) { + var axisExtent = axis.getExtent(); + var axisExtentSum = axisExtent[0] + axisExtent[1]; + + // Fast transform + axis.toGlobalCoord = axis.dim === 'x' ? + function(coord) { + return coord + coordBase; + } : + function(coord) { + return axisExtentSum - coord + coordBase; + }; + axis.toLocalCoord = axis.dim === 'x' ? + function(coord) { + return coord - coordBase; + } : + function(coord) { + return axisExtentSum - coord + coordBase; + }; + } + + var axesTypes = ['xAxis', 'yAxis']; + /** + * @inner + */ + function findAxesModels(seriesModel, ecModel) { + return map(axesTypes, function(axisType) { + var axisModel = seriesModel.getReferringComponents(axisType)[0]; + + if (__DEV__) { + if (!axisModel) { + throw new Error(axisType + ' "' + retrieve( + seriesModel.get(axisType + 'Index'), + seriesModel.get(axisType + 'Id'), + 0 + ) + '" not found'); + } + } + return axisModel; + }); + } + + /** + * @inner + */ + function isCartesian2D(seriesModel) { + return seriesModel.get('coordinateSystem') === 'cartesian2d'; + } + + Grid.create = function(ecModel, api) { + var grids = []; + ecModel.eachComponent('grid', function(gridModel, idx) { + var grid = new Grid(gridModel, ecModel, api); + grid.name = 'grid_' + idx; + // dataSampling requires axis extent, so resize + // should be performed in create stage. + grid.resize(gridModel, api, true); + + gridModel.coordinateSystem = grid; + + grids.push(grid); + }); + + // Inject the coordinateSystems into seriesModel + ecModel.eachSeries(function(seriesModel) { + if (!isCartesian2D(seriesModel)) { + return; + } + + var axesModels = findAxesModels(seriesModel, ecModel); + var xAxisModel = axesModels[0]; + var yAxisModel = axesModels[1]; + + var gridModel = xAxisModel.getCoordSysModel(); + + if (__DEV__) { + if (!gridModel) { + throw new Error( + 'Grid "' + retrieve( + xAxisModel.get('gridIndex'), + xAxisModel.get('gridId'), + 0 + ) + '" not found' + ); + } + if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) { + throw new Error('xAxis and yAxis must use the same grid'); + } + } + + var grid = gridModel.coordinateSystem; + + seriesModel.coordinateSystem = grid.getCartesian( + xAxisModel.componentIndex, yAxisModel.componentIndex + ); + }); + + return grids; + }; + + // For deciding which dimensions to use when creating list data + Grid.dimensions = Grid.prototype.dimensions = Cartesian2D.prototype.dimensions; + + CoordinateSystemManager.register('cartesian2d', Grid); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PI$2 = Math.PI; + + function makeAxisEventDataBase(axisModel) { + var eventData = { + componentType: axisModel.mainType + }; + eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex; + return eventData; + } + + /** + * A final axis is translated and rotated from a "standard axis". + * So opt.position and opt.rotation is required. + * + * A standard axis is and axis from [0, 0] to [0, axisExtent[1]], + * for example: (0, 0) ------------> (0, 50) + * + * nameDirection or tickDirection or labelDirection is 1 means tick + * or label is below the standard axis, whereas is -1 means above + * the standard axis. labelOffset means offset between label and axis, + * which is useful when 'onZero', where axisLabel is in the grid and + * label in outside grid. + * + * Tips: like always, + * positive rotation represents anticlockwise, and negative rotation + * represents clockwise. + * The direction of position coordinate is the same as the direction + * of screen coordinate. + * + * Do not need to consider axis 'inverse', which is auto processed by + * axis extent. + * + * @param {module:zrender/container/Group} group + * @param {Object} axisModel + * @param {Object} opt Standard axis parameters. + * @param {Array.} opt.position [x, y] + * @param {number} opt.rotation by radian + * @param {number} [opt.nameDirection=1] 1 or -1 Used when nameLocation is 'middle' or 'center'. + * @param {number} [opt.tickDirection=1] 1 or -1 + * @param {number} [opt.labelDirection=1] 1 or -1 + * @param {number} [opt.labelOffset=0] Usefull when onZero. + * @param {string} [opt.axisLabelShow] default get from axisModel. + * @param {string} [opt.axisName] default get from axisModel. + * @param {number} [opt.axisNameAvailableWidth] + * @param {number} [opt.labelRotate] by degree, default get from axisModel. + * @param {number} [opt.strokeContainThreshold] Default label interval when label + * @param {number} [opt.nameTruncateMaxWidth] + */ + var AxisBuilder = function(axisModel, opt) { + + /** + * @readOnly + */ + this.opt = opt; + + /** + * @readOnly + */ + this.axisModel = axisModel; + + // Default value + defaults( + opt, { + labelOffset: 0, + nameDirection: 1, + tickDirection: 1, + labelDirection: 1, + silent: true + } + ); + + /** + * @readOnly + */ + this.group = new Group(); + + // FIXME Not use a seperate text group? + var dumbGroup = new Group({ + position: opt.position.slice(), + rotation: opt.rotation + }); + + // this.group.add(dumbGroup); + // this._dumbGroup = dumbGroup; + + dumbGroup.updateTransform(); + this._transform = dumbGroup.transform; + + this._dumbGroup = dumbGroup; + }; + + AxisBuilder.prototype = { + + constructor: AxisBuilder, + + hasBuilder: function(name) { + return !!builders[name]; + }, + + add: function(name) { + builders[name].call(this); + }, + + getGroup: function() { + return this.group; + } + + }; + + var builders = { + + /** + * @private + */ + axisLine: function() { + var opt = this.opt; + var axisModel = this.axisModel; + + if (!axisModel.get('axisLine.show')) { + return; + } + + var extent = this.axisModel.axis.getExtent(); + + var matrix = this._transform; + var pt1 = [extent[0], 0]; + var pt2 = [extent[1], 0]; + if (matrix) { + applyTransform(pt1, pt1, matrix); + applyTransform(pt2, pt2, matrix); + } + + var lineStyle = extend({ + lineCap: 'round' + }, + axisModel.getModel('axisLine.lineStyle').getLineStyle() + ); + + this.group.add(new Line(subPixelOptimizeLine({ + // Id for animation + anid: 'line', + + shape: { + x1: pt1[0], + y1: pt1[1], + x2: pt2[0], + y2: pt2[1] + }, + style: lineStyle, + strokeContainThreshold: opt.strokeContainThreshold || 5, + silent: true, + z2: 1 + }))); + + var arrows = axisModel.get('axisLine.symbol'); + var arrowSize = axisModel.get('axisLine.symbolSize'); + + var arrowOffset = axisModel.get('axisLine.symbolOffset') || 0; + if (typeof arrowOffset === 'number') { + arrowOffset = [arrowOffset, arrowOffset]; + } + + if (arrows != null) { + if (typeof arrows === 'string') { + // Use the same arrow for start and end point + arrows = [arrows, arrows]; + } + if (typeof arrowSize === 'string' || + typeof arrowSize === 'number' + ) { + // Use the same size for width and height + arrowSize = [arrowSize, arrowSize]; + } + + var symbolWidth = arrowSize[0]; + var symbolHeight = arrowSize[1]; + + each$1([{ + rotate: opt.rotation + Math.PI / 2, + offset: arrowOffset[0], + r: 0 + }, { + rotate: opt.rotation - Math.PI / 2, + offset: arrowOffset[1], + r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) + }], function(point, index) { + if (arrows[index] !== 'none' && arrows[index] != null) { + var symbol = createSymbol( + arrows[index], + -symbolWidth / 2, + -symbolHeight / 2, + symbolWidth, + symbolHeight, + lineStyle.stroke, + true + ); + + // Calculate arrow position with offset + var r = point.r + point.offset; + var pos = [ + pt1[0] + r * Math.cos(opt.rotation), + pt1[1] - r * Math.sin(opt.rotation) + ]; + + symbol.attr({ + rotation: point.rotate, + position: pos, + silent: true + }); + this.group.add(symbol); + } + }, this); + } + }, + + /** + * @private + */ + axisTickLabel: function() { + var axisModel = this.axisModel; + var opt = this.opt; + + var tickEls = buildAxisTick(this, axisModel, opt); + var labelEls = buildAxisLabel(this, axisModel, opt); + + fixMinMaxLabelShow(axisModel, labelEls, tickEls); + }, + + /** + * @private + */ + axisName: function() { + var opt = this.opt; + var axisModel = this.axisModel; + var name = retrieve(opt.axisName, axisModel.get('name')); + + if (!name) { + return; + } + + var nameLocation = axisModel.get('nameLocation'); + var nameDirection = opt.nameDirection; + var textStyleModel = axisModel.getModel('nameTextStyle'); + var gap = axisModel.get('nameGap') || 0; + + var extent = this.axisModel.axis.getExtent(); + var gapSignal = extent[0] > extent[1] ? -1 : 1; + var pos = [ + nameLocation === 'start' ? + extent[0] - gapSignal * gap : + nameLocation === 'end' ? + extent[1] + gapSignal * gap : + (extent[0] + extent[1]) / 2, // 'middle' + // Reuse labelOffset. + isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0 + ]; + + var labelLayout; + + var nameRotation = axisModel.get('nameRotate'); + if (nameRotation != null) { + nameRotation = nameRotation * PI$2 / 180; // To radian. + } + + var axisNameAvailableWidth; + + if (isNameLocationCenter(nameLocation)) { + labelLayout = innerTextLayout( + opt.rotation, + nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis. + nameDirection + ); + } else { + labelLayout = endTextLayout( + opt, nameLocation, nameRotation || 0, extent + ); + + axisNameAvailableWidth = opt.axisNameAvailableWidth; + if (axisNameAvailableWidth != null) { + axisNameAvailableWidth = Math.abs( + axisNameAvailableWidth / Math.sin(labelLayout.rotation) + ); + !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null); + } + } + + var textFont = textStyleModel.getFont(); + + var truncateOpt = axisModel.get('nameTruncate', true) || {}; + var ellipsis = truncateOpt.ellipsis; + var maxWidth = retrieve( + opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth + ); + // FIXME + // truncate rich text? (consider performance) + var truncatedText = (ellipsis != null && maxWidth != null) ? + truncateText$1( + name, maxWidth, textFont, ellipsis, { + minChar: 2, + placeholder: truncateOpt.placeholder + } + ) : + name; + + var tooltipOpt = axisModel.get('tooltip', true); + + var mainType = axisModel.mainType; + var formatterParams = { + componentType: mainType, + name: name, + $vars: ['name'] + }; + formatterParams[mainType + 'Index'] = axisModel.componentIndex; + + var textEl = new Text({ + // Id for animation + anid: 'name', + + __fullText: name, + __truncatedText: truncatedText, + + position: pos, + rotation: labelLayout.rotation, + silent: isSilent(axisModel), + z2: 1, + tooltip: (tooltipOpt && tooltipOpt.show) ? + extend({ + content: name, + formatter: function() { + return name; + }, + formatterParams: formatterParams + }, tooltipOpt) : + null + }); + + setTextStyle(textEl.style, textStyleModel, { + text: truncatedText, + textFont: textFont, + textFill: textStyleModel.getTextColor() || + axisModel.get('axisLine.lineStyle.color'), + textAlign: labelLayout.textAlign, + textVerticalAlign: labelLayout.textVerticalAlign + }); + + if (axisModel.get('triggerEvent')) { + textEl.eventData = makeAxisEventDataBase(axisModel); + textEl.eventData.targetType = 'axisName'; + textEl.eventData.name = name; + } + + // FIXME + this._dumbGroup.add(textEl); + textEl.updateTransform(); + + this.group.add(textEl); + + textEl.decomposeTransform(); + } + + }; + + /** + * @public + * @static + * @param {Object} opt + * @param {number} axisRotation in radian + * @param {number} textRotation in radian + * @param {number} direction + * @return {Object} { + * rotation, // according to axis + * textAlign, + * textVerticalAlign + * } + */ + var innerTextLayout = AxisBuilder.innerTextLayout = function(axisRotation, textRotation, direction) { + var rotationDiff = remRadian(textRotation - axisRotation); + var textAlign; + var textVerticalAlign; + + if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line. + textVerticalAlign = direction > 0 ? 'top' : 'bottom'; + textAlign = 'center'; + } else if (isRadianAroundZero(rotationDiff - PI$2)) { // Label is inverse parallel with axis line. + textVerticalAlign = direction > 0 ? 'bottom' : 'top'; + textAlign = 'center'; + } else { + textVerticalAlign = 'middle'; + + if (rotationDiff > 0 && rotationDiff < PI$2) { + textAlign = direction > 0 ? 'right' : 'left'; + } else { + textAlign = direction > 0 ? 'left' : 'right'; + } + } + + return { + rotation: rotationDiff, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + }; + + function endTextLayout(opt, textPosition, textRotate, extent) { + var rotationDiff = remRadian(textRotate - opt.rotation); + var textAlign; + var textVerticalAlign; + var inverse = extent[0] > extent[1]; + var onLeft = (textPosition === 'start' && !inverse) || + (textPosition !== 'start' && inverse); + + if (isRadianAroundZero(rotationDiff - PI$2 / 2)) { + textVerticalAlign = onLeft ? 'bottom' : 'top'; + textAlign = 'center'; + } else if (isRadianAroundZero(rotationDiff - PI$2 * 1.5)) { + textVerticalAlign = onLeft ? 'top' : 'bottom'; + textAlign = 'center'; + } else { + textVerticalAlign = 'middle'; + if (rotationDiff < PI$2 * 1.5 && rotationDiff > PI$2 / 2) { + textAlign = onLeft ? 'left' : 'right'; + } else { + textAlign = onLeft ? 'right' : 'left'; + } + } + + return { + rotation: rotationDiff, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + } + + function isSilent(axisModel) { + var tooltipOpt = axisModel.get('tooltip'); + return axisModel.get('silent') + // Consider mouse cursor, add these restrictions. + || + !( + axisModel.get('triggerEvent') || (tooltipOpt && tooltipOpt.show) + ); + } + + function fixMinMaxLabelShow(axisModel, labelEls, tickEls) { + // If min or max are user set, we need to check + // If the tick on min(max) are overlap on their neighbour tick + // If they are overlapped, we need to hide the min(max) tick label + var showMinLabel = axisModel.get('axisLabel.showMinLabel'); + var showMaxLabel = axisModel.get('axisLabel.showMaxLabel'); + + // FIXME + // Have not consider onBand yet, where tick els is more than label els. + + labelEls = labelEls || []; + tickEls = tickEls || []; + + var firstLabel = labelEls[0]; + var nextLabel = labelEls[1]; + var lastLabel = labelEls[labelEls.length - 1]; + var prevLabel = labelEls[labelEls.length - 2]; + + var firstTick = tickEls[0]; + var nextTick = tickEls[1]; + var lastTick = tickEls[tickEls.length - 1]; + var prevTick = tickEls[tickEls.length - 2]; + + if (showMinLabel === false) { + ignoreEl(firstLabel); + ignoreEl(firstTick); + } else if (isTwoLabelOverlapped(firstLabel, nextLabel)) { + if (showMinLabel) { + ignoreEl(nextLabel); + ignoreEl(nextTick); + } else { + ignoreEl(firstLabel); + ignoreEl(firstTick); + } + } + + if (showMaxLabel === false) { + ignoreEl(lastLabel); + ignoreEl(lastTick); + } else if (isTwoLabelOverlapped(prevLabel, lastLabel)) { + if (showMaxLabel) { + ignoreEl(prevLabel); + ignoreEl(prevTick); + } else { + ignoreEl(lastLabel); + ignoreEl(lastTick); + } + } + } + + function ignoreEl(el) { + el && (el.ignore = true); + } + + function isTwoLabelOverlapped(current, next, labelLayout) { + // current and next has the same rotation. + var firstRect = current && current.getBoundingRect().clone(); + var nextRect = next && next.getBoundingRect().clone(); + + if (!firstRect || !nextRect) { + return; + } + + // When checking intersect of two rotated labels, we use mRotationBack + // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`. + var mRotationBack = identity([]); + rotate(mRotationBack, mRotationBack, -current.rotation); + + firstRect.applyTransform(mul$1([], mRotationBack, current.getLocalTransform())); + nextRect.applyTransform(mul$1([], mRotationBack, next.getLocalTransform())); + + return firstRect.intersect(nextRect); + } + + function isNameLocationCenter(nameLocation) { + return nameLocation === 'middle' || nameLocation === 'center'; + } + + function buildAxisTick(axisBuilder, axisModel, opt) { + var axis = axisModel.axis; + + if (!axisModel.get('axisTick.show') || axis.scale.isBlank()) { + return; + } + + var tickModel = axisModel.getModel('axisTick'); + + var lineStyleModel = tickModel.getModel('lineStyle'); + var tickLen = tickModel.get('length'); + + var ticksCoords = axis.getTicksCoords(); + + var pt1 = []; + var pt2 = []; + var matrix = axisBuilder._transform; + + var tickEls = []; + + for (var i = 0; i < ticksCoords.length; i++) { + var tickCoord = ticksCoords[i].coord; + + pt1[0] = tickCoord; + pt1[1] = 0; + pt2[0] = tickCoord; + pt2[1] = opt.tickDirection * tickLen; + + if (matrix) { + applyTransform(pt1, pt1, matrix); + applyTransform(pt2, pt2, matrix); + } + // Tick line, Not use group transform to have better line draw + var tickEl = new Line(subPixelOptimizeLine({ + // Id for animation + anid: 'tick_' + ticksCoords[i].tickValue, + + shape: { + x1: pt1[0], + y1: pt1[1], + x2: pt2[0], + y2: pt2[1] + }, + style: defaults( + lineStyleModel.getLineStyle(), { + stroke: axisModel.get('axisLine.lineStyle.color') + } + ), + z2: 2, + silent: true + })); + axisBuilder.group.add(tickEl); + tickEls.push(tickEl); + } + + return tickEls; + } + + function buildAxisLabel(axisBuilder, axisModel, opt) { + var axis = axisModel.axis; + var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show')); + + if (!show || axis.scale.isBlank()) { + return; + } + + var labelModel = axisModel.getModel('axisLabel'); + var labelMargin = labelModel.get('margin'); + var labels = axis.getViewLabels(); + + // Special label rotate. + var labelRotation = ( + retrieve(opt.labelRotate, labelModel.get('rotate')) || 0 + ) * PI$2 / 180; + + var labelLayout = innerTextLayout(opt.rotation, labelRotation, opt.labelDirection); + var rawCategoryData = axisModel.getCategories(true); + + var labelEls = []; + var silent = isSilent(axisModel); + var triggerEvent = axisModel.get('triggerEvent'); + + each$1(labels, function(labelItem, index) { + var tickValue = labelItem.tickValue; + var formattedLabel = labelItem.formattedLabel; + var rawLabel = labelItem.rawLabel; + + var itemLabelModel = labelModel; + if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) { + itemLabelModel = new Model( + rawCategoryData[tickValue].textStyle, labelModel, axisModel.ecModel + ); + } + + var textColor = itemLabelModel.getTextColor() || + axisModel.get('axisLine.lineStyle.color'); + + var tickCoord = axis.dataToCoord(tickValue); + var pos = [ + tickCoord, + opt.labelOffset + opt.labelDirection * labelMargin + ]; + + var textEl = new Text({ + // Id for animation + anid: 'label_' + tickValue, + position: pos, + rotation: labelLayout.rotation, + silent: silent, + z2: 10 + }); + + setTextStyle(textEl.style, itemLabelModel, { + text: formattedLabel, + textAlign: itemLabelModel.getShallow('align', true) || + labelLayout.textAlign, + textVerticalAlign: itemLabelModel.getShallow('verticalAlign', true) || + itemLabelModel.getShallow('baseline', true) || + labelLayout.textVerticalAlign, + textFill: typeof textColor === 'function' ? + textColor( + // (1) In category axis with data zoom, tick is not the original + // index of axis.data. So tick should not be exposed to user + // in category axis. + // (2) Compatible with previous version, which always use formatted label as + // input. But in interval scale the formatted label is like '223,445', which + // maked user repalce ','. So we modify it to return original val but remain + // it as 'string' to avoid error in replacing. + axis.type === 'category' ? + rawLabel : + axis.type === 'value' ? + tickValue + '' : + tickValue, + index + ) : + textColor + }); + + // Pack data for mouse event + if (triggerEvent) { + textEl.eventData = makeAxisEventDataBase(axisModel); + textEl.eventData.targetType = 'axisLabel'; + textEl.eventData.value = rawLabel; + } + + // FIXME + axisBuilder._dumbGroup.add(textEl); + textEl.updateTransform(); + + labelEls.push(textEl); + axisBuilder.group.add(textEl); + + textEl.decomposeTransform(); + + }); + + return labelEls; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$6 = each$1; + var curry$1 = curry; + + // Build axisPointerModel, mergin tooltip.axisPointer model for each axis. + // allAxesInfo should be updated when setOption performed. + function collect(ecModel, api) { + var result = { + /** + * key: makeKey(axis.model) + * value: { + * axis, + * coordSys, + * axisPointerModel, + * triggerTooltip, + * involveSeries, + * snap, + * seriesModels, + * seriesDataCount + * } + */ + axesInfo: {}, + seriesInvolved: false, + /** + * key: makeKey(coordSys.model) + * value: Object: key makeKey(axis.model), value: axisInfo + */ + coordSysAxesInfo: {}, + coordSysMap: {} + }; + + collectAxesInfo(result, ecModel, api); + + // Check seriesInvolved for performance, in case too many series in some chart. + result.seriesInvolved && collectSeriesInfo(result, ecModel); + + return result; + } + + function collectAxesInfo(result, ecModel, api) { + var globalTooltipModel = ecModel.getComponent('tooltip'); + var globalAxisPointerModel = ecModel.getComponent('axisPointer'); + // links can only be set on global. + var linksOption = globalAxisPointerModel.get('link', true) || []; + var linkGroups = []; + + // Collect axes info. + each$6(api.getCoordinateSystems(), function(coordSys) { + // Some coordinate system do not support axes, like geo. + if (!coordSys.axisPointerEnabled) { + return; + } + + var coordSysKey = makeKey(coordSys.model); + var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {}; + result.coordSysMap[coordSysKey] = coordSys; + + // Set tooltip (like 'cross') is a convienent way to show axisPointer + // for user. So we enable seting tooltip on coordSys model. + var coordSysModel = coordSys.model; + var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel); + + each$6(coordSys.getAxes(), curry$1(saveTooltipAxisInfo, false, null)); + + // If axis tooltip used, choose tooltip axis for each coordSys. + // Notice this case: coordSys is `grid` but not `cartesian2D` here. + if (coordSys.getTooltipAxes && + globalTooltipModel + // If tooltip.showContent is set as false, tooltip will not + // show but axisPointer will show as normal. + && + baseTooltipModel.get('show') + ) { + // Compatible with previous logic. But series.tooltip.trigger: 'axis' + // or series.data[n].tooltip.trigger: 'axis' are not support any more. + var triggerAxis = baseTooltipModel.get('trigger') === 'axis'; + var cross = baseTooltipModel.get('axisPointer.type') === 'cross'; + var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get('axisPointer.axis')); + if (triggerAxis || cross) { + each$6(tooltipAxes.baseAxes, curry$1( + saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis + )); + } + if (cross) { + each$6(tooltipAxes.otherAxes, curry$1(saveTooltipAxisInfo, 'cross', false)); + } + } + + // fromTooltip: true | false | 'cross' + // triggerTooltip: true | false | null + function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) { + var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel); + + var axisPointerShow = axisPointerModel.get('show'); + if (!axisPointerShow || ( + axisPointerShow === 'auto' && + !fromTooltip && + !isHandleTrigger(axisPointerModel) + )) { + return; + } + + if (triggerTooltip == null) { + triggerTooltip = axisPointerModel.get('triggerTooltip'); + } + + axisPointerModel = fromTooltip ? + makeAxisPointerModel( + axis, baseTooltipModel, globalAxisPointerModel, ecModel, + fromTooltip, triggerTooltip + ) : + axisPointerModel; + + var snap = axisPointerModel.get('snap'); + var key = makeKey(axis.model); + var involveSeries = triggerTooltip || snap || axis.type === 'category'; + + // If result.axesInfo[key] exist, override it (tooltip has higher priority). + var axisInfo = result.axesInfo[key] = { + key: key, + axis: axis, + coordSys: coordSys, + axisPointerModel: axisPointerModel, + triggerTooltip: triggerTooltip, + involveSeries: involveSeries, + snap: snap, + useHandle: isHandleTrigger(axisPointerModel), + seriesModels: [] + }; + axesInfoInCoordSys[key] = axisInfo; + result.seriesInvolved |= involveSeries; + + var groupIndex = getLinkGroupIndex(linksOption, axis); + if (groupIndex != null) { + var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = { + axesInfo: {} + }); + linkGroup.axesInfo[key] = axisInfo; + linkGroup.mapper = linksOption[groupIndex].mapper; + axisInfo.linkGroup = linkGroup; + } + } + }); + } + + function makeAxisPointerModel( + axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip + ) { + var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer'); + var volatileOption = {}; + + each$6( + [ + 'type', 'snap', 'lineStyle', 'shadowStyle', 'label', + 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z' + ], + function(field) { + volatileOption[field] = clone(tooltipAxisPointerModel.get(field)); + } + ); + + // category axis do not auto snap, otherwise some tick that do not + // has value can not be hovered. value/time/log axis default snap if + // triggered from tooltip and trigger tooltip. + volatileOption.snap = axis.type !== 'category' && !!triggerTooltip; + + // Compatibel with previous behavior, tooltip axis do not show label by default. + // Only these properties can be overrided from tooltip to axisPointer. + if (tooltipAxisPointerModel.get('type') === 'cross') { + volatileOption.type = 'line'; + } + var labelOption = volatileOption.label || (volatileOption.label = {}); + // Follow the convention, do not show label when triggered by tooltip by default. + labelOption.show == null && (labelOption.show = false); + + if (fromTooltip === 'cross') { + // When 'cross', both axes show labels. + var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get('label.show'); + labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true; + // If triggerTooltip, this is a base axis, which should better not use cross style + // (cross style is dashed by default) + if (!triggerTooltip) { + var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle'); + crossStyle && defaults(labelOption, crossStyle.textStyle); + } + } + + return axis.model.getModel( + 'axisPointer', + new Model(volatileOption, globalAxisPointerModel, ecModel) + ); + } + + function collectSeriesInfo(result, ecModel) { + // Prepare data for axis trigger + ecModel.eachSeries(function(seriesModel) { + + // Notice this case: this coordSys is `cartesian2D` but not `grid`. + var coordSys = seriesModel.coordinateSystem; + var seriesTooltipTrigger = seriesModel.get('tooltip.trigger', true); + var seriesTooltipShow = seriesModel.get('tooltip.show', true); + if (!coordSys || + seriesTooltipTrigger === 'none' || + seriesTooltipTrigger === false || + seriesTooltipTrigger === 'item' || + seriesTooltipShow === false || + seriesModel.get('axisPointer.show', true) === false + ) { + return; + } + + each$6(result.coordSysAxesInfo[makeKey(coordSys.model)], function(axisInfo) { + var axis = axisInfo.axis; + if (coordSys.getAxis(axis.dim) === axis) { + axisInfo.seriesModels.push(seriesModel); + axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0); + axisInfo.seriesDataCount += seriesModel.getData().count(); + } + }); + + }, this); + } + + /** + * For example: + * { + * axisPointer: { + * links: [{ + * xAxisIndex: [2, 4], + * yAxisIndex: 'all' + * }, { + * xAxisId: ['a5', 'a7'], + * xAxisName: 'xxx' + * }] + * } + * } + */ + function getLinkGroupIndex(linksOption, axis) { + var axisModel = axis.model; + var dim = axis.dim; + for (var i = 0; i < linksOption.length; i++) { + var linkOption = linksOption[i] || {}; + if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id) || + checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex) || + checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name) + ) { + return i; + } + } + } + + function checkPropInLink(linkPropValue, axisPropValue) { + return linkPropValue === 'all' || + (isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0) || + linkPropValue === axisPropValue; + } + + function fixValue(axisModel) { + var axisInfo = getAxisInfo(axisModel); + if (!axisInfo) { + return; + } + + var axisPointerModel = axisInfo.axisPointerModel; + var scale = axisInfo.axis.scale; + var option = axisPointerModel.option; + var status = axisPointerModel.get('status'); + var value = axisPointerModel.get('value'); + + // Parse init value for category and time axis. + if (value != null) { + value = scale.parse(value); + } + + var useHandle = isHandleTrigger(axisPointerModel); + // If `handle` used, `axisPointer` will always be displayed, so value + // and status should be initialized. + if (status == null) { + option.status = useHandle ? 'show' : 'hide'; + } + + var extent = scale.getExtent().slice(); + extent[0] > extent[1] && extent.reverse(); + + if ( // Pick a value on axis when initializing. + value == null + // If both `handle` and `dataZoom` are used, value may be out of axis extent, + // where we should re-pick a value to keep `handle` displaying normally. + || + value > extent[1] + ) { + // Make handle displayed on the end of the axis when init, which looks better. + value = extent[1]; + } + if (value < extent[0]) { + value = extent[0]; + } + + option.value = value; + + if (useHandle) { + option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show'; + } + } + + function getAxisInfo(axisModel) { + var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo; + return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)]; + } + + function getAxisPointerModel(axisModel) { + var axisInfo = getAxisInfo(axisModel); + return axisInfo && axisInfo.axisPointerModel; + } + + function isHandleTrigger(axisPointerModel) { + return !!axisPointerModel.get('handle.show'); + } + + /** + * @param {module:echarts/model/Model} model + * @return {string} unique key + */ + function makeKey(model) { + return model.type + '||' + model.id; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Base class of AxisView. + */ + var AxisView = extendComponentView({ + + type: 'axis', + + /** + * @private + */ + _axisPointer: null, + + /** + * @protected + * @type {string} + */ + axisPointerClass: null, + + /** + * @override + */ + render: function(axisModel, ecModel, api, payload) { + // FIXME + // This process should proformed after coordinate systems updated + // (axis scale updated), and should be performed each time update. + // So put it here temporarily, although it is not appropriate to + // put a model-writing procedure in `view`. + this.axisPointerClass && fixValue(axisModel); + + AxisView.superApply(this, 'render', arguments); + + updateAxisPointer(this, axisModel, ecModel, api, payload, true); + }, + + /** + * Action handler. + * @public + * @param {module:echarts/coord/cartesian/AxisModel} axisModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @param {Object} payload + */ + updateAxisPointer: function(axisModel, ecModel, api, payload, force) { + updateAxisPointer(this, axisModel, ecModel, api, payload, false); + }, + + /** + * @override + */ + remove: function(ecModel, api) { + var axisPointer = this._axisPointer; + axisPointer && axisPointer.remove(api); + AxisView.superApply(this, 'remove', arguments); + }, + + /** + * @override + */ + dispose: function(ecModel, api) { + disposeAxisPointer(this, api); + AxisView.superApply(this, 'dispose', arguments); + } + + }); + + function updateAxisPointer(axisView, axisModel, ecModel, api, payload, forceRender) { + var Clazz = AxisView.getAxisPointerClass(axisView.axisPointerClass); + if (!Clazz) { + return; + } + var axisPointerModel = getAxisPointerModel(axisModel); + axisPointerModel + ? + (axisView._axisPointer || (axisView._axisPointer = new Clazz())) + .render(axisModel, axisPointerModel, api, forceRender) : + disposeAxisPointer(axisView, api); + } + + function disposeAxisPointer(axisView, ecModel, api) { + var axisPointer = axisView._axisPointer; + axisPointer && axisPointer.dispose(ecModel, api); + axisView._axisPointer = null; + } + + var axisPointerClazz = []; + + AxisView.registerAxisPointerClass = function(type, clazz) { + if (__DEV__) { + if (axisPointerClazz[type]) { + throw new Error('axisPointer ' + type + ' exists'); + } + } + axisPointerClazz[type] = clazz; + }; + + AxisView.getAxisPointerClass = function(type) { + return type && axisPointerClazz[type]; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Can only be called after coordinate system creation stage. + * (Can be called before coordinate system update stage). + * + * @param {Object} opt {labelInside} + * @return {Object} { + * position, rotation, labelDirection, labelOffset, + * tickDirection, labelRotate, z2 + * } + */ + function layout$1(gridModel, axisModel, opt) { + opt = opt || {}; + var grid = gridModel.coordinateSystem; + var axis = axisModel.axis; + var layout = {}; + var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0]; + + var rawAxisPosition = axis.position; + var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition; + var axisDim = axis.dim; + + var rect = grid.getRect(); + var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height]; + var idx = { + left: 0, + right: 1, + top: 0, + bottom: 1, + onZero: 2 + }; + var axisOffset = axisModel.get('offset') || 0; + + var posBound = axisDim === 'x' ? + [rectBound[2] - axisOffset, rectBound[3] + axisOffset] : + [rectBound[0] - axisOffset, rectBound[1] + axisOffset]; + + if (otherAxisOnZeroOf) { + var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0)); + posBound[idx['onZero']] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]); + } + + // Axis position + layout.position = [ + axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0], + axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3] + ]; + + // Axis rotation + layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1); + + // Tick and label direction, x y is axisDim + var dirMap = { + top: -1, + bottom: 1, + left: -1, + right: 1 + }; + + layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition]; + layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx['onZero']] : 0; + + if (axisModel.get('axisTick.inside')) { + layout.tickDirection = -layout.tickDirection; + } + if (retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) { + layout.labelDirection = -layout.labelDirection; + } + + // Special label rotation + var labelRotate = axisModel.get('axisLabel.rotate'); + layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate; + + // Over splitLine and splitArea + layout.z2 = 1; + + return layout; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var axisBuilderAttrs = [ + 'axisLine', 'axisTickLabel', 'axisName' + ]; + var selfBuilderAttrs = [ + 'splitArea', 'splitLine' + ]; + + // function getAlignWithLabel(model, axisModel) { + // var alignWithLabel = model.get('alignWithLabel'); + // if (alignWithLabel === 'auto') { + // alignWithLabel = axisModel.get('axisTick.alignWithLabel'); + // } + // return alignWithLabel; + // } + + var CartesianAxisView = AxisView.extend({ + + type: 'cartesianAxis', + + axisPointerClass: 'CartesianAxisPointer', + + /** + * @override + */ + render: function(axisModel, ecModel, api, payload) { + + this.group.removeAll(); + + var oldAxisGroup = this._axisGroup; + this._axisGroup = new Group(); + + this.group.add(this._axisGroup); + + if (!axisModel.get('show')) { + return; + } + + var gridModel = axisModel.getCoordSysModel(); + + var layout = layout$1(gridModel, axisModel); + + var axisBuilder = new AxisBuilder(axisModel, layout); + + each$1(axisBuilderAttrs, axisBuilder.add, axisBuilder); + + this._axisGroup.add(axisBuilder.getGroup()); + + each$1(selfBuilderAttrs, function(name) { + if (axisModel.get(name + '.show')) { + this['_' + name](axisModel, gridModel); + } + }, this); + + groupTransition(oldAxisGroup, this._axisGroup, axisModel); + + CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload); + }, + + remove: function() { + this._splitAreaColors = null; + }, + + /** + * @param {module:echarts/coord/cartesian/AxisModel} axisModel + * @param {module:echarts/coord/cartesian/GridModel} gridModel + * @private + */ + _splitLine: function(axisModel, gridModel) { + var axis = axisModel.axis; + + if (axis.scale.isBlank()) { + return; + } + + var splitLineModel = axisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + + lineColors = isArray(lineColors) ? lineColors : [lineColors]; + + var gridRect = gridModel.coordinateSystem.getRect(); + var isHorizontal = axis.isHorizontal(); + + var lineCount = 0; + + var ticksCoords = axis.getTicksCoords({ + tickModel: splitLineModel + }); + + var p1 = []; + var p2 = []; + + // Simple optimization + // Batching the lines if color are the same + var lineStyle = lineStyleModel.getLineStyle(); + for (var i = 0; i < ticksCoords.length; i++) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + + if (isHorizontal) { + p1[0] = tickCoord; + p1[1] = gridRect.y; + p2[0] = tickCoord; + p2[1] = gridRect.y + gridRect.height; + } else { + p1[0] = gridRect.x; + p1[1] = tickCoord; + p2[0] = gridRect.x + gridRect.width; + p2[1] = tickCoord; + } + + var colorIndex = (lineCount++) % lineColors.length; + var tickValue = ticksCoords[i].tickValue; + this._axisGroup.add(new Line(subPixelOptimizeLine({ + anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null, + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + }, + style: defaults({ + stroke: lineColors[colorIndex] + }, lineStyle), + silent: true + }))); + } + }, + + /** + * @param {module:echarts/coord/cartesian/AxisModel} axisModel + * @param {module:echarts/coord/cartesian/GridModel} gridModel + * @private + */ + _splitArea: function(axisModel, gridModel) { + var axis = axisModel.axis; + + if (axis.scale.isBlank()) { + return; + } + + var splitAreaModel = axisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + + var gridRect = gridModel.coordinateSystem.getRect(); + + var ticksCoords = axis.getTicksCoords({ + tickModel: splitAreaModel, + clamp: true + }); + + if (!ticksCoords.length) { + return; + } + + // For Making appropriate splitArea animation, the color and anid + // should be corresponding to previous one if possible. + var areaColorsLen = areaColors.length; + var lastSplitAreaColors = this._splitAreaColors; + var newSplitAreaColors = createHashMap(); + var colorIndex = 0; + if (lastSplitAreaColors) { + for (var i = 0; i < ticksCoords.length; i++) { + var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue); + if (cIndex != null) { + colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen; + break; + } + } + } + + var prev = axis.toGlobalCoord(ticksCoords[0].coord); + + var areaStyle = areaStyleModel.getAreaStyle(); + areaColors = isArray(areaColors) ? areaColors : [areaColors]; + + for (var i = 1; i < ticksCoords.length; i++) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + + var x; + var y; + var width; + var height; + if (axis.isHorizontal()) { + x = prev; + y = gridRect.y; + width = tickCoord - x; + height = gridRect.height; + prev = x + width; + } else { + x = gridRect.x; + y = prev; + width = gridRect.width; + height = tickCoord - y; + prev = y + height; + } + + var tickValue = ticksCoords[i - 1].tickValue; + tickValue != null && newSplitAreaColors.set(tickValue, colorIndex); + + this._axisGroup.add(new Rect({ + anid: tickValue != null ? 'area_' + tickValue : null, + shape: { + x: x, + y: y, + width: width, + height: height + }, + style: defaults({ + fill: areaColors[colorIndex] + }, areaStyle), + silent: true + })); + + colorIndex = (colorIndex + 1) % areaColorsLen; + } + + this._splitAreaColors = newSplitAreaColors; + } + }); + + CartesianAxisView.extend({ + type: 'xAxis' + }); + CartesianAxisView.extend({ + type: 'yAxis' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Grid view + extendComponentView({ + + type: 'grid', + + render: function(gridModel, ecModel) { + this.group.removeAll(); + if (gridModel.get('show')) { + this.group.add(new Rect({ + shape: gridModel.coordinateSystem.getRect(), + style: defaults({ + fill: gridModel.get('backgroundColor') + }, gridModel.getItemStyle()), + silent: true, + z2: -1 + })); + } + } + + }); + + registerPreprocessor(function(option) { + // Only create grid when need + if (option.xAxis && option.yAxis && !option.grid) { + option.grid = {}; + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // In case developer forget to include grid component + registerVisual(visualSymbol('line', 'circle', 'line')); + registerLayout(pointsLayout('line')); + + // Down sample after filter + registerProcessor( + PRIORITY.PROCESSOR.STATISTIC, + dataSample('line') + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var BaseBarSeries = SeriesModel.extend({ + + type: 'series.__base_bar__', + + getInitialData: function(option, ecModel) { + return createListFromArray(this.getSource(), this); + }, + + getMarkerPosition: function(value) { + var coordSys = this.coordinateSystem; + if (coordSys) { + // PENDING if clamp ? + var pt = coordSys.dataToPoint(coordSys.clampData(value)); + var data = this.getData(); + var offset = data.getLayout('offset'); + var size = data.getLayout('size'); + var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1; + pt[offsetIndex] += offset + size / 2; + return pt; + } + return [NaN, NaN]; + }, + + defaultOption: { + zlevel: 0, // 一级层叠 + z: 2, // 二级层叠 + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + // stack: null + + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + + // 最小高度改为0 + barMinHeight: 0, + // 最小角度为0,仅对极坐标系下的柱状图有效 + barMinAngle: 0, + // cursor: null, + + large: false, + largeThreshold: 400, + progressive: 3e3, + progressiveChunkMode: 'mod', + + // barMaxWidth: null, + // 默认自适应 + // barWidth: null, + // 柱间距离,默认为柱形宽度的30%,可设固定值 + // barGap: '30%', + // 类目间柱形距离,默认为类目间距的20%,可设固定值 + // barCategoryGap: '20%', + // label: { + // show: false + // }, + itemStyle: {}, + emphasis: {} + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + BaseBarSeries.extend({ + + type: 'series.bar', + + dependencies: ['grid', 'polar'], + + brushSelector: 'rect', + + /** + * @override + */ + getProgressive: function() { + // Do not support progressive in normal mode. + return this.get('large') ? + this.get('progressive') : + false; + }, + + /** + * @override + */ + getProgressiveThreshold: function() { + // Do not support progressive in normal mode. + var progressiveThreshold = this.get('progressiveThreshold'); + var largeThreshold = this.get('largeThreshold'); + if (largeThreshold > progressiveThreshold) { + progressiveThreshold = largeThreshold; + } + return progressiveThreshold; + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function setLabel( + normalStyle, hoverStyle, itemModel, color, seriesModel, dataIndex, labelPositionOutside + ) { + var labelModel = itemModel.getModel('label'); + var hoverLabelModel = itemModel.getModel('emphasis.label'); + + setLabelStyle( + normalStyle, hoverStyle, labelModel, hoverLabelModel, { + labelFetcher: seriesModel, + labelDataIndex: dataIndex, + defaultText: getDefaultLabel(seriesModel.getData(), dataIndex), + isRectText: true, + autoColor: color + } + ); + + fixPosition(normalStyle); + fixPosition(hoverStyle); + } + + function fixPosition(style, labelPositionOutside) { + if (style.textPosition === 'outside') { + style.textPosition = labelPositionOutside; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var getBarItemStyle = makeStyleMapper( + [ + ['fill', 'color'], + ['stroke', 'borderColor'], + ['lineWidth', 'borderWidth'], + // Compatitable with 2 + ['stroke', 'barBorderColor'], + ['lineWidth', 'barBorderWidth'], + ['opacity'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ] + ); + + var barItemStyle = { + getBarItemStyle: function(excludes) { + var style = getBarItemStyle(this, excludes); + if (this.getBorderLineDash) { + var lineDash = this.getBorderLineDash(); + lineDash && (style.lineDash = lineDash); + } + return style; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'barBorderWidth']; + + // FIXME + // Just for compatible with ec2. + extend(Model.prototype, barItemStyle); + + extendChartView({ + + type: 'bar', + + render: function(seriesModel, ecModel, api) { + this._updateDrawMode(seriesModel); + + var coordinateSystemType = seriesModel.get('coordinateSystem'); + + if (coordinateSystemType === 'cartesian2d' || + coordinateSystemType === 'polar' + ) { + this._isLargeDraw ? + this._renderLarge(seriesModel, ecModel, api) : + this._renderNormal(seriesModel, ecModel, api); + } else if (__DEV__) { + console.warn('Only cartesian2d and polar supported for bar.'); + } + + return this.group; + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + this._clear(); + this._updateDrawMode(seriesModel); + }, + + incrementalRender: function(params, seriesModel, ecModel, api) { + // Do not support progressive in normal mode. + this._incrementalRenderLarge(params, seriesModel); + }, + + _updateDrawMode: function(seriesModel) { + var isLargeDraw = seriesModel.pipelineContext.large; + if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) { + this._isLargeDraw = isLargeDraw; + this._clear(); + } + }, + + _renderNormal: function(seriesModel, ecModel, api) { + var group = this.group; + var data = seriesModel.getData(); + var oldData = this._data; + + var coord = seriesModel.coordinateSystem; + var baseAxis = coord.getBaseAxis(); + var isHorizontalOrRadial; + + if (coord.type === 'cartesian2d') { + isHorizontalOrRadial = baseAxis.isHorizontal(); + } else if (coord.type === 'polar') { + isHorizontalOrRadial = baseAxis.dim === 'angle'; + } + + var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null; + + data.diff(oldData) + .add(function(dataIndex) { + if (!data.hasValue(dataIndex)) { + return; + } + + var itemModel = data.getItemModel(dataIndex); + var layout = getLayout[coord.type](data, dataIndex, itemModel); + var el = elementCreator[coord.type]( + data, dataIndex, itemModel, layout, isHorizontalOrRadial, animationModel + ); + data.setItemGraphicEl(dataIndex, el); + group.add(el); + + updateStyle( + el, data, dataIndex, itemModel, layout, + seriesModel, isHorizontalOrRadial, coord.type === 'polar' + ); + }) + .update(function(newIndex, oldIndex) { + var el = oldData.getItemGraphicEl(oldIndex); + + if (!data.hasValue(newIndex)) { + group.remove(el); + return; + } + + var itemModel = data.getItemModel(newIndex); + var layout = getLayout[coord.type](data, newIndex, itemModel); + + if (el) { + updateProps(el, { + shape: layout + }, animationModel, newIndex); + } else { + el = elementCreator[coord.type]( + data, newIndex, itemModel, layout, isHorizontalOrRadial, animationModel, true + ); + } + + data.setItemGraphicEl(newIndex, el); + // Add back + group.add(el); + + updateStyle( + el, data, newIndex, itemModel, layout, + seriesModel, isHorizontalOrRadial, coord.type === 'polar' + ); + }) + .remove(function(dataIndex) { + var el = oldData.getItemGraphicEl(dataIndex); + if (coord.type === 'cartesian2d') { + el && removeRect(dataIndex, animationModel, el); + } else { + el && removeSector(dataIndex, animationModel, el); + } + }) + .execute(); + + this._data = data; + }, + + _renderLarge: function(seriesModel, ecModel, api) { + this._clear(); + createLarge(seriesModel, this.group); + }, + + _incrementalRenderLarge: function(params, seriesModel) { + createLarge(seriesModel, this.group, true); + }, + + dispose: noop, + + remove: function(ecModel) { + this._clear(ecModel); + }, + + _clear: function(ecModel) { + var group = this.group; + var data = this._data; + if (ecModel && ecModel.get('animation') && data && !this._isLargeDraw) { + data.eachItemGraphicEl(function(el) { + if (el.type === 'sector') { + removeSector(el.dataIndex, ecModel, el); + } else { + removeRect(el.dataIndex, ecModel, el); + } + }); + } else { + group.removeAll(); + } + this._data = null; + } + + }); + + var elementCreator = { + + cartesian2d: function( + data, dataIndex, itemModel, layout, isHorizontal, + animationModel, isUpdate + ) { + var rect = new Rect({ + shape: extend({}, layout) + }); + + // Animation + if (animationModel) { + var rectShape = rect.shape; + var animateProperty = isHorizontal ? 'height' : 'width'; + var animateTarget = {}; + rectShape[animateProperty] = 0; + animateTarget[animateProperty] = layout[animateProperty]; + graphic[isUpdate ? 'updateProps' : 'initProps'](rect, { + shape: animateTarget + }, animationModel, dataIndex); + } + + return rect; + }, + + polar: function( + data, dataIndex, itemModel, layout, isRadial, + animationModel, isUpdate + ) { + // Keep the same logic with bar in catesion: use end value to control + // direction. Notice that if clockwise is true (by default), the sector + // will always draw clockwisely, no matter whether endAngle is greater + // or less than startAngle. + var clockwise = layout.startAngle < layout.endAngle; + var sector = new Sector({ + shape: defaults({ + clockwise: clockwise + }, layout) + }); + + // Animation + if (animationModel) { + var sectorShape = sector.shape; + var animateProperty = isRadial ? 'r' : 'endAngle'; + var animateTarget = {}; + sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle; + animateTarget[animateProperty] = layout[animateProperty]; + graphic[isUpdate ? 'updateProps' : 'initProps'](sector, { + shape: animateTarget + }, animationModel, dataIndex); + } + + return sector; + } + }; + + function removeRect(dataIndex, animationModel, el) { + // Not show text when animating + el.style.text = null; + updateProps(el, { + shape: { + width: 0 + } + }, animationModel, dataIndex, function() { + el.parent && el.parent.remove(el); + }); + } + + function removeSector(dataIndex, animationModel, el) { + // Not show text when animating + el.style.text = null; + updateProps(el, { + shape: { + r: el.shape.r0 + } + }, animationModel, dataIndex, function() { + el.parent && el.parent.remove(el); + }); + } + + var getLayout = { + cartesian2d: function(data, dataIndex, itemModel) { + var layout = data.getItemLayout(dataIndex); + var fixedLineWidth = getLineWidth(itemModel, layout); + + // fix layout with lineWidth + var signX = layout.width > 0 ? 1 : -1; + var signY = layout.height > 0 ? 1 : -1; + return { + x: layout.x + signX * fixedLineWidth / 2, + y: layout.y + signY * fixedLineWidth / 2, + width: layout.width - signX * fixedLineWidth, + height: layout.height - signY * fixedLineWidth + }; + }, + + polar: function(data, dataIndex, itemModel) { + var layout = data.getItemLayout(dataIndex); + return { + cx: layout.cx, + cy: layout.cy, + r0: layout.r0, + r: layout.r, + startAngle: layout.startAngle, + endAngle: layout.endAngle + }; + } + }; + + function updateStyle( + el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar + ) { + var color = data.getItemVisual(dataIndex, 'color'); + var opacity = data.getItemVisual(dataIndex, 'opacity'); + var itemStyleModel = itemModel.getModel('itemStyle'); + var hoverStyle = itemModel.getModel('emphasis.itemStyle').getBarItemStyle(); + + if (!isPolar) { + el.setShape('r', itemStyleModel.get('barBorderRadius') || 0); + } + + el.useStyle(defaults({ + fill: color, + opacity: opacity + }, + itemStyleModel.getBarItemStyle() + )); + + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && el.attr('cursor', cursorStyle); + + var labelPositionOutside = isHorizontal ? + (layout.height > 0 ? 'bottom' : 'top') : + (layout.width > 0 ? 'left' : 'right'); + + if (!isPolar) { + setLabel( + el.style, hoverStyle, itemModel, color, + seriesModel, dataIndex, labelPositionOutside + ); + } + + setHoverStyle(el, hoverStyle); + } + + // In case width or height are too small. + function getLineWidth(itemModel, rawLayout) { + var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0; + return Math.min(lineWidth, Math.abs(rawLayout.width), Math.abs(rawLayout.height)); + } + + + var LargePath = Path.extend({ + + type: 'largeBar', + + shape: { + points: [] + }, + + buildPath: function(ctx, shape) { + // Drawing lines is more efficient than drawing + // a whole line or drawing rects. + var points = shape.points; + var startPoint = this.__startPoint; + var valueIdx = this.__valueIdx; + + for (var i = 0; i < points.length; i += 2) { + startPoint[this.__valueIdx] = points[i + valueIdx]; + ctx.moveTo(startPoint[0], startPoint[1]); + ctx.lineTo(points[i], points[i + 1]); + } + } + }); + + function createLarge(seriesModel, group, incremental) { + // TODO support polar + var data = seriesModel.getData(); + var startPoint = []; + var valueIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0; + startPoint[1 - valueIdx] = data.getLayout('valueAxisStart'); + + var el = new LargePath({ + shape: { + points: data.getLayout('largePoints') + }, + incremental: !!incremental, + __startPoint: startPoint, + __valueIdx: valueIdx + }); + group.add(el); + setLargeStyle(el, seriesModel, data); + } + + function setLargeStyle(el, seriesModel, data) { + var borderColor = data.getVisual('borderColor') || data.getVisual('color'); + var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(['color', 'borderColor']); + + el.useStyle(itemStyle); + el.style.fill = null; + el.style.stroke = borderColor; + el.style.lineWidth = data.getLayout('barWidth'); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // In case developer forget to include grid component + registerLayout(curry(layout, 'bar')); + // Should after normal bar layout, otherwise it is blocked by normal bar layout. + registerLayout(largeLayout); + + registerVisual({ + seriesType: 'bar', + reset: function(seriesModel) { + // Visual coding for legend + seriesModel.getData().setVisual('legendSymbol', 'roundRect'); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * [Usage]: + * (1) + * createListSimply(seriesModel, ['value']); + * (2) + * createListSimply(seriesModel, { + * coordDimensions: ['value'], + * dimensionsCount: 5 + * }); + * + * @param {module:echarts/model/Series} seriesModel + * @param {Object|Array.} opt opt or coordDimensions + * The options in opt, see `echarts/data/helper/createDimensions` + * @param {Array.} [nameList] + * @return {module:echarts/data/List} + */ + var createListSimply = function(seriesModel, opt, nameList) { + opt = isArray(opt) && { + coordDimensions: opt + } || extend({}, opt); + + var source = seriesModel.getSource(); + + var dimensionsInfo = createDimensions(source, opt); + + var list = new List(dimensionsInfo, seriesModel); + list.initData(source, nameList); + + return list; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Data selectable mixin for chart series. + * To eanble data select, option of series must have `selectedMode`. + * And each data item will use `selected` to toggle itself selected status + */ + + var selectableMixin = { + + /** + * @param {Array.} targetList [{name, value, selected}, ...] + * If targetList is an array, it should like [{name: ..., value: ...}, ...]. + * If targetList is a "List", it must have coordDim: 'value' dimension and name. + */ + updateSelectedMap: function(targetList) { + this._targetList = isArray(targetList) ? targetList.slice() : []; + + this._selectTargetMap = reduce(targetList || [], function(targetMap, target) { + targetMap.set(target.name, target); + return targetMap; + }, createHashMap()); + }, + + /** + * Either name or id should be passed as input here. + * If both of them are defined, id is used. + * + * @param {string|undefined} name name of data + * @param {number|undefined} id dataIndex of data + */ + // PENGING If selectedMode is null ? + select: function(name, id) { + var target = id != null ? + this._targetList[id] : + this._selectTargetMap.get(name); + var selectedMode = this.get('selectedMode'); + if (selectedMode === 'single') { + this._selectTargetMap.each(function(target) { + target.selected = false; + }); + } + target && (target.selected = true); + }, + + /** + * Either name or id should be passed as input here. + * If both of them are defined, id is used. + * + * @param {string|undefined} name name of data + * @param {number|undefined} id dataIndex of data + */ + unSelect: function(name, id) { + var target = id != null ? + this._targetList[id] : + this._selectTargetMap.get(name); + // var selectedMode = this.get('selectedMode'); + // selectedMode !== 'single' && target && (target.selected = false); + target && (target.selected = false); + }, + + /** + * Either name or id should be passed as input here. + * If both of them are defined, id is used. + * + * @param {string|undefined} name name of data + * @param {number|undefined} id dataIndex of data + */ + toggleSelected: function(name, id) { + var target = id != null ? + this._targetList[id] : + this._selectTargetMap.get(name); + if (target != null) { + this[target.selected ? 'unSelect' : 'select'](name, id); + return target.selected; + } + }, + + /** + * Either name or id should be passed as input here. + * If both of them are defined, id is used. + * + * @param {string|undefined} name name of data + * @param {number|undefined} id dataIndex of data + */ + isSelected: function(name, id) { + var target = id != null ? + this._targetList[id] : + this._selectTargetMap.get(name); + return target && target.selected; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PieSeries = extendSeriesModel({ + + type: 'series.pie', + + // Overwrite + init: function(option) { + PieSeries.superApply(this, 'init', arguments); + + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendDataProvider = function() { + return this.getRawData(); + }; + + this.updateSelectedMap(this._createSelectableList()); + + this._defaultLabelLine(option); + }, + + // Overwrite + mergeOption: function(newOption) { + PieSeries.superCall(this, 'mergeOption', newOption); + + this.updateSelectedMap(this._createSelectableList()); + }, + + getInitialData: function(option, ecModel) { + return createListSimply(this, ['value']); + }, + + _createSelectableList: function() { + var data = this.getRawData(); + var valueDim = data.mapDimension('value'); + var targetList = []; + for (var i = 0, len = data.count(); i < len; i++) { + targetList.push({ + name: data.getName(i), + value: data.get(valueDim, i), + selected: retrieveRawAttr(data, i, 'selected') + }); + } + return targetList; + }, + + // Overwrite + getDataParams: function(dataIndex) { + var data = this.getData(); + var params = PieSeries.superCall(this, 'getDataParams', dataIndex); + // FIXME toFixed? + + var valueList = []; + data.each(data.mapDimension('value'), function(value) { + valueList.push(value); + }); + + params.percent = getPercentWithPrecision( + valueList, + dataIndex, + data.hostModel.get('percentPrecision') + ); + + params.$vars.push('percent'); + return params; + }, + + _defaultLabelLine: function(option) { + // Extend labelLine emphasis + defaultEmphasis(option, 'labelLine', ['show']); + + var labelLineNormalOpt = option.labelLine; + var labelLineEmphasisOpt = option.emphasis.labelLine; + // Not show label line if `label.normal.show = false` + labelLineNormalOpt.show = labelLineNormalOpt.show && + option.label.show; + labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && + option.emphasis.label.show; + }, + + defaultOption: { + zlevel: 0, + z: 2, + legendHoverLink: true, + + hoverAnimation: true, + // 默认全局居中 + center: ['50%', '50%'], + radius: [0, '75%'], + // 默认顺时针 + clockwise: true, + startAngle: 90, + // 最小角度改为0 + minAngle: 0, + // 选中时扇区偏移量 + selectedOffset: 10, + // 高亮扇区偏移量 + hoverOffset: 10, + + // If use strategy to avoid label overlapping + avoidLabelOverlap: true, + // 选择模式,默认关闭,可选single,multiple + // selectedMode: false, + // 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积) + // roseType: null, + + percentPrecision: 2, + + // If still show when all data zero. + stillShowZeroSum: true, + + // cursor: null, + + label: { + // If rotate around circle + rotate: false, + show: true, + // 'outer', 'inside', 'center' + position: 'outer' + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + // 默认使用全局文本样式,详见TEXTSTYLE + // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数 + }, + // Enabled when label.normal.position is 'outer' + labelLine: { + show: true, + // 引导线两段中的第一段长度 + length: 15, + // 引导线两段中的第二段长度 + length2: 15, + smooth: false, + lineStyle: { + // color: 各异, + width: 1, + type: 'solid' + } + }, + itemStyle: { + borderWidth: 1 + }, + + // Animation type canbe expansion, scale + animationType: 'expansion', + + animationEasing: 'cubicOut' + } + }); + + mixin(PieSeries, selectableMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/model/Series} seriesModel + * @param {boolean} hasAnimation + * @inner + */ + function updateDataSelected(uid, seriesModel, hasAnimation, api) { + var data = seriesModel.getData(); + var dataIndex = this.dataIndex; + var name = data.getName(dataIndex); + var selectedOffset = seriesModel.get('selectedOffset'); + + api.dispatchAction({ + type: 'pieToggleSelect', + from: uid, + name: name, + seriesId: seriesModel.id + }); + + data.each(function(idx) { + toggleItemSelected( + data.getItemGraphicEl(idx), + data.getItemLayout(idx), + seriesModel.isSelected(data.getName(idx)), + selectedOffset, + hasAnimation + ); + }); + } + + /** + * @param {module:zrender/graphic/Sector} el + * @param {Object} layout + * @param {boolean} isSelected + * @param {number} selectedOffset + * @param {boolean} hasAnimation + * @inner + */ + function toggleItemSelected(el, layout, isSelected, selectedOffset, hasAnimation) { + var midAngle = (layout.startAngle + layout.endAngle) / 2; + + var dx = Math.cos(midAngle); + var dy = Math.sin(midAngle); + + var offset = isSelected ? selectedOffset : 0; + var position = [dx * offset, dy * offset]; + + hasAnimation + // animateTo will stop revious animation like update transition + ? + el.animate() + .when(200, { + position: position + }) + .start('bounceOut') : + el.attr('position', position); + } + + /** + * Piece of pie including Sector, Label, LabelLine + * @constructor + * @extends {module:zrender/graphic/Group} + */ + function PiePiece(data, idx) { + + Group.call(this); + + var sector = new Sector({ + z2: 2 + }); + var polyline = new Polyline(); + var text = new Text(); + this.add(sector); + this.add(polyline); + this.add(text); + + this.updateData(data, idx, true); + + // Hover to change label and labelLine + function onEmphasis() { + polyline.ignore = polyline.hoverIgnore; + text.ignore = text.hoverIgnore; + } + + function onNormal() { + polyline.ignore = polyline.normalIgnore; + text.ignore = text.normalIgnore; + } + this.on('emphasis', onEmphasis) + .on('normal', onNormal) + .on('mouseover', onEmphasis) + .on('mouseout', onNormal); + } + + var piePieceProto = PiePiece.prototype; + + piePieceProto.updateData = function(data, idx, firstCreate) { + + var sector = this.childAt(0); + + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var sectorShape = extend({}, layout); + sectorShape.label = null; + + if (firstCreate) { + sector.setShape(sectorShape); + + var animationType = seriesModel.getShallow('animationType'); + if (animationType === 'scale') { + sector.shape.r = layout.r0; + initProps(sector, { + shape: { + r: layout.r + } + }, seriesModel, idx); + } + // Expansion + else { + sector.shape.endAngle = layout.startAngle; + updateProps(sector, { + shape: { + endAngle: layout.endAngle + } + }, seriesModel, idx); + } + + } else { + updateProps(sector, { + shape: sectorShape + }, seriesModel, idx); + } + + // Update common style + var visualColor = data.getItemVisual(idx, 'color'); + + sector.useStyle( + defaults({ + lineJoin: 'bevel', + fill: visualColor + }, + itemModel.getModel('itemStyle').getItemStyle() + ) + ); + sector.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle(); + + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && sector.attr('cursor', cursorStyle); + + // Toggle selected + toggleItemSelected( + this, + data.getItemLayout(idx), + seriesModel.isSelected(null, idx), + seriesModel.get('selectedOffset'), + seriesModel.get('animation') + ); + + function onEmphasis() { + // Sector may has animation of updating data. Force to move to the last frame + // Or it may stopped on the wrong shape + sector.stopAnimation(true); + sector.animateTo({ + shape: { + r: layout.r + seriesModel.get('hoverOffset') + } + }, 300, 'elasticOut'); + } + + function onNormal() { + sector.stopAnimation(true); + sector.animateTo({ + shape: { + r: layout.r + } + }, 300, 'elasticOut'); + } + sector.off('mouseover').off('mouseout').off('emphasis').off('normal'); + if (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled()) { + sector + .on('mouseover', onEmphasis) + .on('mouseout', onNormal) + .on('emphasis', onEmphasis) + .on('normal', onNormal); + } + + this._updateLabel(data, idx); + + setHoverStyle(this); + }; + + piePieceProto._updateLabel = function(data, idx) { + + var labelLine = this.childAt(1); + var labelText = this.childAt(2); + + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var labelLayout = layout.label; + var visualColor = data.getItemVisual(idx, 'color'); + + updateProps(labelLine, { + shape: { + points: labelLayout.linePoints || [ + [labelLayout.x, labelLayout.y], + [labelLayout.x, labelLayout.y], + [labelLayout.x, labelLayout.y] + ] + } + }, seriesModel, idx); + + updateProps(labelText, { + style: { + x: labelLayout.x, + y: labelLayout.y + } + }, seriesModel, idx); + labelText.attr({ + rotation: labelLayout.rotation, + origin: [labelLayout.x, labelLayout.y], + z2: 10 + }); + + var labelModel = itemModel.getModel('label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + var labelLineModel = itemModel.getModel('labelLine'); + var labelLineHoverModel = itemModel.getModel('emphasis.labelLine'); + var visualColor = data.getItemVisual(idx, 'color'); + + setLabelStyle( + labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel, { + labelFetcher: data.hostModel, + labelDataIndex: idx, + defaultText: data.getName(idx), + autoColor: visualColor, + useInsideStyle: !!labelLayout.inside + }, { + textAlign: labelLayout.textAlign, + textVerticalAlign: labelLayout.verticalAlign, + opacity: data.getItemVisual(idx, 'opacity') + } + ); + + labelText.ignore = labelText.normalIgnore = !labelModel.get('show'); + labelText.hoverIgnore = !labelHoverModel.get('show'); + + labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show'); + labelLine.hoverIgnore = !labelLineHoverModel.get('show'); + + // Default use item visual color + labelLine.setStyle({ + stroke: visualColor, + opacity: data.getItemVisual(idx, 'opacity') + }); + labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle()); + + labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle(); + + var smooth = labelLineModel.get('smooth'); + if (smooth && smooth === true) { + smooth = 0.4; + } + labelLine.setShape({ + smooth: smooth + }); + }; + + inherits(PiePiece, Group); + + + // Pie view + var PieView = Chart.extend({ + + type: 'pie', + + init: function() { + var sectorGroup = new Group(); + this._sectorGroup = sectorGroup; + }, + + render: function(seriesModel, ecModel, api, payload) { + if (payload && (payload.from === this.uid)) { + return; + } + + var data = seriesModel.getData(); + var oldData = this._data; + var group = this.group; + + var hasAnimation = ecModel.get('animation'); + var isFirstRender = !oldData; + var animationType = seriesModel.get('animationType'); + + var onSectorClick = curry( + updateDataSelected, this.uid, seriesModel, hasAnimation, api + ); + + var selectedMode = seriesModel.get('selectedMode'); + + data.diff(oldData) + .add(function(idx) { + var piePiece = new PiePiece(data, idx); + // Default expansion animation + if (isFirstRender && animationType !== 'scale') { + piePiece.eachChild(function(child) { + child.stopAnimation(true); + }); + } + + selectedMode && piePiece.on('click', onSectorClick); + + data.setItemGraphicEl(idx, piePiece); + + group.add(piePiece); + }) + .update(function(newIdx, oldIdx) { + var piePiece = oldData.getItemGraphicEl(oldIdx); + + piePiece.updateData(data, newIdx); + + piePiece.off('click'); + selectedMode && piePiece.on('click', onSectorClick); + group.add(piePiece); + data.setItemGraphicEl(newIdx, piePiece); + }) + .remove(function(idx) { + var piePiece = oldData.getItemGraphicEl(idx); + group.remove(piePiece); + }) + .execute(); + + if ( + hasAnimation && isFirstRender && data.count() > 0 + // Default expansion animation + && + animationType !== 'scale' + ) { + var shape = data.getItemLayout(0); + var r = Math.max(api.getWidth(), api.getHeight()) / 2; + + var removeClipPath = bind(group.removeClipPath, group); + group.setClipPath(this._createClipPath( + shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel + )); + } + + this._data = data; + }, + + dispose: function() {}, + + _createClipPath: function( + cx, cy, r, startAngle, clockwise, cb, seriesModel + ) { + var clipPath = new Sector({ + shape: { + cx: cx, + cy: cy, + r0: 0, + r: r, + startAngle: startAngle, + endAngle: startAngle, + clockwise: clockwise + } + }); + + initProps(clipPath, { + shape: { + endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2 + } + }, seriesModel, cb); + + return clipPath; + }, + + /** + * @implement + */ + containPoint: function(point, seriesModel) { + var data = seriesModel.getData(); + var itemLayout = data.getItemLayout(0); + if (itemLayout) { + var dx = point[0] - itemLayout.cx; + var dy = point[1] - itemLayout.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + return radius <= itemLayout.r && radius >= itemLayout.r0; + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var createDataSelectAction = function(seriesType, actionInfos) { + each$1(actionInfos, function(actionInfo) { + actionInfo.update = 'updateView'; + /** + * @payload + * @property {string} seriesName + * @property {string} name + */ + registerAction(actionInfo, function(payload, ecModel) { + var selected = {}; + ecModel.eachComponent({ + mainType: 'series', + subType: seriesType, + query: payload + }, + function(seriesModel) { + if (seriesModel[actionInfo.method]) { + seriesModel[actionInfo.method]( + payload.name, + payload.dataIndex + ); + } + var data = seriesModel.getData(); + // Create selected map + data.each(function(idx) { + var name = data.getName(idx); + selected[name] = seriesModel.isSelected(name) || + false; + }); + } + ); + return { + name: payload.name, + selected: selected + }; + }); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Pick color from palette for each data item. + // Applicable for charts that require applying color palette + // in data level (like pie, funnel, chord). + var dataColor = function(seriesType) { + return { + getTargetSeries: function(ecModel) { + // Pie and funnel may use diferrent scope + var paletteScope = {}; + var seiresModelMap = createHashMap(); + + ecModel.eachSeriesByType(seriesType, function(seriesModel) { + seriesModel.__paletteScope = paletteScope; + seiresModelMap.set(seriesModel.uid, seriesModel); + }); + + return seiresModelMap; + }, + reset: function(seriesModel, ecModel) { + var dataAll = seriesModel.getRawData(); + var idxMap = {}; + var data = seriesModel.getData(); + + data.each(function(idx) { + var rawIdx = data.getRawIndex(idx); + idxMap[rawIdx] = idx; + }); + + dataAll.each(function(rawIdx) { + var filteredIdx = idxMap[rawIdx]; + + // If series.itemStyle.normal.color is a function. itemVisual may be encoded + var singleDataColor = filteredIdx != null && + data.getItemVisual(filteredIdx, 'color', true); + + if (!singleDataColor) { + // FIXME Performance + var itemModel = dataAll.getItemModel(rawIdx); + + var color = itemModel.get('itemStyle.color') || + seriesModel.getColorFromPalette( + dataAll.getName(rawIdx) || (rawIdx + ''), seriesModel.__paletteScope, + dataAll.count() + ); + // Legend may use the visual info in data before processed + dataAll.setItemVisual(rawIdx, 'color', color); + + // Data is not filtered + if (filteredIdx != null) { + data.setItemVisual(filteredIdx, 'color', color); + } + } else { + // Set data all color for legend + dataAll.setItemVisual(rawIdx, 'color', singleDataColor); + } + }); + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME emphasis label position is not same with normal label position + + function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) { + list.sort(function(a, b) { + return a.y - b.y; + }); + + // 压 + function shiftDown(start, end, delta, dir) { + for (var j = start; j < end; j++) { + list[j].y += delta; + if (j > start && + j + 1 < end && + list[j + 1].y > list[j].y + list[j].height + ) { + shiftUp(j, delta / 2); + return; + } + } + + shiftUp(end - 1, delta / 2); + } + + // 弹 + function shiftUp(end, delta) { + for (var j = end; j >= 0; j--) { + list[j].y -= delta; + if (j > 0 && + list[j].y > list[j - 1].y + list[j - 1].height + ) { + break; + } + } + } + + function changeX(list, isDownList, cx, cy, r, dir) { + var lastDeltaX = dir > 0 ? + isDownList // 右侧 + ? + Number.MAX_VALUE // 下 + : + 0 // 上 + : + isDownList // 左侧 + ? + Number.MAX_VALUE // 下 + : + 0; // 上 + + for (var i = 0, l = list.length; i < l; i++) { + // Not change x for center label + if (list[i].position === 'center') { + continue; + } + var deltaY = Math.abs(list[i].y - cy); + var length = list[i].len; + var length2 = list[i].len2; + var deltaX = (deltaY < r + length) ? + Math.sqrt( + (r + length + length2) * (r + length + length2) - + deltaY * deltaY + ) : + Math.abs(list[i].x - cx); + if (isDownList && deltaX >= lastDeltaX) { + // 右下,左下 + deltaX = lastDeltaX - 10; + } + if (!isDownList && deltaX <= lastDeltaX) { + // 右上,左上 + deltaX = lastDeltaX + 10; + } + + list[i].x = cx + deltaX * dir; + lastDeltaX = deltaX; + } + } + + var lastY = 0; + var delta; + var len = list.length; + var upList = []; + var downList = []; + for (var i = 0; i < len; i++) { + delta = list[i].y - lastY; + if (delta < 0) { + shiftDown(i, len, -delta, dir); + } + lastY = list[i].y + list[i].height; + } + if (viewHeight - lastY < 0) { + shiftUp(len - 1, lastY - viewHeight); + } + for (var i = 0; i < len; i++) { + if (list[i].y >= cy) { + downList.push(list[i]); + } else { + upList.push(list[i]); + } + } + changeX(upList, false, cx, cy, r, dir); + changeX(downList, true, cx, cy, r, dir); + } + + function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) { + var leftList = []; + var rightList = []; + for (var i = 0; i < labelLayoutList.length; i++) { + if (labelLayoutList[i].x < cx) { + leftList.push(labelLayoutList[i]); + } else { + rightList.push(labelLayoutList[i]); + } + } + + adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight); + adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight); + + for (var i = 0; i < labelLayoutList.length; i++) { + var linePoints = labelLayoutList[i].linePoints; + if (linePoints) { + var dist = linePoints[1][0] - linePoints[2][0]; + if (labelLayoutList[i].x < cx) { + linePoints[2][0] = labelLayoutList[i].x + 3; + } else { + linePoints[2][0] = labelLayoutList[i].x - 3; + } + linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y; + linePoints[1][0] = linePoints[2][0] + dist; + } + } + } + + var labelLayout = function(seriesModel, r, viewWidth, viewHeight) { + var data = seriesModel.getData(); + var labelLayoutList = []; + var cx; + var cy; + var hasLabelRotate = false; + + data.each(function(idx) { + var layout = data.getItemLayout(idx); + + var itemModel = data.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + // Use position in normal or emphasis + var labelPosition = labelModel.get('position') || itemModel.get('emphasis.label.position'); + + var labelLineModel = itemModel.getModel('labelLine'); + var labelLineLen = labelLineModel.get('length'); + var labelLineLen2 = labelLineModel.get('length2'); + + var midAngle = (layout.startAngle + layout.endAngle) / 2; + var dx = Math.cos(midAngle); + var dy = Math.sin(midAngle); + + var textX; + var textY; + var linePoints; + var textAlign; + + cx = layout.cx; + cy = layout.cy; + + var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner'; + if (labelPosition === 'center') { + textX = layout.cx; + textY = layout.cy; + textAlign = 'center'; + } else { + var x1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dx : layout.r * dx) + cx; + var y1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dy : layout.r * dy) + cy; + + textX = x1 + dx * 3; + textY = y1 + dy * 3; + + if (!isLabelInside) { + // For roseType + var x2 = x1 + dx * (labelLineLen + r - layout.r); + var y2 = y1 + dy * (labelLineLen + r - layout.r); + var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2); + var y3 = y2; + + textX = x3 + (dx < 0 ? -5 : 5); + textY = y3; + linePoints = [ + [x1, y1], + [x2, y2], + [x3, y3] + ]; + } + + textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right'); + } + var font = labelModel.getFont(); + + var labelRotate = labelModel.get('rotate') ? + (dx < 0 ? -midAngle + Math.PI : -midAngle) : 0; + var text = seriesModel.getFormattedLabel(idx, 'normal') || + data.getName(idx); + var textRect = getBoundingRect( + text, font, textAlign, 'top' + ); + hasLabelRotate = !!labelRotate; + layout.label = { + x: textX, + y: textY, + position: labelPosition, + height: textRect.height, + len: labelLineLen, + len2: labelLineLen2, + linePoints: linePoints, + textAlign: textAlign, + verticalAlign: 'middle', + rotation: labelRotate, + inside: isLabelInside + }; + + // Not layout the inside label + if (!isLabelInside) { + labelLayoutList.push(layout.label); + } + }); + if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) { + avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var PI2$4 = Math.PI * 2; + var RADIAN = Math.PI / 180; + + var pieLayout = function(seriesType, ecModel, api, payload) { + ecModel.eachSeriesByType(seriesType, function(seriesModel) { + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + + var center = seriesModel.get('center'); + var radius = seriesModel.get('radius'); + + if (!isArray(radius)) { + radius = [0, radius]; + } + if (!isArray(center)) { + center = [center, center]; + } + + var width = api.getWidth(); + var height = api.getHeight(); + var size = Math.min(width, height); + var cx = parsePercent$1(center[0], width); + var cy = parsePercent$1(center[1], height); + var r0 = parsePercent$1(radius[0], size / 2); + var r = parsePercent$1(radius[1], size / 2); + + var startAngle = -seriesModel.get('startAngle') * RADIAN; + + var minAngle = seriesModel.get('minAngle') * RADIAN; + + var validDataCount = 0; + data.each(valueDim, function(value) { + !isNaN(value) && validDataCount++; + }); + + var sum = data.getSum(valueDim); + // Sum may be 0 + var unitRadian = Math.PI / (sum || validDataCount) * 2; + + var clockwise = seriesModel.get('clockwise'); + + var roseType = seriesModel.get('roseType'); + var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); + + // [0...max] + var extent = data.getDataExtent(valueDim); + extent[0] = 0; + + // In the case some sector angle is smaller than minAngle + var restAngle = PI2$4; + var valueSumLargerThanMinAngle = 0; + + var currentAngle = startAngle; + var dir = clockwise ? 1 : -1; + + data.each(valueDim, function(value, idx) { + var angle; + if (isNaN(value)) { + data.setItemLayout(idx, { + angle: NaN, + startAngle: NaN, + endAngle: NaN, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: r0, + r: roseType ? + NaN : + r + }); + return; + } + + // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样? + if (roseType !== 'area') { + angle = (sum === 0 && stillShowZeroSum) ? + unitRadian : (value * unitRadian); + } else { + angle = PI2$4 / validDataCount; + } + + if (angle < minAngle) { + angle = minAngle; + restAngle -= minAngle; + } else { + valueSumLargerThanMinAngle += value; + } + + var endAngle = currentAngle + dir * angle; + data.setItemLayout(idx, { + angle: angle, + startAngle: currentAngle, + endAngle: endAngle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: r0, + r: roseType ? + linearMap(value, extent, [r0, r]) : + r + }); + + currentAngle = endAngle; + }); + + // Some sector is constrained by minAngle + // Rest sectors needs recalculate angle + if (restAngle < PI2$4 && validDataCount) { + // Average the angle if rest angle is not enough after all angles is + // Constrained by minAngle + if (restAngle <= 1e-3) { + var angle = PI2$4 / validDataCount; + data.each(valueDim, function(value, idx) { + if (!isNaN(value)) { + var layout = data.getItemLayout(idx); + layout.angle = angle; + layout.startAngle = startAngle + dir * idx * angle; + layout.endAngle = startAngle + dir * (idx + 1) * angle; + } + }); + } else { + unitRadian = restAngle / valueSumLargerThanMinAngle; + currentAngle = startAngle; + data.each(valueDim, function(value, idx) { + if (!isNaN(value)) { + var layout = data.getItemLayout(idx); + var angle = layout.angle === minAngle ? + minAngle : value * unitRadian; + layout.startAngle = currentAngle; + layout.endAngle = currentAngle + dir * angle; + currentAngle += dir * angle; + } + }); + } + } + + labelLayout(seriesModel, r, width, height); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var dataFilter = function(seriesType) { + return { + seriesType: seriesType, + reset: function(seriesModel, ecModel) { + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (!legendModels || !legendModels.length) { + return; + } + var data = seriesModel.getData(); + data.filterSelf(function(idx) { + var name = data.getName(idx); + // If in any legend component the status is not selected. + for (var i = 0; i < legendModels.length; i++) { + if (!legendModels[i].isSelected(name)) { + return false; + } + } + return true; + }); + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + createDataSelectAction('pie', [{ + type: 'pieToggleSelect', + event: 'pieselectchanged', + method: 'toggleSelected' + }, { + type: 'pieSelect', + event: 'pieselected', + method: 'select' + }, { + type: 'pieUnSelect', + event: 'pieunselected', + method: 'unSelect' + }]); + + registerVisual(dataColor('pie')); + registerLayout(curry(pieLayout, 'pie')); + registerProcessor(dataFilter('pie')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.scatter', + + dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'], + + getInitialData: function(option, ecModel) { + return createListFromArray(this.getSource(), this); + }, + + brushSelector: 'point', + + getProgressive: function() { + var progressive = this.option.progressive; + if (progressive == null) { + // PENDING + return this.option.large ? 5e3 : this.get('progressive'); + } + return progressive; + }, + + getProgressiveThreshold: function() { + var progressiveThreshold = this.option.progressiveThreshold; + if (progressiveThreshold == null) { + // PENDING + return this.option.large ? 1e4 : this.get('progressiveThreshold'); + } + return progressiveThreshold; + }, + + defaultOption: { + coordinateSystem: 'cartesian2d', + zlevel: 0, + z: 2, + legendHoverLink: true, + + hoverAnimation: true, + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + + // Polar coordinate system + // polarIndex: 0, + + // Geo coordinate system + // geoIndex: 0, + + // symbol: null, // 图形类型 + symbolSize: 10, // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 + // symbolRotate: null, // 图形旋转控制 + + large: false, + // Available when large is true + largeThreshold: 2000, + // cursor: null, + + // label: { + // show: false + // distance: 5, + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 + // 'inside'|'left'|'right'|'top'|'bottom' + // 默认使用全局文本样式,详见TEXTSTYLE + // }, + itemStyle: { + opacity: 0.8 + // color: 各异 + } + + // progressive: null + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO Batch by color + + var BOOST_SIZE_THRESHOLD = 4; + + var LargeSymbolPath = extendShape({ + + shape: { + points: null + }, + + symbolProxy: null, + + buildPath: function(path, shape) { + var points = shape.points; + var size = shape.size; + + var symbolProxy = this.symbolProxy; + var symbolProxyShape = symbolProxy.shape; + var ctx = path.getContext ? path.getContext() : path; + var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD; + + // Do draw in afterBrush. + if (canBoost) { + return; + } + + for (var i = 0; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + + if (isNaN(x) || isNaN(y)) { + continue; + } + + symbolProxyShape.x = x - size[0] / 2; + symbolProxyShape.y = y - size[1] / 2; + symbolProxyShape.width = size[0]; + symbolProxyShape.height = size[1]; + + symbolProxy.buildPath(path, symbolProxyShape, true); + } + }, + + afterBrush: function(ctx) { + var shape = this.shape; + var points = shape.points; + var size = shape.size; + var canBoost = size[0] < BOOST_SIZE_THRESHOLD; + + if (!canBoost) { + return; + } + + this.setTransform(ctx); + // PENDING If style or other canvas status changed? + for (var i = 0; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + if (isNaN(x) || isNaN(y)) { + continue; + } + // fillRect is faster than building a rect path and draw. + // And it support light globalCompositeOperation. + ctx.fillRect( + x - size[0] / 2, y - size[1] / 2, + size[0], size[1] + ); + } + + this.restoreTransform(ctx); + }, + + findDataIndex: function(x, y) { + // TODO ??? + // Consider transform + + var shape = this.shape; + var points = shape.points; + var size = shape.size; + + var w = Math.max(size[0], 4); + var h = Math.max(size[1], 4); + + // Not consider transform + // Treat each element as a rect + // top down traverse + for (var idx = points.length / 2 - 1; idx >= 0; idx--) { + var i = idx * 2; + var x0 = points[i] - w / 2; + var y0 = points[i + 1] - h / 2; + if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) { + return idx; + } + } + + return -1; + } + }); + + function LargeSymbolDraw() { + this.group = new Group(); + } + + var largeSymbolProto = LargeSymbolDraw.prototype; + + largeSymbolProto.isPersistent = function() { + return !this._incremental; + }; + + /** + * Update symbols draw by new data + * @param {module:echarts/data/List} data + */ + largeSymbolProto.updateData = function(data) { + this.group.removeAll(); + var symbolEl = new LargeSymbolPath({ + rectHover: true, + cursor: 'default' + }); + + symbolEl.setShape({ + points: data.getLayout('symbolPoints') + }); + this._setCommon(symbolEl, data); + this.group.add(symbolEl); + + this._incremental = null; + }; + + largeSymbolProto.updateLayout = function(data) { + if (this._incremental) { + return; + } + + var points = data.getLayout('symbolPoints'); + this.group.eachChild(function(child) { + if (child.startIndex != null) { + var len = (child.endIndex - child.startIndex) * 2; + var byteOffset = child.startIndex * 4 * 2; + points = new Float32Array(points.buffer, byteOffset, len); + } + child.setShape('points', points); + }); + }; + + largeSymbolProto.incrementalPrepareUpdate = function(data) { + this.group.removeAll(); + + this._clearIncremental(); + // Only use incremental displayables when data amount is larger than 2 million. + // PENDING Incremental data? + if (data.count() > 2e6) { + if (!this._incremental) { + this._incremental = new IncrementalDisplayble({ + silent: true + }); + } + this.group.add(this._incremental); + } else { + this._incremental = null; + } + }; + + largeSymbolProto.incrementalUpdate = function(taskParams, data) { + var symbolEl; + if (this._incremental) { + symbolEl = new LargeSymbolPath(); + this._incremental.addDisplayable(symbolEl, true); + } else { + symbolEl = new LargeSymbolPath({ + rectHover: true, + cursor: 'default', + startIndex: taskParams.start, + endIndex: taskParams.end + }); + symbolEl.incremental = true; + this.group.add(symbolEl); + } + + symbolEl.setShape({ + points: data.getLayout('symbolPoints') + }); + this._setCommon(symbolEl, data, !!this._incremental); + }; + + largeSymbolProto._setCommon = function(symbolEl, data, isIncremental) { + var hostModel = data.hostModel; + + // TODO + // if (data.hasItemVisual.symbolSize) { + // // TODO typed array? + // symbolEl.setShape('sizes', data.mapArray( + // function (idx) { + // var size = data.getItemVisual(idx, 'symbolSize'); + // return (size instanceof Array) ? size : [size, size]; + // } + // )); + // } + // else { + var size = data.getVisual('symbolSize'); + symbolEl.setShape('size', (size instanceof Array) ? size : [size, size]); + // } + + // Create symbolProxy to build path for each data + symbolEl.symbolProxy = createSymbol( + data.getVisual('symbol'), 0, 0, 0, 0 + ); + // Use symbolProxy setColor method + symbolEl.setColor = symbolEl.symbolProxy.setColor; + + var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD; + symbolEl.useStyle( + // Draw shadow when doing fillRect is extremely slow. + hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color']) + ); + + var visualColor = data.getVisual('color'); + if (visualColor) { + symbolEl.setColor(visualColor); + } + + if (!isIncremental) { + // Enable tooltip + // PENDING May have performance issue when path is extremely large + symbolEl.seriesIndex = hostModel.seriesIndex; + symbolEl.on('mousemove', function(e) { + symbolEl.dataIndex = null; + var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY); + if (dataIndex >= 0) { + // Provide dataIndex for tooltip + symbolEl.dataIndex = dataIndex + (symbolEl.startIndex || 0); + } + }); + } + }; + + largeSymbolProto.remove = function() { + this._clearIncremental(); + this._incremental = null; + this.group.removeAll(); + }; + + largeSymbolProto._clearIncremental = function() { + var incremental = this._incremental; + if (incremental) { + incremental.clearDisplaybles(); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendChartView({ + + type: 'scatter', + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + var symbolDraw = this._updateSymbolDraw(data, seriesModel); + symbolDraw.updateData(data); + + this._finished = true; + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var symbolDraw = this._updateSymbolDraw(data, seriesModel); + + symbolDraw.incrementalPrepareUpdate(data); + + this._finished = false; + }, + + incrementalRender: function(taskParams, seriesModel, ecModel) { + this._symbolDraw.incrementalUpdate(taskParams, seriesModel.getData()); + + this._finished = taskParams.end === seriesModel.getData().count(); + }, + + updateTransform: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + // Must mark group dirty and make sure the incremental layer will be cleared + // PENDING + this.group.dirty(); + + if (!this._finished || data.count() > 1e4 || !this._symbolDraw.isPersistent()) { + return { + update: true + }; + } else { + var res = pointsLayout().reset(seriesModel); + if (res.progress) { + res.progress({ + start: 0, + end: data.count() + }, data); + } + + this._symbolDraw.updateLayout(data); + } + }, + + _updateSymbolDraw: function(data, seriesModel) { + var symbolDraw = this._symbolDraw; + var pipelineContext = seriesModel.pipelineContext; + var isLargeDraw = pipelineContext.large; + + if (!symbolDraw || isLargeDraw !== this._isLargeDraw) { + symbolDraw && symbolDraw.remove(); + symbolDraw = this._symbolDraw = isLargeDraw ? + new LargeSymbolDraw() : + new SymbolDraw(); + this._isLargeDraw = isLargeDraw; + this.group.removeAll(); + } + + this.group.add(symbolDraw.group); + + return symbolDraw; + }, + + remove: function(ecModel, api) { + this._symbolDraw && this._symbolDraw.remove(true); + this._symbolDraw = null; + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // import * as zrUtil from 'zrender/src/core/util'; + + // In case developer forget to include grid component + registerVisual(visualSymbol('scatter', 'circle')); + registerLayout(pointsLayout('scatter')); + + // echarts.registerProcessor(function (ecModel, api) { + // ecModel.eachSeriesByType('scatter', function (seriesModel) { + // var data = seriesModel.getData(); + // var coordSys = seriesModel.coordinateSystem; + // if (coordSys.type !== 'geo') { + // return; + // } + // var startPt = coordSys.pointToData([0, 0]); + // var endPt = coordSys.pointToData([api.getWidth(), api.getHeight()]); + + // var dims = zrUtil.map(coordSys.dimensions, function (dim) { + // return data.mapDimension(dim); + // }); + // var range = {}; + // range[dims[0]] = [Math.min(startPt[0], endPt[0]), Math.max(startPt[0], endPt[0])]; + // range[dims[1]] = [Math.min(startPt[1], endPt[1]), Math.max(startPt[1], endPt[1])]; + + // data.selectRange(range); + // }); + // }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function IndicatorAxis(dim, scale, radiusExtent) { + Axis.call(this, dim, scale, radiusExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = 'value'; + + this.angle = 0; + + /** + * Indicator name + * @type {string} + */ + this.name = ''; + /** + * @type {module:echarts/model/Model} + */ + this.model; + } + + inherits(IndicatorAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO clockwise + + function Radar(radarModel, ecModel, api) { + + this._model = radarModel; + /** + * Radar dimensions + * @type {Array.} + */ + this.dimensions = []; + + this._indicatorAxes = map(radarModel.getIndicatorModels(), function(indicatorModel, idx) { + var dim = 'indicator_' + idx; + var indicatorAxis = new IndicatorAxis(dim, new IntervalScale()); + indicatorAxis.name = indicatorModel.get('name'); + // Inject model and axis + indicatorAxis.model = indicatorModel; + indicatorModel.axis = indicatorAxis; + this.dimensions.push(dim); + return indicatorAxis; + }, this); + + this.resize(radarModel, api); + + /** + * @type {number} + * @readOnly + */ + this.cx; + /** + * @type {number} + * @readOnly + */ + this.cy; + /** + * @type {number} + * @readOnly + */ + this.r; + /** + * @type {number} + * @readOnly + */ + this.startAngle; + } + + Radar.prototype.getIndicatorAxes = function() { + return this._indicatorAxes; + }; + + Radar.prototype.dataToPoint = function(value, indicatorIndex) { + var indicatorAxis = this._indicatorAxes[indicatorIndex]; + + return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex); + }; + + Radar.prototype.coordToPoint = function(coord, indicatorIndex) { + var indicatorAxis = this._indicatorAxes[indicatorIndex]; + var angle = indicatorAxis.angle; + var x = this.cx + coord * Math.cos(angle); + var y = this.cy - coord * Math.sin(angle); + return [x, y]; + }; + + Radar.prototype.pointToData = function(pt) { + var dx = pt[0] - this.cx; + var dy = pt[1] - this.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + dx /= radius; + dy /= radius; + + var radian = Math.atan2(-dy, dx); + + // Find the closest angle + // FIXME index can calculated directly + var minRadianDiff = Infinity; + var closestAxis; + var closestAxisIdx = -1; + for (var i = 0; i < this._indicatorAxes.length; i++) { + var indicatorAxis = this._indicatorAxes[i]; + var diff = Math.abs(radian - indicatorAxis.angle); + if (diff < minRadianDiff) { + closestAxis = indicatorAxis; + closestAxisIdx = i; + minRadianDiff = diff; + } + } + + return [closestAxisIdx, +(closestAxis && closestAxis.coodToData(radius))]; + }; + + Radar.prototype.resize = function(radarModel, api) { + var center = radarModel.get('center'); + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + var viewSize = Math.min(viewWidth, viewHeight) / 2; + this.cx = parsePercent$1(center[0], viewWidth); + this.cy = parsePercent$1(center[1], viewHeight); + + this.startAngle = radarModel.get('startAngle') * Math.PI / 180; + + this.r = parsePercent$1(radarModel.get('radius'), viewSize); + + each$1(this._indicatorAxes, function(indicatorAxis, idx) { + indicatorAxis.setExtent(0, this.r); + var angle = (this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length); + // Normalize to [-PI, PI] + angle = Math.atan2(Math.sin(angle), Math.cos(angle)); + indicatorAxis.angle = angle; + }, this); + }; + + Radar.prototype.update = function(ecModel, api) { + var indicatorAxes = this._indicatorAxes; + var radarModel = this._model; + each$1(indicatorAxes, function(indicatorAxis) { + indicatorAxis.scale.setExtent(Infinity, -Infinity); + }); + ecModel.eachSeriesByType('radar', function(radarSeries, idx) { + if (radarSeries.get('coordinateSystem') !== 'radar' || + ecModel.getComponent('radar', radarSeries.get('radarIndex')) !== radarModel + ) { + return; + } + var data = radarSeries.getData(); + each$1(indicatorAxes, function(indicatorAxis) { + indicatorAxis.scale.unionExtentFromData(data, data.mapDimension(indicatorAxis.dim)); + }); + }, this); + + var splitNumber = radarModel.get('splitNumber'); + + function increaseInterval(interval) { + var exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10)); + // Increase interval + var f = interval / exp10; + if (f === 2) { + f = 5; + } else { // f is 2 or 5 + f *= 2; + } + return f * exp10; + } + // Force all the axis fixing the maxSplitNumber. + each$1(indicatorAxes, function(indicatorAxis, idx) { + var rawExtent = getScaleExtent(indicatorAxis.scale, indicatorAxis.model); + niceScaleExtent(indicatorAxis.scale, indicatorAxis.model); + + var axisModel = indicatorAxis.model; + var scale = indicatorAxis.scale; + var fixedMin = axisModel.getMin(); + var fixedMax = axisModel.getMax(); + var interval = scale.getInterval(); + + if (fixedMin != null && fixedMax != null) { + // User set min, max, divide to get new interval + scale.setExtent(+fixedMin, +fixedMax); + scale.setInterval( + (fixedMax - fixedMin) / splitNumber + ); + } else if (fixedMin != null) { + var max; + // User set min, expand extent on the other side + do { + max = fixedMin + interval * splitNumber; + scale.setExtent(+fixedMin, max); + // Interval must been set after extent + // FIXME + scale.setInterval(interval); + + interval = increaseInterval(interval); + } while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1])); + } else if (fixedMax != null) { + var min; + // User set min, expand extent on the other side + do { + min = fixedMax - interval * splitNumber; + scale.setExtent(min, +fixedMax); + scale.setInterval(interval); + interval = increaseInterval(interval); + } while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0])); + } else { + var nicedSplitNumber = scale.getTicks().length - 1; + if (nicedSplitNumber > splitNumber) { + interval = increaseInterval(interval); + } + // PENDING + var center = Math.round((rawExtent[0] + rawExtent[1]) / 2 / interval) * interval; + var halfSplitNumber = Math.round(splitNumber / 2); + scale.setExtent( + round$1(center - halfSplitNumber * interval), + round$1(center + (splitNumber - halfSplitNumber) * interval) + ); + scale.setInterval(interval); + } + }); + }; + + /** + * Radar dimensions is based on the data + * @type {Array} + */ + Radar.dimensions = []; + + Radar.create = function(ecModel, api) { + var radarList = []; + ecModel.eachComponent('radar', function(radarModel) { + var radar = new Radar(radarModel, ecModel, api); + radarList.push(radar); + radarModel.coordinateSystem = radar; + }); + ecModel.eachSeriesByType('radar', function(radarSeries) { + if (radarSeries.get('coordinateSystem') === 'radar') { + // Inject coordinate system + radarSeries.coordinateSystem = radarList[radarSeries.get('radarIndex') || 0]; + } + }); + return radarList; + }; + + CoordinateSystemManager.register('radar', Radar); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var valueAxisDefault = axisDefault.valueAxis; + + function defaultsShow(opt, show) { + return defaults({ + show: show + }, opt); + } + + var RadarModel = extendComponentModel({ + + type: 'radar', + + optionUpdated: function() { + var boundaryGap = this.get('boundaryGap'); + var splitNumber = this.get('splitNumber'); + var scale = this.get('scale'); + var axisLine = this.get('axisLine'); + var axisTick = this.get('axisTick'); + var axisLabel = this.get('axisLabel'); + var nameTextStyle = this.get('name'); + var showName = this.get('name.show'); + var nameFormatter = this.get('name.formatter'); + var nameGap = this.get('nameGap'); + var triggerEvent = this.get('triggerEvent'); + + var indicatorModels = map(this.get('indicator') || [], function(indicatorOpt) { + // PENDING + if (indicatorOpt.max != null && indicatorOpt.max > 0 && !indicatorOpt.min) { + indicatorOpt.min = 0; + } else if (indicatorOpt.min != null && indicatorOpt.min < 0 && !indicatorOpt.max) { + indicatorOpt.max = 0; + } + var iNameTextStyle = nameTextStyle; + if (indicatorOpt.color != null) { + iNameTextStyle = defaults({ + color: indicatorOpt.color + }, nameTextStyle); + } + // Use same configuration + indicatorOpt = merge(clone(indicatorOpt), { + boundaryGap: boundaryGap, + splitNumber: splitNumber, + scale: scale, + axisLine: axisLine, + axisTick: axisTick, + axisLabel: axisLabel, + // Competitable with 2 and use text + name: indicatorOpt.text, + nameLocation: 'end', + nameGap: nameGap, + // min: 0, + nameTextStyle: iNameTextStyle, + triggerEvent: triggerEvent + }, false); + if (!showName) { + indicatorOpt.name = ''; + } + if (typeof nameFormatter === 'string') { + var indName = indicatorOpt.name; + indicatorOpt.name = nameFormatter.replace('{value}', indName != null ? indName : ''); + } else if (typeof nameFormatter === 'function') { + indicatorOpt.name = nameFormatter( + indicatorOpt.name, indicatorOpt + ); + } + var model = extend( + new Model(indicatorOpt, null, this.ecModel), + axisModelCommonMixin + ); + + // For triggerEvent. + model.mainType = 'radar'; + model.componentIndex = this.componentIndex; + + return model; + }, this); + + this.getIndicatorModels = function() { + return indicatorModels; + }; + }, + + defaultOption: { + + zlevel: 0, + + z: 0, + + center: ['50%', '50%'], + + radius: '75%', + + startAngle: 90, + + name: { + show: true + // formatter: null + // textStyle: {} + }, + + boundaryGap: [0, 0], + + splitNumber: 5, + + nameGap: 15, + + scale: false, + + // Polygon or circle + shape: 'polygon', + + axisLine: merge({ + lineStyle: { + color: '#bbb' + } + }, + valueAxisDefault.axisLine + ), + axisLabel: defaultsShow(valueAxisDefault.axisLabel, false), + axisTick: defaultsShow(valueAxisDefault.axisTick, false), + splitLine: defaultsShow(valueAxisDefault.splitLine, true), + splitArea: defaultsShow(valueAxisDefault.splitArea, true), + + // {text, min, max} + indicator: [] + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var axisBuilderAttrs$1 = [ + 'axisLine', 'axisTickLabel', 'axisName' + ]; + + extendComponentView({ + + type: 'radar', + + render: function(radarModel, ecModel, api) { + var group = this.group; + group.removeAll(); + + this._buildAxes(radarModel); + this._buildSplitLineAndArea(radarModel); + }, + + _buildAxes: function(radarModel) { + var radar = radarModel.coordinateSystem; + var indicatorAxes = radar.getIndicatorAxes(); + var axisBuilders = map(indicatorAxes, function(indicatorAxis) { + var axisBuilder = new AxisBuilder(indicatorAxis.model, { + position: [radar.cx, radar.cy], + rotation: indicatorAxis.angle, + labelDirection: -1, + tickDirection: -1, + nameDirection: 1 + }); + return axisBuilder; + }); + + each$1(axisBuilders, function(axisBuilder) { + each$1(axisBuilderAttrs$1, axisBuilder.add, axisBuilder); + this.group.add(axisBuilder.getGroup()); + }, this); + }, + + _buildSplitLineAndArea: function(radarModel) { + var radar = radarModel.coordinateSystem; + var indicatorAxes = radar.getIndicatorAxes(); + if (!indicatorAxes.length) { + return; + } + var shape = radarModel.get('shape'); + var splitLineModel = radarModel.getModel('splitLine'); + var splitAreaModel = radarModel.getModel('splitArea'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + + var showSplitLine = splitLineModel.get('show'); + var showSplitArea = splitAreaModel.get('show'); + var splitLineColors = lineStyleModel.get('color'); + var splitAreaColors = areaStyleModel.get('color'); + + splitLineColors = isArray(splitLineColors) ? splitLineColors : [splitLineColors]; + splitAreaColors = isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors]; + + var splitLines = []; + var splitAreas = []; + + function getColorIndex(areaOrLine, areaOrLineColorList, idx) { + var colorIndex = idx % areaOrLineColorList.length; + areaOrLine[colorIndex] = areaOrLine[colorIndex] || []; + return colorIndex; + } + + if (shape === 'circle') { + var ticksRadius = indicatorAxes[0].getTicksCoords(); + var cx = radar.cx; + var cy = radar.cy; + for (var i = 0; i < ticksRadius.length; i++) { + if (showSplitLine) { + var colorIndex = getColorIndex(splitLines, splitLineColors, i); + splitLines[colorIndex].push(new Circle({ + shape: { + cx: cx, + cy: cy, + r: ticksRadius[i].coord + } + })); + } + if (showSplitArea && i < ticksRadius.length - 1) { + var colorIndex = getColorIndex(splitAreas, splitAreaColors, i); + splitAreas[colorIndex].push(new Ring({ + shape: { + cx: cx, + cy: cy, + r0: ticksRadius[i].coord, + r: ticksRadius[i + 1].coord + } + })); + } + } + } + // Polyyon + else { + var realSplitNumber; + var axesTicksPoints = map(indicatorAxes, function(indicatorAxis, idx) { + var ticksCoords = indicatorAxis.getTicksCoords(); + realSplitNumber = realSplitNumber == null ? + ticksCoords.length - 1 : + Math.min(ticksCoords.length - 1, realSplitNumber); + return map(ticksCoords, function(tickCoord) { + return radar.coordToPoint(tickCoord.coord, idx); + }); + }); + + var prevPoints = []; + for (var i = 0; i <= realSplitNumber; i++) { + var points = []; + for (var j = 0; j < indicatorAxes.length; j++) { + points.push(axesTicksPoints[j][i]); + } + // Close + if (points[0]) { + points.push(points[0].slice()); + } else { + if (__DEV__) { + console.error('Can\'t draw value axis ' + i); + } + } + + if (showSplitLine) { + var colorIndex = getColorIndex(splitLines, splitLineColors, i); + splitLines[colorIndex].push(new Polyline({ + shape: { + points: points + } + })); + } + if (showSplitArea && prevPoints) { + var colorIndex = getColorIndex(splitAreas, splitAreaColors, i - 1); + splitAreas[colorIndex].push(new Polygon({ + shape: { + points: points.concat(prevPoints) + } + })); + } + prevPoints = points.slice().reverse(); + } + } + + var lineStyle = lineStyleModel.getLineStyle(); + var areaStyle = areaStyleModel.getAreaStyle(); + // Add splitArea before splitLine + each$1(splitAreas, function(splitAreas, idx) { + this.group.add(mergePath( + splitAreas, { + style: defaults({ + stroke: 'none', + fill: splitAreaColors[idx % splitAreaColors.length] + }, areaStyle), + silent: true + } + )); + }, this); + + each$1(splitLines, function(splitLines, idx) { + this.group.add(mergePath( + splitLines, { + style: defaults({ + fill: 'none', + stroke: splitLineColors[idx % splitLineColors.length] + }, lineStyle), + silent: true + } + )); + }, this); + + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var RadarSeries = SeriesModel.extend({ + + type: 'series.radar', + + dependencies: ['radar'], + + + // Overwrite + init: function(option) { + RadarSeries.superApply(this, 'init', arguments); + + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendDataProvider = function() { + return this.getRawData(); + }; + }, + + getInitialData: function(option, ecModel) { + return createListSimply(this, { + generateCoord: 'indicator_', + generateCoordCount: Infinity + }); + }, + + formatTooltip: function(dataIndex) { + var data = this.getData(); + var coordSys = this.coordinateSystem; + var indicatorAxes = coordSys.getIndicatorAxes(); + var name = this.getData().getName(dataIndex); + return encodeHTML(name === '' ? this.name : name) + '
' + + map(indicatorAxes, function(axis, idx) { + var val = data.get(data.mapDimension(axis.dim), dataIndex); + return encodeHTML(axis.name + ' : ' + val); + }).join('
'); + }, + + defaultOption: { + zlevel: 0, + z: 2, + coordinateSystem: 'radar', + legendHoverLink: true, + radarIndex: 0, + lineStyle: { + width: 2, + type: 'solid' + }, + label: { + position: 'top' + }, + // areaStyle: { + // }, + // itemStyle: {} + symbol: 'emptyCircle', + symbolSize: 4 + // symbolRotate: null + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function normalizeSymbolSize(symbolSize) { + if (!isArray(symbolSize)) { + symbolSize = [+symbolSize, +symbolSize]; + } + return symbolSize; + } + + extendChartView({ + + type: 'radar', + + render: function(seriesModel, ecModel, api) { + var polar = seriesModel.coordinateSystem; + var group = this.group; + + var data = seriesModel.getData(); + var oldData = this._data; + + function createSymbol$$1(data, idx) { + var symbolType = data.getItemVisual(idx, 'symbol') || 'circle'; + var color = data.getItemVisual(idx, 'color'); + if (symbolType === 'none') { + return; + } + var symbolSize = normalizeSymbolSize( + data.getItemVisual(idx, 'symbolSize') + ); + var symbolPath = createSymbol( + symbolType, -1, -1, 2, 2, color + ); + symbolPath.attr({ + style: { + strokeNoScale: true + }, + z2: 100, + scale: [symbolSize[0] / 2, symbolSize[1] / 2] + }); + return symbolPath; + } + + function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) { + // Simply rerender all + symbolGroup.removeAll(); + for (var i = 0; i < newPoints.length - 1; i++) { + var symbolPath = createSymbol$$1(data, idx); + if (symbolPath) { + symbolPath.__dimIdx = i; + if (oldPoints[i]) { + symbolPath.attr('position', oldPoints[i]); + graphic[isInit ? 'initProps' : 'updateProps']( + symbolPath, { + position: newPoints[i] + }, seriesModel, idx + ); + } else { + symbolPath.attr('position', newPoints[i]); + } + symbolGroup.add(symbolPath); + } + } + } + + function getInitialPoints(points) { + return map(points, function(pt) { + return [polar.cx, polar.cy]; + }); + } + data.diff(oldData) + .add(function(idx) { + var points = data.getItemLayout(idx); + if (!points) { + return; + } + var polygon = new Polygon(); + var polyline = new Polyline(); + var target = { + shape: { + points: points + } + }; + polygon.shape.points = getInitialPoints(points); + polyline.shape.points = getInitialPoints(points); + initProps(polygon, target, seriesModel, idx); + initProps(polyline, target, seriesModel, idx); + + var itemGroup = new Group(); + var symbolGroup = new Group(); + itemGroup.add(polyline); + itemGroup.add(polygon); + itemGroup.add(symbolGroup); + + updateSymbols( + polyline.shape.points, points, symbolGroup, data, idx, true + ); + + data.setItemGraphicEl(idx, itemGroup); + }) + .update(function(newIdx, oldIdx) { + var itemGroup = oldData.getItemGraphicEl(oldIdx); + var polyline = itemGroup.childAt(0); + var polygon = itemGroup.childAt(1); + var symbolGroup = itemGroup.childAt(2); + var target = { + shape: { + points: data.getItemLayout(newIdx) + } + }; + if (!target.shape.points) { + return; + } + updateSymbols( + polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false + ); + + updateProps(polyline, target, seriesModel); + updateProps(polygon, target, seriesModel); + + data.setItemGraphicEl(newIdx, itemGroup); + }) + .remove(function(idx) { + group.remove(oldData.getItemGraphicEl(idx)); + }) + .execute(); + + data.eachItemGraphicEl(function(itemGroup, idx) { + var itemModel = data.getItemModel(idx); + var polyline = itemGroup.childAt(0); + var polygon = itemGroup.childAt(1); + var symbolGroup = itemGroup.childAt(2); + var color = data.getItemVisual(idx, 'color'); + + group.add(itemGroup); + + polyline.useStyle( + defaults( + itemModel.getModel('lineStyle').getLineStyle(), { + fill: 'none', + stroke: color + } + ) + ); + polyline.hoverStyle = itemModel.getModel('emphasis.lineStyle').getLineStyle(); + + var areaStyleModel = itemModel.getModel('areaStyle'); + var hoverAreaStyleModel = itemModel.getModel('emphasis.areaStyle'); + var polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty(); + var hoverPolygonIgnore = hoverAreaStyleModel.isEmpty() && hoverAreaStyleModel.parentModel.isEmpty(); + + hoverPolygonIgnore = hoverPolygonIgnore && polygonIgnore; + polygon.ignore = polygonIgnore; + + polygon.useStyle( + defaults( + areaStyleModel.getAreaStyle(), { + fill: color, + opacity: 0.7 + } + ) + ); + polygon.hoverStyle = hoverAreaStyleModel.getAreaStyle(); + + var itemStyle = itemModel.getModel('itemStyle').getItemStyle(['color']); + var itemHoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle(); + var labelModel = itemModel.getModel('label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + symbolGroup.eachChild(function(symbolPath) { + symbolPath.setStyle(itemStyle); + symbolPath.hoverStyle = clone(itemHoverStyle); + + setLabelStyle( + symbolPath.style, symbolPath.hoverStyle, labelModel, labelHoverModel, { + labelFetcher: data.hostModel, + labelDataIndex: idx, + labelDimIndex: symbolPath.__dimIdx, + defaultText: data.get(data.dimensions[symbolPath.__dimIdx], idx), + autoColor: color, + isRectText: true + } + ); + }); + + function onEmphasis() { + polygon.attr('ignore', hoverPolygonIgnore); + } + + function onNormal() { + polygon.attr('ignore', polygonIgnore); + } + + itemGroup.off('mouseover').off('mouseout').off('normal').off('emphasis'); + itemGroup.on('emphasis', onEmphasis) + .on('mouseover', onEmphasis) + .on('normal', onNormal) + .on('mouseout', onNormal); + + setHoverStyle(itemGroup); + }); + + this._data = data; + }, + + remove: function() { + this.group.removeAll(); + this._data = null; + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var radarLayout = function(ecModel) { + ecModel.eachSeriesByType('radar', function(seriesModel) { + var data = seriesModel.getData(); + var points = []; + var coordSys = seriesModel.coordinateSystem; + if (!coordSys) { + return; + } + + function pointsConverter(val, idx) { + points[idx] = points[idx] || []; + points[idx][i] = coordSys.dataToPoint(val, i); + } + var axes = coordSys.getIndicatorAxes(); + for (var i = 0; i < axes.length; i++) { + data.each(data.mapDimension(axes[i].dim), pointsConverter); + } + + data.each(function(idx) { + // Close polygon + points[idx][0] && points[idx].push(points[idx][0].slice()); + data.setItemLayout(idx, points[idx]); + }); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Backward compat for radar chart in 2 + var backwardCompat$1 = function(option) { + var polarOptArr = option.polar; + if (polarOptArr) { + if (!isArray(polarOptArr)) { + polarOptArr = [polarOptArr]; + } + var polarNotRadar = []; + each$1(polarOptArr, function(polarOpt, idx) { + if (polarOpt.indicator) { + if (polarOpt.type && !polarOpt.shape) { + polarOpt.shape = polarOpt.type; + } + option.radar = option.radar || []; + if (!isArray(option.radar)) { + option.radar = [option.radar]; + } + option.radar.push(polarOpt); + } else { + polarNotRadar.push(polarOpt); + } + }); + option.polar = polarNotRadar; + } + each$1(option.series, function(seriesOpt) { + if (seriesOpt && seriesOpt.type === 'radar' && seriesOpt.polarIndex) { + seriesOpt.radarIndex = seriesOpt.polarIndex; + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + // Must use radar component + registerVisual(dataColor('radar')); + registerVisual(visualSymbol('radar', 'circle')); + registerLayout(radarLayout); + registerProcessor(dataFilter('radar')); + registerPreprocessor(backwardCompat$1); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Simple view coordinate system + * Mapping given x, y to transformd view x, y + */ + + var v2ApplyTransform$1 = applyTransform; + + // Dummy transform node + function TransformDummy() { + Transformable.call(this); + } + mixin(TransformDummy, Transformable); + + function View(name) { + /** + * @type {string} + */ + this.name = name; + + /** + * @type {Object} + */ + this.zoomLimit; + + Transformable.call(this); + + this._roamTransformable = new TransformDummy(); + + this._rawTransformable = new TransformDummy(); + + this._center; + this._zoom; + } + + View.prototype = { + + constructor: View, + + type: 'view', + + /** + * @param {Array.} + * @readOnly + */ + dimensions: ['x', 'y'], + + /** + * Set bounding rect + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + + // PENDING to getRect + setBoundingRect: function(x, y, width, height) { + this._rect = new BoundingRect(x, y, width, height); + return this._rect; + }, + + /** + * @return {module:zrender/core/BoundingRect} + */ + // PENDING to getRect + getBoundingRect: function() { + return this._rect; + }, + + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + setViewRect: function(x, y, width, height) { + this.transformTo(x, y, width, height); + this._viewRect = new BoundingRect(x, y, width, height); + }, + + /** + * Transformed to particular position and size + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + transformTo: function(x, y, width, height) { + var rect = this.getBoundingRect(); + var rawTransform = this._rawTransformable; + + rawTransform.transform = rect.calculateTransform( + new BoundingRect(x, y, width, height) + ); + + rawTransform.decomposeTransform(); + + this._updateTransform(); + }, + + /** + * Set center of view + * @param {Array.} [centerCoord] + */ + setCenter: function(centerCoord) { + if (!centerCoord) { + return; + } + this._center = centerCoord; + + this._updateCenterAndZoom(); + }, + + /** + * @param {number} zoom + */ + setZoom: function(zoom) { + zoom = zoom || 1; + + var zoomLimit = this.zoomLimit; + if (zoomLimit) { + if (zoomLimit.max != null) { + zoom = Math.min(zoomLimit.max, zoom); + } + if (zoomLimit.min != null) { + zoom = Math.max(zoomLimit.min, zoom); + } + } + this._zoom = zoom; + + this._updateCenterAndZoom(); + }, + + /** + * Get default center without roam + */ + getDefaultCenter: function() { + // Rect before any transform + var rawRect = this.getBoundingRect(); + var cx = rawRect.x + rawRect.width / 2; + var cy = rawRect.y + rawRect.height / 2; + + return [cx, cy]; + }, + + getCenter: function() { + return this._center || this.getDefaultCenter(); + }, + + getZoom: function() { + return this._zoom || 1; + }, + + /** + * @return {Array.} data + * @param {boolean} noRoam + * @param {Array.} [out] + * @return {Array.} + */ + dataToPoint: function(data, noRoam, out) { + var transform = noRoam ? this._rawTransform : this.transform; + out = out || []; + return transform ? + v2ApplyTransform$1(out, data, transform) : + copy(out, data); + }, + + /** + * Convert a (x, y) point to (lon, lat) data + * @param {Array.} point + * @return {Array.} + */ + pointToData: function(point) { + var invTransform = this.invTransform; + return invTransform ? + v2ApplyTransform$1([], point, invTransform) : + [point[0], point[1]]; + }, + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + convertToPixel: curry(doConvert$1, 'dataToPoint'), + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + convertFromPixel: curry(doConvert$1, 'pointToData'), + + /** + * @implements + * see {module:echarts/CoodinateSystem} + */ + containPoint: function(point) { + return this.getViewRectAfterRoam().contain(point[0], point[1]); + } + + /** + * @return {number} + */ + // getScalarScale: function () { + // // Use determinant square root of transform to mutiply scalar + // var m = this.transform; + // var det = Math.sqrt(Math.abs(m[0] * m[3] - m[2] * m[1])); + // return det; + // } + }; + + mixin(View, Transformable); + + function doConvert$1(methodName, ecModel, finder, value) { + var seriesModel = finder.seriesModel; + var coordSys = seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph. + return coordSys === this ? coordSys[methodName](value) : null; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Fix for 南海诸岛 + + var geoCoord = [126, 25]; + + var points$1 = [ + [ + [0, 3.5], + [7, 11.2], + [15, 11.9], + [30, 7], + [42, 0.7], + [52, 0.7], + [56, 7.7], + [59, 0.7], + [64, 0.7], + [64, 0], + [5, 0], + [0, 3.5] + ], + [ + [13, 16.1], + [19, 14.7], + [16, 21.7], + [11, 23.1], + [13, 16.1] + ], + [ + [12, 32.2], + [14, 38.5], + [15, 38.5], + [13, 32.2], + [12, 32.2] + ], + [ + [16, 47.6], + [12, 53.2], + [13, 53.2], + [18, 47.6], + [16, 47.6] + ], + [ + [6, 64.4], + [8, 70], + [9, 70], + [8, 64.4], + [6, 64.4] + ], + [ + [23, 82.6], + [29, 79.8], + [30, 79.8], + [25, 82.6], + [23, 82.6] + ], + [ + [37, 70.7], + [43, 62.3], + [44, 62.3], + [39, 70.7], + [37, 70.7] + ], + [ + [48, 51.1], + [51, 45.5], + [53, 45.5], + [50, 51.1], + [48, 51.1] + ], + [ + [51, 35], + [51, 28.7], + [53, 28.7], + [53, 35], + [51, 35] + ], + [ + [52, 22.4], + [55, 17.5], + [56, 17.5], + [53, 22.4], + [52, 22.4] + ], + [ + [58, 12.6], + [62, 7], + [63, 7], + [60, 12.6], + [58, 12.6] + ], + [ + [0, 3.5], + [0, 93.1], + [64, 93.1], + [64, 0], + [63, 0], + [63, 92.4], + [1, 92.4], + [1, 3.5], + [0, 3.5] + ] + ]; + + for (var i$1 = 0; i$1 < points$1.length; i$1++) { + for (var k = 0; k < points$1[i$1].length; k++) { + points$1[i$1][k][0] /= 10.5; + points$1[i$1][k][1] /= -10.5 / 0.75; + + points$1[i$1][k][0] += geoCoord[0]; + points$1[i$1][k][1] += geoCoord[1]; + } + } + + var fixNanhai = function(geo) { + if (geo.map === 'china') { + geo.regions.push(new Region( + '南海诸岛', + map(points$1, function(exterior) { + return { + type: 'polygon', + exterior: exterior + }; + }), geoCoord + )); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var coordsOffsetMap = { + '南海诸岛': [32, 80], + // 全国 + '广东': [0, -10], + '香港': [10, 5], + '澳门': [-10, 10], + //'北京': [-10, 0], + '天津': [5, 5] + }; + + var fixTextCoord = function(geo) { + each$1(geo.regions, function(region) { + var coordFix = coordsOffsetMap[region.name]; + if (coordFix) { + var cp = region.center; + cp[0] += coordFix[0] / 10.5; + cp[1] += -coordFix[1] / (10.5 / 0.75); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var geoCoordMap = { + 'Russia': [100, 60], + 'United States': [-99, 38], + 'United States of America': [-99, 38] + }; + + var fixGeoCoord = function(geo) { + each$1(geo.regions, function(region) { + var geoCoord = geoCoordMap[region.name]; + if (geoCoord) { + var cp = region.center; + cp[0] = geoCoord[0]; + cp[1] = geoCoord[1]; + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Fix for 钓鱼岛 + + // var Region = require('../Region'); + // var zrUtil = require('zrender/src/core/util'); + + // var geoCoord = [126, 25]; + + var points$2 = [ + [ + [123.45165252685547, 25.73527164402261], + [123.49731445312499, 25.73527164402261], + [123.49731445312499, 25.750734064600884], + [123.45165252685547, 25.750734064600884], + [123.45165252685547, 25.73527164402261] + ] + ]; + + var fixDiaoyuIsland = function(geo) { + if (geo.map === 'china') { + for (var i = 0, len = geo.regions.length; i < len; ++i) { + if (geo.regions[i].name === '台湾') { + geo.regions[i].geometries.push({ + type: 'polygon', + exterior: points$2[0] + }); + } + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Geo fix functions + var geoFixFuncs = [ + fixNanhai, + fixTextCoord, + fixGeoCoord, + fixDiaoyuIsland + ]; + + /** + * [Geo description] + * @param {string} name Geo name + * @param {string} map Map type + * @param {Object} geoJson + * @param {Object} [specialAreas] + * Specify the positioned areas by left, top, width, height + * @param {Object.} [nameMap] + * Specify name alias + */ + function Geo(name, map$$1, geoJson, specialAreas, nameMap) { + + View.call(this, name); + + /** + * Map type + * @type {string} + */ + this.map = map$$1; + + this._nameCoordMap = createHashMap(); + + this.loadGeoJson(geoJson, specialAreas, nameMap); + } + + Geo.prototype = { + + constructor: Geo, + + type: 'geo', + + /** + * @param {Array.} + * @readOnly + */ + dimensions: ['lng', 'lat'], + + /** + * If contain given lng,lat coord + * @param {Array.} + * @readOnly + */ + containCoord: function(coord) { + var regions = this.regions; + for (var i = 0; i < regions.length; i++) { + if (regions[i].contain(coord)) { + return true; + } + } + return false; + }, + /** + * @param {Object} geoJson + * @param {Object} [specialAreas] + * Specify the positioned areas by left, top, width, height + * @param {Object.} [nameMap] + * Specify name alias + */ + loadGeoJson: function(geoJson, specialAreas, nameMap) { + // https://jsperf.com/try-catch-performance-overhead + try { + this.regions = geoJson ? parseGeoJson$1(geoJson) : []; + } catch (e) { + throw 'Invalid geoJson format\n' + e.message; + } + specialAreas = specialAreas || {}; + nameMap = nameMap || {}; + var regions = this.regions; + var regionsMap = createHashMap(); + for (var i = 0; i < regions.length; i++) { + var regionName = regions[i].name; + // Try use the alias in nameMap + regionName = nameMap.hasOwnProperty(regionName) ? nameMap[regionName] : regionName; + regions[i].name = regionName; + + regionsMap.set(regionName, regions[i]); + // Add geoJson + this.addGeoCoord(regionName, regions[i].center); + + // Some area like Alaska in USA map needs to be tansformed + // to look better + var specialArea = specialAreas[regionName]; + if (specialArea) { + regions[i].transformTo( + specialArea.left, specialArea.top, specialArea.width, specialArea.height + ); + } + } + + this._regionsMap = regionsMap; + + this._rect = null; + + each$1(geoFixFuncs, function(fixFunc) { + fixFunc(this); + }, this); + }, + + // Overwrite + transformTo: function(x, y, width, height) { + var rect = this.getBoundingRect(); + + rect = rect.clone(); + // Longitute is inverted + rect.y = -rect.y - rect.height; + + var rawTransformable = this._rawTransformable; + + rawTransformable.transform = rect.calculateTransform( + new BoundingRect(x, y, width, height) + ); + + rawTransformable.decomposeTransform(); + + var scale = rawTransformable.scale; + scale[1] = -scale[1]; + + rawTransformable.updateTransform(); + + this._updateTransform(); + }, + + /** + * @param {string} name + * @return {module:echarts/coord/geo/Region} + */ + getRegion: function(name) { + return this._regionsMap.get(name); + }, + + getRegionByCoord: function(coord) { + var regions = this.regions; + for (var i = 0; i < regions.length; i++) { + if (regions[i].contain(coord)) { + return regions[i]; + } + } + }, + + /** + * Add geoCoord for indexing by name + * @param {string} name + * @param {Array.} geoCoord + */ + addGeoCoord: function(name, geoCoord) { + this._nameCoordMap.set(name, geoCoord); + }, + + /** + * Get geoCoord by name + * @param {string} name + * @return {Array.} + */ + getGeoCoord: function(name) { + return this._nameCoordMap.get(name); + }, + + // Overwrite + getBoundingRect: function() { + if (this._rect) { + return this._rect; + } + var rect; + + var regions = this.regions; + for (var i = 0; i < regions.length; i++) { + var regionRect = regions[i].getBoundingRect(); + rect = rect || regionRect.clone(); + rect.union(regionRect); + } + // FIXME Always return new ? + return (this._rect = rect || new BoundingRect(0, 0, 0, 0)); + }, + + /** + * @param {string|Array.} data + * @param {boolean} noRoam + * @param {Array.} [out] + * @return {Array.} + */ + dataToPoint: function(data, noRoam, out) { + if (typeof data === 'string') { + // Map area name to geoCoord + data = this.getGeoCoord(data); + } + if (data) { + return View.prototype.dataToPoint.call(this, data, noRoam, out); + } + }, + + /** + * @inheritDoc + */ + convertToPixel: curry(doConvert, 'dataToPoint'), + + /** + * @inheritDoc + */ + convertFromPixel: curry(doConvert, 'pointToData') + + }; + + mixin(Geo, View); + + function doConvert(methodName, ecModel, finder, value) { + var geoModel = finder.geoModel; + var seriesModel = finder.seriesModel; + + var coordSys = geoModel ? + geoModel.coordinateSystem : + seriesModel ? + ( + seriesModel.coordinateSystem // For map. + || + (seriesModel.getReferringComponents('geo')[0] || {}).coordinateSystem + ) : + null; + + return coordSys === this ? coordSys[methodName](value) : null; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Resize method bound to the geo + * @param {module:echarts/coord/geo/GeoModel|module:echarts/chart/map/MapModel} geoModel + * @param {module:echarts/ExtensionAPI} api + */ + function resizeGeo(geoModel, api) { + + var boundingCoords = geoModel.get('boundingCoords'); + if (boundingCoords != null) { + var leftTop = boundingCoords[0]; + var rightBottom = boundingCoords[1]; + if (isNaN(leftTop[0]) || isNaN(leftTop[1]) || isNaN(rightBottom[0]) || isNaN(rightBottom[1])) { + if (__DEV__) { + console.error('Invalid boundingCoords'); + } + } else { + this.setBoundingRect(leftTop[0], leftTop[1], rightBottom[0] - leftTop[0], rightBottom[1] - leftTop[1]); + } + } + + var rect = this.getBoundingRect(); + + var boxLayoutOption; + + var center = geoModel.get('layoutCenter'); + var size = geoModel.get('layoutSize'); + + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + + var aspectScale = geoModel.get('aspectScale') || 0.75; + var aspect = rect.width / rect.height * aspectScale; + + var useCenterAndSize = false; + + if (center && size) { + center = [ + parsePercent$1(center[0], viewWidth), + parsePercent$1(center[1], viewHeight) + ]; + size = parsePercent$1(size, Math.min(viewWidth, viewHeight)); + + if (!isNaN(center[0]) && !isNaN(center[1]) && !isNaN(size)) { + useCenterAndSize = true; + } else { + if (__DEV__) { + console.warn('Given layoutCenter or layoutSize data are invalid. Use left/top/width/height instead.'); + } + } + } + + var viewRect; + if (useCenterAndSize) { + var viewRect = {}; + if (aspect > 1) { + // Width is same with size + viewRect.width = size; + viewRect.height = size / aspect; + } else { + viewRect.height = size; + viewRect.width = size * aspect; + } + viewRect.y = center[1] - viewRect.height / 2; + viewRect.x = center[0] - viewRect.width / 2; + } else { + // Use left/top/width/height + boxLayoutOption = geoModel.getBoxLayoutParams(); + + // 0.75 rate + boxLayoutOption.aspect = aspect; + + viewRect = getLayoutRect(boxLayoutOption, { + width: viewWidth, + height: viewHeight + }); + } + + this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height); + + this.setCenter(geoModel.get('center')); + this.setZoom(geoModel.get('zoom')); + } + + /** + * @param {module:echarts/coord/Geo} geo + * @param {module:echarts/model/Model} model + * @inner + */ + function setGeoCoords(geo, model) { + each$1(model.get('geoCoord'), function(geoCoord, name) { + geo.addGeoCoord(name, geoCoord); + }); + } + + if (__DEV__) { + var mapNotExistsError = function(name) { + console.error('Map ' + name + + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html'); + }; + } + + var geoCreator = { + + // For deciding which dimensions to use when creating list data + dimensions: Geo.prototype.dimensions, + + create: function(ecModel, api) { + var geoList = []; + + // FIXME Create each time may be slow + ecModel.eachComponent('geo', function(geoModel, idx) { + var name = geoModel.get('map'); + var mapData = getMap(name); + if (__DEV__) { + if (!mapData) { + mapNotExistsError(name); + } + } + var geo = new Geo( + name + idx, name, + mapData && mapData.geoJson, mapData && mapData.specialAreas, + geoModel.get('nameMap') + ); + geo.zoomLimit = geoModel.get('scaleLimit'); + geoList.push(geo); + + setGeoCoords(geo, geoModel); + + geoModel.coordinateSystem = geo; + geo.model = geoModel; + + // Inject resize method + geo.resize = resizeGeo; + + geo.resize(geoModel, api); + }); + + ecModel.eachSeries(function(seriesModel) { + var coordSys = seriesModel.get('coordinateSystem'); + if (coordSys === 'geo') { + var geoIndex = seriesModel.get('geoIndex') || 0; + seriesModel.coordinateSystem = geoList[geoIndex]; + } + }); + + // If has map series + var mapModelGroupBySeries = {}; + + ecModel.eachSeriesByType('map', function(seriesModel) { + if (!seriesModel.getHostGeoModel()) { + var mapType = seriesModel.getMapType(); + mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || []; + mapModelGroupBySeries[mapType].push(seriesModel); + } + }); + + each$1(mapModelGroupBySeries, function(mapSeries, mapType) { + var mapData = getMap(mapType); + if (__DEV__) { + if (!mapData) { + mapNotExistsError(mapSeries[0].get('map')); + } + } + + var nameMapList = map(mapSeries, function(singleMapSeries) { + return singleMapSeries.get('nameMap'); + }); + var geo = new Geo( + mapType, mapType, + mapData && mapData.geoJson, mapData && mapData.specialAreas, + mergeAll(nameMapList) + ); + geo.zoomLimit = retrieve.apply(null, map(mapSeries, function(singleMapSeries) { + return singleMapSeries.get('scaleLimit'); + })); + geoList.push(geo); + + // Inject resize method + geo.resize = resizeGeo; + + geo.resize(mapSeries[0], api); + + each$1(mapSeries, function(singleMapSeries) { + singleMapSeries.coordinateSystem = geo; + + setGeoCoords(geo, singleMapSeries); + }); + }); + + return geoList; + }, + + /** + * Fill given regions array + * @param {Array.} originRegionArr + * @param {string} mapName + * @param {Object} [nameMap] + * @return {Array} + */ + getFilledRegions: function(originRegionArr, mapName, nameMap) { + // Not use the original + var regionsArr = (originRegionArr || []).slice(); + nameMap = nameMap || {}; + + var map$$1 = getMap(mapName); + var geoJson = map$$1 && map$$1.geoJson; + if (!geoJson) { + if (__DEV__) { + mapNotExistsError(mapName); + } + return originRegionArr; + } + + var dataNameMap = createHashMap(); + var features = geoJson.features; + for (var i = 0; i < regionsArr.length; i++) { + dataNameMap.set(regionsArr[i].name, regionsArr[i]); + } + + for (var i = 0; i < features.length; i++) { + var name = features[i].properties.name; + if (!dataNameMap.get(name)) { + if (nameMap.hasOwnProperty(name)) { + name = nameMap[name]; + } + regionsArr.push({ + name: name + }); + } + } + return regionsArr; + } + }; + + registerCoordinateSystem('geo', geoCreator); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var MapSeries = SeriesModel.extend({ + + type: 'series.map', + + dependencies: ['geo'], + + layoutMode: 'box', + + /** + * Only first map series of same mapType will drawMap + * @type {boolean} + */ + needsDrawMap: false, + + /** + * Group of all map series with same mapType + * @type {boolean} + */ + seriesGroup: [], + + init: function(option) { + + // this._fillOption(option, this.getMapType()); + // this.option = option; + + MapSeries.superApply(this, 'init', arguments); + + this.updateSelectedMap(this._createSelectableList()); + }, + + getInitialData: function(option) { + return createListSimply(this, ['value']); + }, + + mergeOption: function(newOption) { + // this._fillOption(newOption, this.getMapType()); + + MapSeries.superApply(this, 'mergeOption', arguments); + + this.updateSelectedMap(this._createSelectableList()); + }, + + _createSelectableList: function() { + var data = this.getRawData(); + var valueDim = data.mapDimension('value'); + var targetList = []; + for (var i = 0, len = data.count(); i < len; i++) { + targetList.push({ + name: data.getName(i), + value: data.get(valueDim, i), + selected: retrieveRawAttr(data, i, 'selected') + }); + } + + targetList = geoCreator.getFilledRegions(targetList, this.getMapType(), this.option.nameMap); + + return targetList; + }, + + /** + * If no host geo model, return null, which means using a + * inner exclusive geo model. + */ + getHostGeoModel: function() { + var geoIndex = this.option.geoIndex; + return geoIndex != null ? + this.dependentModels.geo[geoIndex] : + null; + }, + + getMapType: function() { + return (this.getHostGeoModel() || this).option.map; + }, + + _fillOption: function(option, mapName) { + // Shallow clone + // option = zrUtil.extend({}, option); + + // option.data = geoCreator.getFilledRegions(option.data, mapName, option.nameMap); + + // return option; + }, + + getRawValue: function(dataIndex) { + // Use value stored in data instead because it is calculated from multiple series + // FIXME Provide all value of multiple series ? + var data = this.getData(); + return data.get(data.mapDimension('value'), dataIndex); + }, + + /** + * Get model of region + * @param {string} name + * @return {module:echarts/model/Model} + */ + getRegionModel: function(regionName) { + var data = this.getData(); + return data.getItemModel(data.indexOfName(regionName)); + }, + + /** + * Map tooltip formatter + * + * @param {number} dataIndex + */ + formatTooltip: function(dataIndex) { + // FIXME orignalData and data is a bit confusing + var data = this.getData(); + var formattedValue = addCommas(this.getRawValue(dataIndex)); + var name = data.getName(dataIndex); + + var seriesGroup = this.seriesGroup; + var seriesNames = []; + for (var i = 0; i < seriesGroup.length; i++) { + var otherIndex = seriesGroup[i].originalData.indexOfName(name); + var valueDim = data.mapDimension('value'); + if (!isNaN(seriesGroup[i].originalData.get(valueDim, otherIndex))) { + seriesNames.push( + encodeHTML(seriesGroup[i].name) + ); + } + } + + return seriesNames.join(', ') + '
' + + encodeHTML(name + ' : ' + formattedValue); + }, + + /** + * @implement + */ + getTooltipPosition: function(dataIndex) { + if (dataIndex != null) { + var name = this.getData().getName(dataIndex); + var geo = this.coordinateSystem; + var region = geo.getRegion(name); + + return region && geo.dataToPoint(region.center); + } + }, + + setZoom: function(zoom) { + this.option.zoom = zoom; + }, + + setCenter: function(center) { + this.option.center = center; + }, + + defaultOption: { + // 一级层叠 + zlevel: 0, + // 二级层叠 + z: 2, + + coordinateSystem: 'geo', + + // map should be explicitly specified since ec3. + map: '', + + // If `geoIndex` is not specified, a exclusive geo will be + // created. Otherwise use the specified geo component, and + // `map` and `mapType` are ignored. + // geoIndex: 0, + + // 'center' | 'left' | 'right' | 'x%' | {number} + left: 'center', + // 'center' | 'top' | 'bottom' | 'x%' | {number} + top: 'center', + // right + // bottom + // width: + // height + + // Aspect is width / height. Inited to be geoJson bbox aspect + // This parameter is used for scale this aspect + aspectScale: 0.75, + + ///// Layout with center and size + // If you wan't to put map in a fixed size box with right aspect ratio + // This two properties may more conveninet + // layoutCenter: [50%, 50%] + // layoutSize: 100 + + + // 数值合并方式,默认加和,可选为: + // 'sum' | 'average' | 'max' | 'min' + // mapValueCalculation: 'sum', + // 地图数值计算结果小数精度 + // mapValuePrecision: 0, + + + // 显示图例颜色标识(系列标识的小圆点),图例开启时有效 + showLegendSymbol: true, + // 选择模式,默认关闭,可选single,multiple + // selectedMode: false, + dataRangeHoverLink: true, + // 是否开启缩放及漫游模式 + // roam: false, + + // Define left-top, right-bottom coords to control view + // For example, [ [180, 90], [-180, -90] ], + // higher priority than center and zoom + boundingCoords: null, + + // Default on center of map + center: null, + + zoom: 1, + + scaleLimit: null, + + label: { + show: false, + color: '#000' + }, + // scaleLimit: null, + itemStyle: { + borderWidth: 0.5, + borderColor: '#444', + areaColor: '#eee' + }, + + emphasis: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + areaColor: 'rgba(255,215,0,0.8)' + } + } + } + + }); + + mixin(MapSeries, selectableMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var ATTR = '\0_ec_interaction_mutex'; + + function take(zr, resourceKey, userKey) { + var store = getStore(zr); + store[resourceKey] = userKey; + } + + function release(zr, resourceKey, userKey) { + var store = getStore(zr); + var uKey = store[resourceKey]; + + if (uKey === userKey) { + store[resourceKey] = null; + } + } + + function isTaken(zr, resourceKey) { + return !!getStore(zr)[resourceKey]; + } + + function getStore(zr) { + return zr[ATTR] || (zr[ATTR] = {}); + } + + /** + * payload: { + * type: 'takeGlobalCursor', + * key: 'dataZoomSelect', or 'brush', or ..., + * If no userKey, release global cursor. + * } + */ + registerAction({ + type: 'takeGlobalCursor', + event: 'globalCursorTaken', + update: 'update' + }, + function() {} + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @alias module:echarts/component/helper/RoamController + * @constructor + * @mixin {module:zrender/mixin/Eventful} + * + * @param {module:zrender/zrender~ZRender} zr + */ + function RoamController(zr) { + + /** + * @type {Function} + */ + this.pointerChecker; + + /** + * @type {module:zrender} + */ + this._zr = zr; + + /** + * @type {Object} + */ + this._opt = {}; + + // Avoid two roamController bind the same handler + var bind$$1 = bind; + var mousedownHandler = bind$$1(mousedown, this); + var mousemoveHandler = bind$$1(mousemove, this); + var mouseupHandler = bind$$1(mouseup, this); + var mousewheelHandler = bind$$1(mousewheel, this); + var pinchHandler = bind$$1(pinch, this); + + Eventful.call(this); + + /** + * @param {Function} pointerChecker + * input: x, y + * output: boolean + */ + this.setPointerChecker = function(pointerChecker) { + this.pointerChecker = pointerChecker; + }; + + /** + * Notice: only enable needed types. For example, if 'zoom' + * is not needed, 'zoom' should not be enabled, otherwise + * default mousewheel behaviour (scroll page) will be disabled. + * + * @param {boolean|string} [controlType=true] Specify the control type, + * which can be null/undefined or true/false + * or 'pan/move' or 'zoom'/'scale' + * @param {Object} [opt] + * @param {Object} [opt.zoomOnMouseWheel=true] + * @param {Object} [opt.moveOnMouseMove=true] + * @param {Object} [opt.preventDefaultMouseMove=true] When pan. + */ + this.enable = function(controlType, opt) { + + // Disable previous first + this.disable(); + + this._opt = defaults(clone(opt) || {}, { + zoomOnMouseWheel: true, + moveOnMouseMove: true, + preventDefaultMouseMove: true + }); + + if (controlType == null) { + controlType = true; + } + + if (controlType === true || (controlType === 'move' || controlType === 'pan')) { + zr.on('mousedown', mousedownHandler); + zr.on('mousemove', mousemoveHandler); + zr.on('mouseup', mouseupHandler); + } + if (controlType === true || (controlType === 'scale' || controlType === 'zoom')) { + zr.on('mousewheel', mousewheelHandler); + zr.on('pinch', pinchHandler); + } + }; + + this.disable = function() { + zr.off('mousedown', mousedownHandler); + zr.off('mousemove', mousemoveHandler); + zr.off('mouseup', mouseupHandler); + zr.off('mousewheel', mousewheelHandler); + zr.off('pinch', pinchHandler); + }; + + this.dispose = this.disable; + + this.isDragging = function() { + return this._dragging; + }; + + this.isPinching = function() { + return this._pinching; + }; + } + + mixin(RoamController, Eventful); + + + function mousedown(e) { + if (notLeftMouse(e) || + (e.target && e.target.draggable) + ) { + return; + } + + var x = e.offsetX; + var y = e.offsetY; + + // Only check on mosedown, but not mousemove. + // Mouse can be out of target when mouse moving. + if (this.pointerChecker && this.pointerChecker(e, x, y)) { + this._x = x; + this._y = y; + this._dragging = true; + } + } + + function mousemove(e) { + if (notLeftMouse(e) || + !checkKeyBinding(this, 'moveOnMouseMove', e) || + !this._dragging || + e.gestureEvent === 'pinch' || + isTaken(this._zr, 'globalPan') + ) { + return; + } + + var x = e.offsetX; + var y = e.offsetY; + + var oldX = this._x; + var oldY = this._y; + + var dx = x - oldX; + var dy = y - oldY; + + this._x = x; + this._y = y; + + this._opt.preventDefaultMouseMove && stop(e.event); + + this.trigger('pan', dx, dy, oldX, oldY, x, y); + } + + function mouseup(e) { + if (!notLeftMouse(e)) { + this._dragging = false; + } + } + + function mousewheel(e) { + // wheelDelta maybe -0 in chrome mac. + if (!checkKeyBinding(this, 'zoomOnMouseWheel', e) || e.wheelDelta === 0) { + return; + } + + // Convenience: + // Mac and VM Windows on Mac: scroll up: zoom out. + // Windows: scroll up: zoom in. + var zoomDelta = e.wheelDelta > 0 ? 1.1 : 1 / 1.1; + zoom.call(this, e, zoomDelta, e.offsetX, e.offsetY); + } + + function pinch(e) { + if (isTaken(this._zr, 'globalPan')) { + return; + } + var zoomDelta = e.pinchScale > 1 ? 1.1 : 1 / 1.1; + zoom.call(this, e, zoomDelta, e.pinchX, e.pinchY); + } + + function zoom(e, zoomDelta, zoomX, zoomY) { + if (this.pointerChecker && this.pointerChecker(e, zoomX, zoomY)) { + // When mouse is out of roamController rect, + // default befavoius should not be be disabled, otherwise + // page sliding is disabled, contrary to expectation. + stop(e.event); + + this.trigger('zoom', zoomDelta, zoomX, zoomY); + } + } + + function checkKeyBinding(roamController, prop, e) { + var setting = roamController._opt[prop]; + return setting && + (!isString(setting) || e.event[setting + 'Key']); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * For geo and graph. + * + * @param {Object} controllerHost + * @param {module:zrender/Element} controllerHost.target + */ + function updateViewOnPan(controllerHost, dx, dy) { + var target = controllerHost.target; + var pos = target.position; + pos[0] += dx; + pos[1] += dy; + target.dirty(); + } + + /** + * For geo and graph. + * + * @param {Object} controllerHost + * @param {module:zrender/Element} controllerHost.target + * @param {number} controllerHost.zoom + * @param {number} controllerHost.zoomLimit like: {min: 1, max: 2} + */ + function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) { + var target = controllerHost.target; + var zoomLimit = controllerHost.zoomLimit; + var pos = target.position; + var scale = target.scale; + + var newZoom = controllerHost.zoom = controllerHost.zoom || 1; + newZoom *= zoomDelta; + if (zoomLimit) { + var zoomMin = zoomLimit.min || 0; + var zoomMax = zoomLimit.max || Infinity; + newZoom = Math.max( + Math.min(zoomMax, newZoom), + zoomMin + ); + } + var zoomScale = newZoom / controllerHost.zoom; + controllerHost.zoom = newZoom; + // Keep the mouse center when scaling + pos[0] -= (zoomX - pos[0]) * (zoomScale - 1); + pos[1] -= (zoomY - pos[1]) * (zoomScale - 1); + scale[0] *= zoomScale; + scale[1] *= zoomScale; + + target.dirty(); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var IRRELEVANT_EXCLUDES = { + 'axisPointer': 1, + 'tooltip': 1, + 'brush': 1 + }; + + /** + * Avoid that: mouse click on a elements that is over geo or graph, + * but roam is triggered. + */ + function onIrrelevantElement(e, api, targetCoordSysModel) { + var model = api.getComponentByElement(e.topTarget); + // If model is axisModel, it works only if it is injected with coordinateSystem. + var coordSys = model && model.coordinateSystem; + return model && + model !== targetCoordSysModel && + !IRRELEVANT_EXCLUDES[model.mainType] && + (coordSys && coordSys.model !== targetCoordSysModel); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function getFixedItemStyle(model, scale) { + var itemStyle = model.getItemStyle(); + var areaColor = model.get('areaColor'); + + // If user want the color not to be changed when hover, + // they should both set areaColor and color to be null. + if (areaColor != null) { + itemStyle.fill = areaColor; + } + + return itemStyle; + } + + function updateMapSelectHandler(mapDraw, mapOrGeoModel, group, api, fromView) { + group.off('click'); + group.off('mousedown'); + + if (mapOrGeoModel.get('selectedMode')) { + + group.on('mousedown', function() { + mapDraw._mouseDownFlag = true; + }); + + group.on('click', function(e) { + if (!mapDraw._mouseDownFlag) { + return; + } + mapDraw._mouseDownFlag = false; + + var el = e.target; + while (!el.__regions) { + el = el.parent; + } + if (!el) { + return; + } + + var action = { + type: (mapOrGeoModel.mainType === 'geo' ? 'geo' : 'map') + 'ToggleSelect', + batch: map(el.__regions, function(region) { + return { + name: region.name, + from: fromView.uid + }; + }) + }; + action[mapOrGeoModel.mainType + 'Id'] = mapOrGeoModel.id; + + api.dispatchAction(action); + + updateMapSelected(mapOrGeoModel, group); + }); + } + } + + function updateMapSelected(mapOrGeoModel, group) { + // FIXME + group.eachChild(function(otherRegionEl) { + each$1(otherRegionEl.__regions, function(region) { + otherRegionEl.trigger(mapOrGeoModel.isSelected(region.name) ? 'emphasis' : 'normal'); + }); + }); + } + + /** + * @alias module:echarts/component/helper/MapDraw + * @param {module:echarts/ExtensionAPI} api + * @param {boolean} updateGroup + */ + function MapDraw(api, updateGroup) { + + var group = new Group(); + + /** + * @type {module:echarts/component/helper/RoamController} + * @private + */ + this._controller = new RoamController(api.getZr()); + + /** + * @type {Object} {target, zoom, zoomLimit} + * @private + */ + this._controllerHost = { + target: updateGroup ? group : null + }; + + /** + * @type {module:zrender/container/Group} + * @readOnly + */ + this.group = group; + + /** + * @type {boolean} + * @private + */ + this._updateGroup = updateGroup; + + /** + * This flag is used to make sure that only one among + * `pan`, `zoom`, `click` can occurs, otherwise 'selected' + * action may be triggered when `pan`, which is unexpected. + * @type {booelan} + */ + this._mouseDownFlag; + } + + MapDraw.prototype = { + + constructor: MapDraw, + + draw: function(mapOrGeoModel, ecModel, api, fromView, payload) { + + var isGeo = mapOrGeoModel.mainType === 'geo'; + + // Map series has data. GEO model that controlled by map series + // will be assigned with map data. Other GEO model has no data. + var data = mapOrGeoModel.getData && mapOrGeoModel.getData(); + isGeo && ecModel.eachComponent({ + mainType: 'series', + subType: 'map' + }, function(mapSeries) { + if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) { + data = mapSeries.getData(); + } + }); + + var geo = mapOrGeoModel.coordinateSystem; + + var group = this.group; + + var scale = geo.scale; + var groupNewProp = { + position: geo.position, + scale: scale + }; + + // No animation when first draw or in action + if (!group.childAt(0) || payload) { + group.attr(groupNewProp); + } else { + updateProps(group, groupNewProp, mapOrGeoModel); + } + + group.removeAll(); + + var itemStyleAccessPath = ['itemStyle']; + var hoverItemStyleAccessPath = ['emphasis', 'itemStyle']; + var labelAccessPath = ['label']; + var hoverLabelAccessPath = ['emphasis', 'label']; + var nameMap = createHashMap(); + + each$1(geo.regions, function(region) { + + // Consider in GeoJson properties.name may be duplicated, for example, + // there is multiple region named "United Kindom" or "France" (so many + // colonies). And it is not appropriate to merge them in geo, which + // will make them share the same label and bring trouble in label + // location calculation. + var regionGroup = nameMap.get(region.name) || + nameMap.set(region.name, new Group()); + + var compoundPath = new CompoundPath({ + shape: { + paths: [] + } + }); + regionGroup.add(compoundPath); + + var regionModel = mapOrGeoModel.getRegionModel(region.name) || mapOrGeoModel; + + var itemStyleModel = regionModel.getModel(itemStyleAccessPath); + var hoverItemStyleModel = regionModel.getModel(hoverItemStyleAccessPath); + var itemStyle = getFixedItemStyle(itemStyleModel, scale); + var hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale); + + var labelModel = regionModel.getModel(labelAccessPath); + var hoverLabelModel = regionModel.getModel(hoverLabelAccessPath); + + var dataIdx; + // Use the itemStyle in data if has data + if (data) { + dataIdx = data.indexOfName(region.name); + // Only visual color of each item will be used. It can be encoded by dataRange + // But visual color of series is used in symbol drawing + // + // Visual color for each series is for the symbol draw + var visualColor = data.getItemVisual(dataIdx, 'color', true); + if (visualColor) { + itemStyle.fill = visualColor; + } + } + + each$1(region.geometries, function(geometry) { + if (geometry.type !== 'polygon') { + return; + } + compoundPath.shape.paths.push(new Polygon({ + shape: { + points: geometry.exterior + } + })); + + for (var i = 0; i < (geometry.interiors ? geometry.interiors.length : 0); i++) { + compoundPath.shape.paths.push(new Polygon({ + shape: { + points: geometry.interiors[i] + } + })); + } + }); + + compoundPath.setStyle(itemStyle); + compoundPath.style.strokeNoScale = true; + compoundPath.culling = true; + // Label + var showLabel = labelModel.get('show'); + var hoverShowLabel = hoverLabelModel.get('show'); + + var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx)); + var itemLayout = data && data.getItemLayout(dataIdx); + // In the following cases label will be drawn + // 1. In map series and data value is NaN + // 2. In geo component + // 4. Region has no series legendSymbol, which will be add a showLabel flag in mapSymbolLayout + if ( + (isGeo || isDataNaN && (showLabel || hoverShowLabel)) || + (itemLayout && itemLayout.showLabel) + ) { + var query = !isGeo ? dataIdx : region.name; + var labelFetcher; + + // Consider dataIdx not found. + if (!data || dataIdx >= 0) { + labelFetcher = mapOrGeoModel; + } + + var textEl = new Text({ + position: region.center.slice(), + scale: [1 / scale[0], 1 / scale[1]], + z2: 10, + silent: true + }); + + setLabelStyle( + textEl.style, textEl.hoverStyle = {}, labelModel, hoverLabelModel, { + labelFetcher: labelFetcher, + labelDataIndex: query, + defaultText: region.name, + useInsideStyle: false + }, { + textAlign: 'center', + textVerticalAlign: 'middle' + } + ); + + regionGroup.add(textEl); + } + + // setItemGraphicEl, setHoverStyle after all polygons and labels + // are added to the rigionGroup + if (data) { + data.setItemGraphicEl(dataIdx, regionGroup); + } else { + var regionModel = mapOrGeoModel.getRegionModel(region.name); + // Package custom mouse event for geo component + compoundPath.eventData = { + componentType: 'geo', + geoIndex: mapOrGeoModel.componentIndex, + name: region.name, + region: (regionModel && regionModel.option) || {} + }; + } + + var groupRegions = regionGroup.__regions || (regionGroup.__regions = []); + groupRegions.push(region); + + setHoverStyle( + regionGroup, + hoverItemStyle, { + hoverSilentOnTouch: !!mapOrGeoModel.get('selectedMode') + } + ); + + group.add(regionGroup); + }); + + this._updateController(mapOrGeoModel, ecModel, api); + + updateMapSelectHandler(this, mapOrGeoModel, group, api, fromView); + + updateMapSelected(mapOrGeoModel, group); + }, + + remove: function() { + this.group.removeAll(); + this._controller.dispose(); + this._controllerHost = {}; + }, + + _updateController: function(mapOrGeoModel, ecModel, api) { + var geo = mapOrGeoModel.coordinateSystem; + var controller = this._controller; + var controllerHost = this._controllerHost; + + controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit'); + controllerHost.zoom = geo.getZoom(); + + // roamType is will be set default true if it is null + controller.enable(mapOrGeoModel.get('roam') || false); + var mainType = mapOrGeoModel.mainType; + + function makeActionBase() { + var action = { + type: 'geoRoam', + componentType: mainType + }; + action[mainType + 'Id'] = mapOrGeoModel.id; + return action; + } + + controller.off('pan').on('pan', function(dx, dy) { + this._mouseDownFlag = false; + + updateViewOnPan(controllerHost, dx, dy); + + api.dispatchAction(extend(makeActionBase(), { + dx: dx, + dy: dy + })); + }, this); + + controller.off('zoom').on('zoom', function(zoom, mouseX, mouseY) { + this._mouseDownFlag = false; + + updateViewOnZoom(controllerHost, zoom, mouseX, mouseY); + + api.dispatchAction(extend(makeActionBase(), { + zoom: zoom, + originX: mouseX, + originY: mouseY + })); + + if (this._updateGroup) { + var group = this.group; + var scale = group.scale; + group.traverse(function(el) { + if (el.type === 'text') { + el.attr('scale', [1 / scale[0], 1 / scale[1]]); + } + }); + } + }, this); + + controller.setPointerChecker(function(e, x, y) { + return geo.getViewRectAfterRoam().contain(x, y) && + !onIrrelevantElement(e, api, mapOrGeoModel); + }); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendChartView({ + + type: 'map', + + render: function(mapModel, ecModel, api, payload) { + // Not render if it is an toggleSelect action from self + if (payload && payload.type === 'mapToggleSelect' && + payload.from === this.uid + ) { + return; + } + + var group = this.group; + group.removeAll(); + + if (mapModel.getHostGeoModel()) { + return; + } + + // Not update map if it is an roam action from self + if (!(payload && payload.type === 'geoRoam' && + payload.componentType === 'series' && + payload.seriesId === mapModel.id + )) { + if (mapModel.needsDrawMap) { + var mapDraw = this._mapDraw || new MapDraw(api, true); + group.add(mapDraw.group); + + mapDraw.draw(mapModel, ecModel, api, this, payload); + + this._mapDraw = mapDraw; + } else { + // Remove drawed map + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + } + } else { + var mapDraw = this._mapDraw; + mapDraw && group.add(mapDraw.group); + } + + mapModel.get('showLegendSymbol') && ecModel.getComponent('legend') && + this._renderSymbols(mapModel, ecModel, api); + }, + + remove: function() { + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + this.group.removeAll(); + }, + + dispose: function() { + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + }, + + _renderSymbols: function(mapModel, ecModel, api) { + var originalData = mapModel.originalData; + var group = this.group; + + originalData.each(originalData.mapDimension('value'), function(value, idx) { + if (isNaN(value)) { + return; + } + + var layout = originalData.getItemLayout(idx); + + if (!layout || !layout.point) { + // Not exists in map + return; + } + + var point = layout.point; + var offset = layout.offset; + + var circle = new Circle({ + style: { + // Because the special of map draw. + // Which needs statistic of multiple series and draw on one map. + // And each series also need a symbol with legend color + // + // Layout and visual are put one the different data + fill: mapModel.getData().getVisual('color') + }, + shape: { + cx: point[0] + offset * 9, + cy: point[1], + r: 3 + }, + silent: true, + // Do not overlap the first series, on which labels are displayed. + z2: !offset ? 10 : 8 + }); + + // First data on the same region + if (!offset) { + var fullData = mapModel.mainSeries.getData(); + var name = originalData.getName(idx); + + var fullIndex = fullData.indexOfName(name); + + var itemModel = originalData.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + var hoverLabelModel = itemModel.getModel('emphasis.label'); + + var polygonGroups = fullData.getItemGraphicEl(fullIndex); + + var normalText = retrieve2( + mapModel.getFormattedLabel(idx, 'normal'), + name + ); + var emphasisText = retrieve2( + mapModel.getFormattedLabel(idx, 'emphasis'), + normalText + ); + + var onEmphasis = function() { + var hoverStyle = setTextStyle({}, hoverLabelModel, { + text: hoverLabelModel.get('show') ? emphasisText : null + }, { + isRectText: true, + useInsideStyle: false + }, true); + circle.style.extendFrom(hoverStyle); + // Make label upper than others if overlaps. + circle.__mapOriginalZ2 = circle.z2; + circle.z2 += 1; + }; + + var onNormal = function() { + setTextStyle(circle.style, labelModel, { + text: labelModel.get('show') ? normalText : null, + textPosition: labelModel.getShallow('position') || 'bottom' + }, { + isRectText: true, + useInsideStyle: false + }); + + if (circle.__mapOriginalZ2 != null) { + circle.z2 = circle.__mapOriginalZ2; + circle.__mapOriginalZ2 = null; + } + }; + + polygonGroups.on('mouseover', onEmphasis) + .on('mouseout', onNormal) + .on('emphasis', onEmphasis) + .on('normal', onNormal); + + onNormal(); + } + + group.add(circle); + }); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/coord/View} view + * @param {Object} payload + * @param {Object} [zoomLimit] + */ + function updateCenterAndZoom( + view, payload, zoomLimit + ) { + var previousZoom = view.getZoom(); + var center = view.getCenter(); + var zoom = payload.zoom; + + var point = view.dataToPoint(center); + + if (payload.dx != null && payload.dy != null) { + point[0] -= payload.dx; + point[1] -= payload.dy; + + var center = view.pointToData(point); + view.setCenter(center); + } + if (zoom != null) { + if (zoomLimit) { + var zoomMin = zoomLimit.min || 0; + var zoomMax = zoomLimit.max || Infinity; + zoom = Math.max( + Math.min(previousZoom * zoom, zoomMax), + zoomMin + ) / previousZoom; + } + + // Zoom on given point(originX, originY) + view.scale[0] *= zoom; + view.scale[1] *= zoom; + var position = view.position; + var fixX = (payload.originX - position[0]) * (zoom - 1); + var fixY = (payload.originY - position[1]) * (zoom - 1); + + position[0] -= fixX; + position[1] -= fixY; + + view.updateTransform(); + // Get the new center + var center = view.pointToData(point); + view.setCenter(center); + view.setZoom(zoom * previousZoom); + } + + return { + center: view.getCenter(), + zoom: view.getZoom() + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @payload + * @property {string} [componentType=series] + * @property {number} [dx] + * @property {number} [dy] + * @property {number} [zoom] + * @property {number} [originX] + * @property {number} [originY] + */ + registerAction({ + type: 'geoRoam', + event: 'geoRoam', + update: 'updateTransform' + }, function(payload, ecModel) { + var componentType = payload.componentType || 'series'; + + ecModel.eachComponent({ + mainType: componentType, + query: payload + }, + function(componentModel) { + var geo = componentModel.coordinateSystem; + if (geo.type !== 'geo') { + return; + } + + var res = updateCenterAndZoom( + geo, payload, componentModel.get('scaleLimit') + ); + + componentModel.setCenter && + componentModel.setCenter(res.center); + + componentModel.setZoom && + componentModel.setZoom(res.zoom); + + // All map series with same `map` use the same geo coordinate system + // So the center and zoom must be in sync. Include the series not selected by legend + if (componentType === 'series') { + each$1(componentModel.seriesGroup, function(seriesModel) { + seriesModel.setCenter(res.center); + seriesModel.setZoom(res.zoom); + }); + } + } + ); + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var mapSymbolLayout = function(ecModel) { + + var processedMapType = {}; + + ecModel.eachSeriesByType('map', function(mapSeries) { + var mapType = mapSeries.getMapType(); + if (mapSeries.getHostGeoModel() || processedMapType[mapType]) { + return; + } + + var mapSymbolOffsets = {}; + + each$1(mapSeries.seriesGroup, function(subMapSeries) { + var geo = subMapSeries.coordinateSystem; + var data = subMapSeries.originalData; + if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) { + data.each(data.mapDimension('value'), function(value, idx) { + var name = data.getName(idx); + var region = geo.getRegion(name); + + // If input series.data is [11, 22, '-'/null/undefined, 44], + // it will be filled with NaN: [11, 22, NaN, 44] and NaN will + // not be drawn. So here must validate if value is NaN. + if (!region || isNaN(value)) { + return; + } + + var offset = mapSymbolOffsets[name] || 0; + + var point = geo.dataToPoint(region.center); + + mapSymbolOffsets[name] = offset + 1; + + data.setItemLayout(idx, { + point: point, + offset: offset + }); + }); + } + }); + + // Show label of those region not has legendSymbol(which is offset 0) + var data = mapSeries.getData(); + data.each(function(idx) { + var name = data.getName(idx); + var layout = data.getItemLayout(idx) || {}; + layout.showLabel = !mapSymbolOffsets[name]; + data.setItemLayout(idx, layout); + }); + + processedMapType[mapType] = true; + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var mapVisual = function(ecModel) { + ecModel.eachSeriesByType('map', function(seriesModel) { + var colorList = seriesModel.get('color'); + var itemStyleModel = seriesModel.getModel('itemStyle'); + + var areaColor = itemStyleModel.get('areaColor'); + var color = itemStyleModel.get('color') || + colorList[seriesModel.seriesIndex % colorList.length]; + + seriesModel.getData().setVisual({ + 'areaColor': areaColor, + 'color': color + }); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME 公用? + /** + * @param {Array.} datas + * @param {string} statisticType 'average' 'sum' + * @inner + */ + function dataStatistics(datas, statisticType) { + var dataNameMap = {}; + + each$1(datas, function(data) { + data.each(data.mapDimension('value'), function(value, idx) { + // Add prefix to avoid conflict with Object.prototype. + var mapKey = 'ec-' + data.getName(idx); + dataNameMap[mapKey] = dataNameMap[mapKey] || []; + if (!isNaN(value)) { + dataNameMap[mapKey].push(value); + } + }); + }); + + return datas[0].map(datas[0].mapDimension('value'), function(value, idx) { + var mapKey = 'ec-' + datas[0].getName(idx); + var sum = 0; + var min = Infinity; + var max = -Infinity; + var len = dataNameMap[mapKey].length; + for (var i = 0; i < len; i++) { + min = Math.min(min, dataNameMap[mapKey][i]); + max = Math.max(max, dataNameMap[mapKey][i]); + sum += dataNameMap[mapKey][i]; + } + var result; + if (statisticType === 'min') { + result = min; + } else if (statisticType === 'max') { + result = max; + } else if (statisticType === 'average') { + result = sum / len; + } else { + result = sum; + } + return len === 0 ? NaN : result; + }); + } + + var mapDataStatistic = function(ecModel) { + var seriesGroups = {}; + ecModel.eachSeriesByType('map', function(seriesModel) { + var hostGeoModel = seriesModel.getHostGeoModel(); + var key = hostGeoModel ? 'o' + hostGeoModel.id : 'i' + seriesModel.getMapType(); + (seriesGroups[key] = seriesGroups[key] || []).push(seriesModel); + }); + + each$1(seriesGroups, function(seriesList, key) { + var data = dataStatistics( + map(seriesList, function(seriesModel) { + return seriesModel.getData(); + }), + seriesList[0].get('mapValueCalculation') + ); + + for (var i = 0; i < seriesList.length; i++) { + seriesList[i].originalData = seriesList[i].getData(); + } + + // FIXME Put where? + for (var i = 0; i < seriesList.length; i++) { + seriesList[i].seriesGroup = seriesList; + seriesList[i].needsDrawMap = i === 0 && !seriesList[i].getHostGeoModel(); + + seriesList[i].setData(data.cloneShallow()); + seriesList[i].mainSeries = seriesList[0]; + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var backwardCompat$2 = function(option) { + // Save geoCoord + var mapSeries = []; + each$1(option.series, function(seriesOpt) { + if (seriesOpt && seriesOpt.type === 'map') { + mapSeries.push(seriesOpt); + seriesOpt.map = seriesOpt.map || seriesOpt.mapType; + // Put x, y, width, height, x2, y2 in the top level + defaults(seriesOpt, seriesOpt.mapLocation); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerLayout(mapSymbolLayout); + registerVisual(mapVisual); + registerProcessor(PRIORITY.PROCESSOR.STATISTIC, mapDataStatistic); + registerPreprocessor(backwardCompat$2); + + createDataSelectAction('map', [{ + type: 'mapToggleSelect', + event: 'mapselectchanged', + method: 'toggleSelected' + }, { + type: 'mapSelect', + event: 'mapselected', + method: 'select' + }, { + type: 'mapUnSelect', + event: 'mapunselected', + method: 'unSelect' + }]); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Link lists and struct (graph or tree) + */ + + var each$7 = each$1; + + var DATAS = '\0__link_datas'; + var MAIN_DATA = '\0__link_mainData'; + + // Caution: + // In most case, either list or its shallow clones (see list.cloneShallow) + // is active in echarts process. So considering heap memory consumption, + // we do not clone tree or graph, but share them among list and its shallow clones. + // But in some rare case, we have to keep old list (like do animation in chart). So + // please take care that both the old list and the new list share the same tree/graph. + + /** + * @param {Object} opt + * @param {module:echarts/data/List} opt.mainData + * @param {Object} [opt.struct] For example, instance of Graph or Tree. + * @param {string} [opt.structAttr] designation: list[structAttr] = struct; + * @param {Object} [opt.datas] {dataType: data}, + * like: {node: nodeList, edge: edgeList}. + * Should contain mainData. + * @param {Object} [opt.datasAttr] {dataType: attr}, + * designation: struct[datasAttr[dataType]] = list; + */ + function linkList(opt) { + var mainData = opt.mainData; + var datas = opt.datas; + + if (!datas) { + datas = { + main: mainData + }; + opt.datasAttr = { + main: 'data' + }; + } + opt.datas = opt.mainData = null; + + linkAll(mainData, datas, opt); + + // Porxy data original methods. + each$7(datas, function(data) { + each$7(mainData.TRANSFERABLE_METHODS, function(methodName) { + data.wrapMethod(methodName, curry(transferInjection, opt)); + }); + + }); + + // Beyond transfer, additional features should be added to `cloneShallow`. + mainData.wrapMethod('cloneShallow', curry(cloneShallowInjection, opt)); + + // Only mainData trigger change, because struct.update may trigger + // another changable methods, which may bring about dead lock. + each$7(mainData.CHANGABLE_METHODS, function(methodName) { + mainData.wrapMethod(methodName, curry(changeInjection, opt)); + }); + + // Make sure datas contains mainData. + assert$1(datas[mainData.dataType] === mainData); + } + + function transferInjection(opt, res) { + if (isMainData(this)) { + // Transfer datas to new main data. + var datas = extend({}, this[DATAS]); + datas[this.dataType] = res; + linkAll(res, datas, opt); + } else { + // Modify the reference in main data to point newData. + linkSingle(res, this.dataType, this[MAIN_DATA], opt); + } + return res; + } + + function changeInjection(opt, res) { + opt.struct && opt.struct.update(this); + return res; + } + + function cloneShallowInjection(opt, res) { + // cloneShallow, which brings about some fragilities, may be inappropriate + // to be exposed as an API. So for implementation simplicity we can make + // the restriction that cloneShallow of not-mainData should not be invoked + // outside, but only be invoked here. + each$7(res[DATAS], function(data, dataType) { + data !== res && linkSingle(data.cloneShallow(), dataType, res, opt); + }); + return res; + } + + /** + * Supplement method to List. + * + * @public + * @param {string} [dataType] If not specified, return mainData. + * @return {module:echarts/data/List} + */ + function getLinkedData(dataType) { + var mainData = this[MAIN_DATA]; + return (dataType == null || mainData == null) ? + mainData : + mainData[DATAS][dataType]; + } + + function isMainData(data) { + return data[MAIN_DATA] === data; + } + + function linkAll(mainData, datas, opt) { + mainData[DATAS] = {}; + each$7(datas, function(data, dataType) { + linkSingle(data, dataType, mainData, opt); + }); + } + + function linkSingle(data, dataType, mainData, opt) { + mainData[DATAS][dataType] = data; + data[MAIN_DATA] = mainData; + data.dataType = dataType; + + if (opt.struct) { + data[opt.structAttr] = opt.struct; + opt.struct[opt.datasAttr[dataType]] = data; + } + + // Supplement method. + data.getLinkedData = getLinkedData; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Tree data structure + * + * @module echarts/data/Tree + */ + + /** + * @constructor module:echarts/data/Tree~TreeNode + * @param {string} name + * @param {module:echarts/data/Tree} hostTree + */ + var TreeNode = function(name, hostTree) { + /** + * @type {string} + */ + this.name = name || ''; + + /** + * Depth of node + * + * @type {number} + * @readOnly + */ + this.depth = 0; + + /** + * Height of the subtree rooted at this node. + * @type {number} + * @readOnly + */ + this.height = 0; + + /** + * @type {module:echarts/data/Tree~TreeNode} + * @readOnly + */ + this.parentNode = null; + + /** + * Reference to list item. + * Do not persistent dataIndex outside, + * besause it may be changed by list. + * If dataIndex -1, + * this node is logical deleted (filtered) in list. + * + * @type {Object} + * @readOnly + */ + this.dataIndex = -1; + + /** + * @type {Array.} + * @readOnly + */ + this.children = []; + + /** + * @type {Array.} + * @pubilc + */ + this.viewChildren = []; + + /** + * @type {moduel:echarts/data/Tree} + * @readOnly + */ + this.hostTree = hostTree; + }; + + TreeNode.prototype = { + + constructor: TreeNode, + + /** + * The node is removed. + * @return {boolean} is removed. + */ + isRemoved: function() { + return this.dataIndex < 0; + }, + + /** + * Travel this subtree (include this node). + * Usage: + * node.eachNode(function () { ... }); // preorder + * node.eachNode('preorder', function () { ... }); // preorder + * node.eachNode('postorder', function () { ... }); // postorder + * node.eachNode( + * {order: 'postorder', attr: 'viewChildren'}, + * function () { ... } + * ); // postorder + * + * @param {(Object|string)} options If string, means order. + * @param {string=} options.order 'preorder' or 'postorder' + * @param {string=} options.attr 'children' or 'viewChildren' + * @param {Function} cb If in preorder and return false, + * its subtree will not be visited. + * @param {Object} [context] + */ + eachNode: function(options, cb, context) { + if (typeof options === 'function') { + context = cb; + cb = options; + options = null; + } + + options = options || {}; + if (isString(options)) { + options = { + order: options + }; + } + + var order = options.order || 'preorder'; + var children = this[options.attr || 'children']; + + var suppressVisitSub; + order === 'preorder' && (suppressVisitSub = cb.call(context, this)); + + for (var i = 0; !suppressVisitSub && i < children.length; i++) { + children[i].eachNode(options, cb, context); + } + + order === 'postorder' && cb.call(context, this); + }, + + /** + * Update depth and height of this subtree. + * + * @param {number} depth + */ + updateDepthAndHeight: function(depth) { + var height = 0; + this.depth = depth; + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.updateDepthAndHeight(depth + 1); + if (child.height > height) { + height = child.height; + } + } + this.height = height + 1; + }, + + /** + * @param {string} id + * @return {module:echarts/data/Tree~TreeNode} + */ + getNodeById: function(id) { + if (this.getId() === id) { + return this; + } + for (var i = 0, children = this.children, len = children.length; i < len; i++) { + var res = children[i].getNodeById(id); + if (res) { + return res; + } + } + }, + + /** + * @param {module:echarts/data/Tree~TreeNode} node + * @return {boolean} + */ + contains: function(node) { + if (node === this) { + return true; + } + for (var i = 0, children = this.children, len = children.length; i < len; i++) { + var res = children[i].contains(node); + if (res) { + return res; + } + } + }, + + /** + * @param {boolean} includeSelf Default false. + * @return {Array.} order: [root, child, grandchild, ...] + */ + getAncestors: function(includeSelf) { + var ancestors = []; + var node = includeSelf ? this : this.parentNode; + while (node) { + ancestors.push(node); + node = node.parentNode; + } + ancestors.reverse(); + return ancestors; + }, + + /** + * @param {string|Array=} [dimension='value'] Default 'value'. can be 0, 1, 2, 3 + * @return {number} Value. + */ + getValue: function(dimension) { + var data = this.hostTree.data; + return data.get(data.getDimension(dimension || 'value'), this.dataIndex); + }, + + /** + * @param {Object} layout + * @param {boolean=} [merge=false] + */ + setLayout: function(layout, merge$$1) { + this.dataIndex >= 0 && + this.hostTree.data.setItemLayout(this.dataIndex, layout, merge$$1); + }, + + /** + * @return {Object} layout + */ + getLayout: function() { + return this.hostTree.data.getItemLayout(this.dataIndex); + }, + + /** + * @param {string} [path] + * @return {module:echarts/model/Model} + */ + getModel: function(path) { + if (this.dataIndex < 0) { + return; + } + var hostTree = this.hostTree; + var itemModel = hostTree.data.getItemModel(this.dataIndex); + var levelModel = this.getLevelModel(); + var leavesModel; + if (!levelModel && (this.children.length === 0 || (this.children.length !== 0 && this.isExpand === false))) { + leavesModel = this.getLeavesModel(); + } + return itemModel.getModel(path, (levelModel || leavesModel || hostTree.hostModel).getModel(path)); + }, + + /** + * @return {module:echarts/model/Model} + */ + getLevelModel: function() { + return (this.hostTree.levelModels || [])[this.depth]; + }, + + /** + * @return {module:echarts/model/Model} + */ + getLeavesModel: function() { + return this.hostTree.leavesModel; + }, + + /** + * @example + * setItemVisual('color', color); + * setItemVisual({ + * 'color': color + * }); + */ + setVisual: function(key, value) { + this.dataIndex >= 0 && + this.hostTree.data.setItemVisual(this.dataIndex, key, value); + }, + + /** + * Get item visual + */ + getVisual: function(key, ignoreParent) { + return this.hostTree.data.getItemVisual(this.dataIndex, key, ignoreParent); + }, + + /** + * @public + * @return {number} + */ + getRawIndex: function() { + return this.hostTree.data.getRawIndex(this.dataIndex); + }, + + /** + * @public + * @return {string} + */ + getId: function() { + return this.hostTree.data.getId(this.dataIndex); + }, + + /** + * if this is an ancestor of another node + * + * @public + * @param {TreeNode} node another node + * @return {boolean} if is ancestor + */ + isAncestorOf: function(node) { + var parent = node.parentNode; + while (parent) { + if (parent === this) { + return true; + } + parent = parent.parentNode; + } + return false; + }, + + /** + * if this is an descendant of another node + * + * @public + * @param {TreeNode} node another node + * @return {boolean} if is descendant + */ + isDescendantOf: function(node) { + return node !== this && node.isAncestorOf(this); + } + }; + + /** + * @constructor + * @alias module:echarts/data/Tree + * @param {module:echarts/model/Model} hostModel + * @param {Array.} levelOptions + * @param {Object} leavesOption + */ + function Tree(hostModel, levelOptions, leavesOption) { + /** + * @type {module:echarts/data/Tree~TreeNode} + * @readOnly + */ + this.root; + + /** + * @type {module:echarts/data/List} + * @readOnly + */ + this.data; + + /** + * Index of each item is the same as the raw index of coresponding list item. + * @private + * @type {Array.} treeOptions.levels + * @param {Array.} treeOptions.leaves + * @return module:echarts/data/Tree + */ + Tree.createTree = function(dataRoot, hostModel, treeOptions) { + + var tree = new Tree(hostModel, treeOptions.levels, treeOptions.leaves); + var listData = []; + var dimMax = 1; + + buildHierarchy(dataRoot); + + function buildHierarchy(dataNode, parentNode) { + var value = dataNode.value; + dimMax = Math.max(dimMax, isArray(value) ? value.length : 1); + + listData.push(dataNode); + + var node = new TreeNode(dataNode.name, tree); + parentNode + ? + addChild(node, parentNode) : + (tree.root = node); + + tree._nodes.push(node); + + var children = dataNode.children; + if (children) { + for (var i = 0; i < children.length; i++) { + buildHierarchy(children[i], node); + } + } + } + + tree.root.updateDepthAndHeight(0); + + var dimensionsInfo = createDimensions(listData, { + coordDimensions: ['value'], + dimensionsCount: dimMax + }); + + var list = new List(dimensionsInfo, hostModel); + list.initData(listData); + + linkList({ + mainData: list, + struct: tree, + structAttr: 'tree' + }); + + tree.update(); + + return tree; + }; + + /** + * It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote, + * so this function is not ready and not necessary to be public. + * + * @param {(module:echarts/data/Tree~TreeNode|Object)} child + */ + function addChild(child, node) { + var children = node.children; + if (child.parentNode === node) { + return; + } + + children.push(child); + child.parentNode = node; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Create data struct and define tree view's series model + */ + + SeriesModel.extend({ + + type: 'series.tree', + + layoutInfo: null, + + // can support the position parameters 'left', 'top','right','bottom', 'width', + // 'height' in the setOption() with 'merge' mode normal. + layoutMode: 'box', + + /** + * Init a tree data structure from data in option series + * @param {Object} option the object used to config echarts view + * @return {module:echarts/data/List} storage initial data + */ + getInitialData: function(option) { + + //create an virtual root + var root = { + name: option.name, + children: option.data + }; + + var leaves = option.leaves || {}; + + var treeOption = {}; + + treeOption.leaves = leaves; + + var tree = Tree.createTree(root, this, treeOption); + + var treeDepth = 0; + + tree.eachNode('preorder', function(node) { + if (node.depth > treeDepth) { + treeDepth = node.depth; + } + }); + + var expandAndCollapse = option.expandAndCollapse; + var expandTreeDepth = (expandAndCollapse && option.initialTreeDepth >= 0) ? + option.initialTreeDepth : treeDepth; + + tree.root.eachNode('preorder', function(node) { + var item = node.hostTree.data.getRawDataItem(node.dataIndex); + // add item.collapsed != null, because users can collapse node original in the series.data. + node.isExpand = (item && item.collapsed != null) ? + !item.collapsed : + node.depth <= expandTreeDepth; + }); + + return tree.data; + }, + + /** + * Make the configuration 'orient' backward compatibly, with 'horizontal = LR', 'vertical = TB'. + * @returns {string} orient + */ + getOrient: function() { + var orient = this.get('orient'); + if (orient === 'horizontal') { + orient = 'LR'; + } else if (orient === 'vertical') { + orient = 'TB'; + } + return orient; + }, + + /** + * @override + * @param {number} dataIndex + */ + formatTooltip: function(dataIndex) { + var tree = this.getData().tree; + var realRoot = tree.root.children[0]; + var node = tree.getNodeByDataIndex(dataIndex); + var value = node.getValue(); + var name = node.name; + while (node && (node !== realRoot)) { + name = node.parentNode.name + '.' + name; + node = node.parentNode; + } + return encodeHTML(name + ( + (isNaN(value) || value == null) ? '' : ' : ' + value + )); + }, + + defaultOption: { + zlevel: 0, + z: 2, + + // the position of the whole view + left: '12%', + top: '12%', + right: '12%', + bottom: '12%', + + // the layout of the tree, two value can be selected, 'orthogonal' or 'radial' + layout: 'orthogonal', + + // The orient of orthoginal layout, can be setted to 'LR', 'TB', 'RL', 'BT'. + // and the backward compatibility configuration 'horizontal = LR', 'vertical = TB'. + orient: 'LR', + + symbol: 'emptyCircle', + + symbolSize: 7, + + expandAndCollapse: true, + + initialTreeDepth: 2, + + lineStyle: { + color: '#ccc', + width: 1.5, + curveness: 0.5 + }, + + itemStyle: { + color: 'lightsteelblue', + borderColor: '#c23531', + borderWidth: 1.5 + }, + + label: { + show: true, + color: '#555' + }, + + leaves: { + label: { + show: true + } + }, + + animationEasing: 'linear', + + animationDuration: 700, + + animationDurationUpdate: 1000 + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * The tree layout implementation references to d3.js + * (https://github.com/d3/d3-hierarchy). The use of the source + * code of this file is also subject to the terms and consitions + * of its license (BSD-3Clause, see ). + */ + + /** + * @file The layout algorithm of node-link tree diagrams. Here we using Reingold-Tilford algorithm to drawing + * the tree. + * @see https://github.com/d3/d3-hierarchy + */ + + /** + * Initialize all computational message for following algorithm + * @param {module:echarts/data/Tree~TreeNode} root The virtual root of the tree + */ + function init$2(root) { + root.hierNode = { + defaultAncestor: null, + ancestor: root, + prelim: 0, + modifier: 0, + change: 0, + shift: 0, + i: 0, + thread: null + }; + + var nodes = [root]; + var node; + var children; + + while (node = nodes.pop()) { // jshint ignore:line + children = node.children; + if (node.isExpand && children.length) { + var n = children.length; + for (var i = n - 1; i >= 0; i--) { + var child = children[i]; + child.hierNode = { + defaultAncestor: null, + ancestor: child, + prelim: 0, + modifier: 0, + change: 0, + shift: 0, + i: i, + thread: null + }; + nodes.push(child); + } + } + } + } + + /** + * Computes a preliminary x coordinate for node. Before that, this function is + * applied recursively to the children of node, as well as the function + * apportion(). After spacing out the children by calling executeShifts(), the + * node is placed to the midpoint of its outermost children. + * @param {module:echarts/data/Tree~TreeNode} node + * @param {Function} separation + */ + function firstWalk(node, separation) { + var children = node.isExpand ? node.children : []; + var siblings = node.parentNode.children; + var subtreeW = node.hierNode.i ? siblings[node.hierNode.i - 1] : null; + if (children.length) { + executeShifts(node); + var midPoint = (children[0].hierNode.prelim + children[children.length - 1].hierNode.prelim) / 2; + if (subtreeW) { + node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW); + node.hierNode.modifier = node.hierNode.prelim - midPoint; + } else { + node.hierNode.prelim = midPoint; + } + } else if (subtreeW) { + node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW); + } + node.parentNode.hierNode.defaultAncestor = apportion(node, subtreeW, node.parentNode.hierNode.defaultAncestor || + siblings[0], separation); + } + + + /** + * Computes all real x-coordinates by summing up the modifiers recursively. + * @param {module:echarts/data/Tree~TreeNode} node + */ + function secondWalk(node) { + var nodeX = node.hierNode.prelim + node.parentNode.hierNode.modifier; + node.setLayout({ + x: nodeX + }, true); + node.hierNode.modifier += node.parentNode.hierNode.modifier; + } + + + function separation(cb) { + return arguments.length ? cb : defaultSeparation; + } + + /** + * Transform the common coordinate to radial coordinate + * @param {number} x + * @param {number} y + * @return {Object} + */ + function radialCoordinate(x, y) { + var radialCoor = {}; + x -= Math.PI / 2; + radialCoor.x = y * Math.cos(x); + radialCoor.y = y * Math.sin(x); + return radialCoor; + } + + /** + * Get the layout position of the whole view + * @param {module:echarts/model/Series} seriesModel the model object of sankey series + * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call + * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view + */ + function getViewRect(seriesModel, api) { + return getLayoutRect( + seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + } + + /** + * All other shifts, applied to the smaller subtrees between w- and w+, are + * performed by this function. + * @param {module:echarts/data/Tree~TreeNode} node + */ + function executeShifts(node) { + var children = node.children; + var n = children.length; + var shift = 0; + var change = 0; + while (--n >= 0) { + var child = children[n]; + child.hierNode.prelim += shift; + child.hierNode.modifier += shift; + change += child.hierNode.change; + shift += child.hierNode.shift + change; + } + } + + /** + * The core of the algorithm. Here, a new subtree is combined with the + * previous subtrees. Threads are used to traverse the inside and outside + * contours of the left and right subtree up to the highest common level. + * Whenever two nodes of the inside contours conflict, we compute the left + * one of the greatest uncommon ancestors using the function nextAncestor() + * and call moveSubtree() to shift the subtree and prepare the shifts of + * smaller subtrees. Finally, we add a new thread (if necessary). + * @param {module:echarts/data/Tree~TreeNode} subtreeV + * @param {module:echarts/data/Tree~TreeNode} subtreeW + * @param {module:echarts/data/Tree~TreeNode} ancestor + * @param {Function} separation + * @return {module:echarts/data/Tree~TreeNode} + */ + function apportion(subtreeV, subtreeW, ancestor, separation) { + + if (subtreeW) { + var nodeOutRight = subtreeV; + var nodeInRight = subtreeV; + var nodeOutLeft = nodeInRight.parentNode.children[0]; + var nodeInLeft = subtreeW; + + var sumOutRight = nodeOutRight.hierNode.modifier; + var sumInRight = nodeInRight.hierNode.modifier; + var sumOutLeft = nodeOutLeft.hierNode.modifier; + var sumInLeft = nodeInLeft.hierNode.modifier; + + while (nodeInLeft = nextRight(nodeInLeft), nodeInRight = nextLeft(nodeInRight), nodeInLeft && nodeInRight) { + nodeOutRight = nextRight(nodeOutRight); + nodeOutLeft = nextLeft(nodeOutLeft); + nodeOutRight.hierNode.ancestor = subtreeV; + var shift = nodeInLeft.hierNode.prelim + sumInLeft - nodeInRight.hierNode.prelim - + sumInRight + separation(nodeInLeft, nodeInRight); + if (shift > 0) { + moveSubtree(nextAncestor(nodeInLeft, subtreeV, ancestor), subtreeV, shift); + sumInRight += shift; + sumOutRight += shift; + } + sumInLeft += nodeInLeft.hierNode.modifier; + sumInRight += nodeInRight.hierNode.modifier; + sumOutRight += nodeOutRight.hierNode.modifier; + sumOutLeft += nodeOutLeft.hierNode.modifier; + } + if (nodeInLeft && !nextRight(nodeOutRight)) { + nodeOutRight.hierNode.thread = nodeInLeft; + nodeOutRight.hierNode.modifier += sumInLeft - sumOutRight; + + } + if (nodeInRight && !nextLeft(nodeOutLeft)) { + nodeOutLeft.hierNode.thread = nodeInRight; + nodeOutLeft.hierNode.modifier += sumInRight - sumOutLeft; + ancestor = subtreeV; + } + } + return ancestor; + } + + /** + * This function is used to traverse the right contour of a subtree. + * It returns the rightmost child of node or the thread of node. The function + * returns null if and only if node is on the highest depth of its subtree. + * @param {module:echarts/data/Tree~TreeNode} node + * @return {module:echarts/data/Tree~TreeNode} + */ + function nextRight(node) { + var children = node.children; + return children.length && node.isExpand ? children[children.length - 1] : node.hierNode.thread; + } + + /** + * This function is used to traverse the left contour of a subtree (or a subforest). + * It returns the leftmost child of node or the thread of node. The function + * returns null if and only if node is on the highest depth of its subtree. + * @param {module:echarts/data/Tree~TreeNode} node + * @return {module:echarts/data/Tree~TreeNode} + */ + function nextLeft(node) { + var children = node.children; + return children.length && node.isExpand ? children[0] : node.hierNode.thread; + } + + /** + * If nodeInLeft’s ancestor is a sibling of node, returns nodeInLeft’s ancestor. + * Otherwise, returns the specified ancestor. + * @param {module:echarts/data/Tree~TreeNode} nodeInLeft + * @param {module:echarts/data/Tree~TreeNode} node + * @param {module:echarts/data/Tree~TreeNode} ancestor + * @return {module:echarts/data/Tree~TreeNode} + */ + function nextAncestor(nodeInLeft, node, ancestor) { + return nodeInLeft.hierNode.ancestor.parentNode === node.parentNode ? + nodeInLeft.hierNode.ancestor : ancestor; + } + + /** + * Shifts the current subtree rooted at wr. This is done by increasing prelim(w+) and modifier(w+) by shift. + * @param {module:echarts/data/Tree~TreeNode} wl + * @param {module:echarts/data/Tree~TreeNode} wr + * @param {number} shift [description] + */ + function moveSubtree(wl, wr, shift) { + var change = shift / (wr.hierNode.i - wl.hierNode.i); + wr.hierNode.change -= change; + wr.hierNode.shift += shift; + wr.hierNode.modifier += shift; + wr.hierNode.prelim += shift; + wl.hierNode.change += change; + } + + function defaultSeparation(node1, node2) { + return node1.parentNode === node2.parentNode ? 1 : 2; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file This file used to draw tree view + */ + + extendChartView({ + + type: 'tree', + + /** + * Init the chart + * @override + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + init: function(ecModel, api) { + + /** + * @private + * @type {module:echarts/data/Tree} + */ + this._oldTree; + + /** + * @private + * @type {module:zrender/container/Group} + */ + this._mainGroup = new Group(); + + this.group.add(this._mainGroup); + }, + + render: function(seriesModel, ecModel, api, payload) { + + var data = seriesModel.getData(); + + var layoutInfo = seriesModel.layoutInfo; + + var group = this._mainGroup; + + var layout = seriesModel.get('layout'); + + if (layout === 'radial') { + group.attr('position', [layoutInfo.x + layoutInfo.width / 2, layoutInfo.y + layoutInfo.height / 2]); + } else { + group.attr('position', [layoutInfo.x, layoutInfo.y]); + } + + var oldData = this._data; + + var seriesScope = { + expandAndCollapse: seriesModel.get('expandAndCollapse'), + layout: layout, + orient: seriesModel.getOrient(), + curvature: seriesModel.get('lineStyle.curveness'), + symbolRotate: seriesModel.get('symbolRotate'), + symbolOffset: seriesModel.get('symbolOffset'), + hoverAnimation: seriesModel.get('hoverAnimation'), + useNameLabel: true, + fadeIn: true + }; + + data.diff(oldData) + .add(function(newIdx) { + if (symbolNeedsDraw$1(data, newIdx)) { + // create node and edge + updateNode(data, newIdx, null, group, seriesModel, seriesScope); + } + }) + .update(function(newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + if (!symbolNeedsDraw$1(data, newIdx)) { + symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope); + return; + } + // update node and edge + updateNode(data, newIdx, symbolEl, group, seriesModel, seriesScope); + }) + .remove(function(oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + // When remove a collapsed node of subtree, since the collapsed + // node haven't been initialized with a symbol element, + // you can't found it's symbol element through index. + // so if we want to remove the symbol element we should insure + // that the symbol element is not null. + if (symbolEl) { + removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope); + } + }) + .execute(); + + if (seriesScope.expandAndCollapse === true) { + data.eachItemGraphicEl(function(el, dataIndex) { + el.off('click').on('click', function() { + api.dispatchAction({ + type: 'treeExpandAndCollapse', + seriesId: seriesModel.id, + dataIndex: dataIndex + }); + }); + }); + } + + this._data = data; + }, + + dispose: function() {}, + + remove: function() { + this._mainGroup.removeAll(); + this._data = null; + } + + }); + + function symbolNeedsDraw$1(data, dataIndex) { + var layout = data.getItemLayout(dataIndex); + + return layout && + !isNaN(layout.x) && !isNaN(layout.y) && + data.getItemVisual(dataIndex, 'symbol') !== 'none'; + } + + function getTreeNodeStyle(node, itemModel, seriesScope) { + seriesScope.itemModel = itemModel; + seriesScope.itemStyle = itemModel.getModel('itemStyle').getItemStyle(); + seriesScope.hoverItemStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle(); + seriesScope.lineStyle = itemModel.getModel('lineStyle').getLineStyle(); + seriesScope.labelModel = itemModel.getModel('label'); + seriesScope.hoverLabelModel = itemModel.getModel('emphasis.label'); + + if (node.isExpand === false && node.children.length !== 0) { + seriesScope.symbolInnerColor = seriesScope.itemStyle.fill; + } else { + seriesScope.symbolInnerColor = '#fff'; + } + + return seriesScope; + } + + function updateNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) { + var isInit = !symbolEl; + var node = data.tree.getNodeByDataIndex(dataIndex); + var itemModel = node.getModel(); + var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope); + var virtualRoot = data.tree.root; + + var source = node.parentNode === virtualRoot ? node : node.parentNode || node; + var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex); + var sourceLayout = source.getLayout(); + var sourceOldLayout = sourceSymbolEl ? + { + x: sourceSymbolEl.position[0], + y: sourceSymbolEl.position[1], + rawX: sourceSymbolEl.__radialOldRawX, + rawY: sourceSymbolEl.__radialOldRawY + } : + sourceLayout; + var targetLayout = node.getLayout(); + + if (isInit) { + symbolEl = new SymbolClz$1(data, dataIndex, seriesScope); + symbolEl.attr('position', [sourceOldLayout.x, sourceOldLayout.y]); + } else { + symbolEl.updateData(data, dataIndex, seriesScope); + } + + symbolEl.__radialOldRawX = symbolEl.__radialRawX; + symbolEl.__radialOldRawY = symbolEl.__radialRawY; + symbolEl.__radialRawX = targetLayout.rawX; + symbolEl.__radialRawY = targetLayout.rawY; + + group.add(symbolEl); + data.setItemGraphicEl(dataIndex, symbolEl); + updateProps(symbolEl, { + position: [targetLayout.x, targetLayout.y] + }, seriesModel); + + var symbolPath = symbolEl.getSymbolPath(); + + if (seriesScope.layout === 'radial') { + var realRoot = virtualRoot.children[0]; + var rootLayout = realRoot.getLayout(); + var length = realRoot.children.length; + var rad; + var isLeft; + + if (targetLayout.x === rootLayout.x && node.isExpand === true) { + var center = {}; + center.x = (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2; + center.y = (realRoot.children[0].getLayout().y + realRoot.children[length - 1].getLayout().y) / 2; + rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + isLeft = center.x < rootLayout.x; + if (isLeft) { + rad = rad - Math.PI; + } + } else { + rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + if (node.children.length === 0 || (node.children.length !== 0 && node.isExpand === false)) { + isLeft = targetLayout.x < rootLayout.x; + if (isLeft) { + rad = rad - Math.PI; + } + } else { + isLeft = targetLayout.x > rootLayout.x; + if (!isLeft) { + rad = rad - Math.PI; + } + } + } + + var textPosition = isLeft ? 'left' : 'right'; + symbolPath.setStyle({ + textPosition: textPosition, + textRotation: -rad, + textOrigin: 'center', + verticalAlign: 'middle' + }); + } + + if (node.parentNode && node.parentNode !== virtualRoot) { + var edge = symbolEl.__edge; + if (!edge) { + edge = symbolEl.__edge = new BezierCurve({ + shape: getEdgeShape(seriesScope, sourceOldLayout, sourceOldLayout), + style: defaults({ + opacity: 0 + }, seriesScope.lineStyle) + }); + } + + updateProps(edge, { + shape: getEdgeShape(seriesScope, sourceLayout, targetLayout), + style: { + opacity: 1 + } + }, seriesModel); + + group.add(edge); + } + } + + function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) { + var node = data.tree.getNodeByDataIndex(dataIndex); + var virtualRoot = data.tree.root; + var itemModel = node.getModel(); + var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope); + + var source = node.parentNode === virtualRoot ? node : node.parentNode || node; + var sourceLayout; + while (sourceLayout = source.getLayout(), sourceLayout == null) { + source = source.parentNode === virtualRoot ? source : source.parentNode || source; + } + + updateProps(symbolEl, { + position: [sourceLayout.x + 1, sourceLayout.y + 1] + }, seriesModel, function() { + group.remove(symbolEl); + data.setItemGraphicEl(dataIndex, null); + }); + + symbolEl.fadeOut(null, { + keepLabel: true + }); + + var edge = symbolEl.__edge; + if (edge) { + updateProps(edge, { + shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout), + style: { + opacity: 0 + } + }, seriesModel, function() { + group.remove(edge); + }); + } + } + + function getEdgeShape(seriesScope, sourceLayout, targetLayout) { + var cpx1; + var cpy1; + var cpx2; + var cpy2; + var orient = seriesScope.orient; + + if (seriesScope.layout === 'radial') { + var x1 = sourceLayout.rawX; + var y1 = sourceLayout.rawY; + var x2 = targetLayout.rawX; + var y2 = targetLayout.rawY; + + var radialCoor1 = radialCoordinate(x1, y1); + var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * seriesScope.curvature); + var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * seriesScope.curvature); + var radialCoor4 = radialCoordinate(x2, y2); + + return { + x1: radialCoor1.x, + y1: radialCoor1.y, + x2: radialCoor4.x, + y2: radialCoor4.y, + cpx1: radialCoor2.x, + cpy1: radialCoor2.y, + cpx2: radialCoor3.x, + cpy2: radialCoor3.y + }; + } else { + var x1 = sourceLayout.x; + var y1 = sourceLayout.y; + var x2 = targetLayout.x; + var y2 = targetLayout.y; + + if (orient === 'LR' || orient === 'RL') { + cpx1 = x1 + (x2 - x1) * seriesScope.curvature; + cpy1 = y1; + cpx2 = x2 + (x1 - x2) * seriesScope.curvature; + cpy2 = y2; + } + if (orient === 'TB' || orient === 'BT') { + cpx1 = x1; + cpy1 = y1 + (y2 - y1) * seriesScope.curvature; + cpx2 = x2; + cpy2 = y2 + (y1 - y2) * seriesScope.curvature; + } + return { + x1: x1, + y1: y1, + x2: x2, + y2: y2, + cpx1: cpx1, + cpy1: cpy1, + cpx2: cpx2, + cpy2: cpy2 + }; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerAction({ + type: 'treeExpandAndCollapse', + event: 'treeExpandAndCollapse', + update: 'update' + }, function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'tree', + query: payload + }, function(seriesModel) { + var dataIndex = payload.dataIndex; + var tree = seriesModel.getData().tree; + var node = tree.getNodeByDataIndex(dataIndex); + node.isExpand = !node.isExpand; + + }); + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * Traverse the tree from bottom to top and do something + * @param {module:echarts/data/Tree~TreeNode} root The real root of the tree + * @param {Function} callback + */ + function eachAfter(root, callback, separation) { + var nodes = [root]; + var next = []; + var node; + + while (node = nodes.pop()) { // jshint ignore:line + next.push(node); + if (node.isExpand) { + var children = node.children; + if (children.length) { + for (var i = 0; i < children.length; i++) { + nodes.push(children[i]); + } + } + } + } + + while (node = next.pop()) { // jshint ignore:line + callback(node, separation); + } + } + + /** + * Traverse the tree from top to bottom and do something + * @param {module:echarts/data/Tree~TreeNode} root The real root of the tree + * @param {Function} callback + */ + function eachBefore(root, callback) { + var nodes = [root]; + var node; + while (node = nodes.pop()) { // jshint ignore:line + callback(node); + if (node.isExpand) { + var children = node.children; + if (children.length) { + for (var i = children.length - 1; i >= 0; i--) { + nodes.push(children[i]); + } + } + } + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var treeLayout = function(ecModel, api) { + ecModel.eachSeriesByType('tree', function(seriesModel) { + commonLayout(seriesModel, api); + }); + }; + + function commonLayout(seriesModel, api) { + var layoutInfo = getViewRect(seriesModel, api); + seriesModel.layoutInfo = layoutInfo; + var layout = seriesModel.get('layout'); + var width = 0; + var height = 0; + var separation$$1 = null; + + if (layout === 'radial') { + width = 2 * Math.PI; + height = Math.min(layoutInfo.height, layoutInfo.width) / 2; + separation$$1 = separation(function(node1, node2) { + return (node1.parentNode === node2.parentNode ? 1 : 2) / node1.depth; + }); + } else { + width = layoutInfo.width; + height = layoutInfo.height; + separation$$1 = separation(); + } + + var virtualRoot = seriesModel.getData().tree.root; + var realRoot = virtualRoot.children[0]; + + if (realRoot) { + init$2(virtualRoot); + eachAfter(realRoot, firstWalk, separation$$1); + virtualRoot.hierNode.modifier = -realRoot.hierNode.prelim; + eachBefore(realRoot, secondWalk); + + var left = realRoot; + var right = realRoot; + var bottom = realRoot; + eachBefore(realRoot, function(node) { + var x = node.getLayout().x; + if (x < left.getLayout().x) { + left = node; + } + if (x > right.getLayout().x) { + right = node; + } + if (node.depth > bottom.depth) { + bottom = node; + } + }); + + var delta = left === right ? 1 : separation$$1(left, right) / 2; + var tx = delta - left.getLayout().x; + var kx = 0; + var ky = 0; + var coorX = 0; + var coorY = 0; + if (layout === 'radial') { + kx = width / (right.getLayout().x + delta + tx); + // here we use (node.depth - 1), bucause the real root's depth is 1 + ky = height / ((bottom.depth - 1) || 1); + eachBefore(realRoot, function(node) { + coorX = (node.getLayout().x + tx) * kx; + coorY = (node.depth - 1) * ky; + var finalCoor = radialCoordinate(coorX, coorY); + node.setLayout({ + x: finalCoor.x, + y: finalCoor.y, + rawX: coorX, + rawY: coorY + }, true); + }); + } else { + var orient = seriesModel.getOrient(); + if (orient === 'RL' || orient === 'LR') { + ky = height / (right.getLayout().x + delta + tx); + kx = width / ((bottom.depth - 1) || 1); + eachBefore(realRoot, function(node) { + coorY = (node.getLayout().x + tx) * ky; + coorX = orient === 'LR' ? + (node.depth - 1) * kx : + width - (node.depth - 1) * kx; + node.setLayout({ + x: coorX, + y: coorY + }, true); + }); + } else if (orient === 'TB' || orient === 'BT') { + kx = width / (right.getLayout().x + delta + tx); + ky = height / ((bottom.depth - 1) || 1); + eachBefore(realRoot, function(node) { + coorX = (node.getLayout().x + tx) * kx; + coorY = orient === 'TB' ? + (node.depth - 1) * ky : + height - (node.depth - 1) * ky; + node.setLayout({ + x: coorX, + y: coorY + }, true); + }); + } + } + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(visualSymbol('tree', 'circle')); + registerLayout(treeLayout); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function retrieveTargetInfo(payload, validPayloadTypes, seriesModel) { + if (payload && indexOf(validPayloadTypes, payload.type) >= 0) { + var root = seriesModel.getData().tree.root; + var targetNode = payload.targetNode; + if (targetNode && root.contains(targetNode)) { + return { + node: targetNode + }; + } + + var targetNodeId = payload.targetNodeId; + if (targetNodeId != null && (targetNode = root.getNodeById(targetNodeId))) { + return { + node: targetNode + }; + } + } + } + + // Not includes the given node at the last item. + function getPathToRoot(node) { + var path = []; + while (node) { + node = node.parentNode; + node && path.push(node); + } + return path.reverse(); + } + + function aboveViewRoot(viewRoot, node) { + var viewPath = getPathToRoot(viewRoot); + return indexOf(viewPath, node) >= 0; + } + + // From root to the input node (the input node will be included). + function wrapTreePathInfo(node, seriesModel) { + var treePathInfo = []; + + while (node) { + var nodeDataIndex = node.dataIndex; + treePathInfo.push({ + name: node.name, + dataIndex: nodeDataIndex, + value: seriesModel.getRawValue(nodeDataIndex) + }); + node = node.parentNode; + } + + treePathInfo.reverse(); + + return treePathInfo; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.treemap', + + layoutMode: 'box', + + dependencies: ['grid', 'polar'], + + /** + * @type {module:echarts/data/Tree~Node} + */ + _viewRoot: null, + + defaultOption: { + // Disable progressive rendering + progressive: 0, + hoverLayerThreshold: Infinity, + // center: ['50%', '50%'], // not supported in ec3. + // size: ['80%', '80%'], // deprecated, compatible with ec2. + left: 'center', + top: 'middle', + right: null, + bottom: null, + width: '80%', + height: '80%', + sort: true, // Can be null or false or true + // (order by desc default, asc not supported yet (strange effect)) + clipWindow: 'origin', // Size of clipped window when zooming. 'origin' or 'fullscreen' + squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio + leafDepth: null, // Nodes on depth from root are regarded as leaves. + // Count from zero (zero represents only view root). + drillDownIcon: '▶', // Use html character temporarily because it is complicated + // to align specialized icon. ▷▶❒❐▼✚ + + zoomToNodeRatio: 0.32 * 0.32, // Be effective when using zoomToNode. Specify the proportion of the + // target node area in the view area. + roam: true, // true, false, 'scale' or 'zoom', 'move'. + nodeClick: 'zoomToNode', // Leaf node click behaviour: 'zoomToNode', 'link', false. + // If leafDepth is set and clicking a node which has children but + // be on left depth, the behaviour would be changing root. Otherwise + // use behavious defined above. + animation: true, + animationDurationUpdate: 900, + animationEasing: 'quinticInOut', + breadcrumb: { + show: true, + height: 22, + left: 'center', + top: 'bottom', + // right + // bottom + emptyItemWidth: 25, // Width of empty node. + itemStyle: { + color: 'rgba(0,0,0,0.7)', //'#5793f3', + borderColor: 'rgba(255,255,255,0.7)', + borderWidth: 1, + shadowColor: 'rgba(150,150,150,1)', + shadowBlur: 3, + shadowOffsetX: 0, + shadowOffsetY: 0, + textStyle: { + color: '#fff' + } + }, + emphasis: { + textStyle: {} + } + }, + label: { + show: true, + // Do not use textDistance, for ellipsis rect just the same as treemap node rect. + distance: 0, + padding: 5, + position: 'inside', // Can be [5, '5%'] or position stirng like 'insideTopLeft', ... + // formatter: null, + color: '#fff', + ellipsis: true + // align + // verticalAlign + }, + upperLabel: { // Label when node is parent. + show: false, + position: [0, '50%'], + height: 20, + // formatter: null, + color: '#fff', + ellipsis: true, + // align: null, + verticalAlign: 'middle' + }, + itemStyle: { + color: null, // Can be 'none' if not necessary. + colorAlpha: null, // Can be 'none' if not necessary. + colorSaturation: null, // Can be 'none' if not necessary. + borderWidth: 0, + gapWidth: 0, + borderColor: '#fff', + borderColorSaturation: null // If specified, borderColor will be ineffective, and the + // border color is evaluated by color of current node and + // borderColorSaturation. + }, + emphasis: { + upperLabel: { + show: true, + position: [0, '50%'], + color: '#fff', + ellipsis: true, + verticalAlign: 'middle' + } + }, + + visualDimension: 0, // Can be 0, 1, 2, 3. + visualMin: null, + visualMax: null, + + color: [], // + treemapSeries.color should not be modified. Please only modified + // level[n].color (if necessary). + // + Specify color list of each level. level[0].color would be global + // color list if not specified. (see method `setDefault`). + // + But set as a empty array to forbid fetch color from global palette + // when using nodeModel.get('color'), otherwise nodes on deep level + // will always has color palette set and are not able to inherit color + // from parent node. + // + TreemapSeries.color can not be set as 'none', otherwise effect + // legend color fetching (see seriesColor.js). + colorAlpha: null, // Array. Specify color alpha range of each level, like [0.2, 0.8] + colorSaturation: null, // Array. Specify color saturation of each level, like [0.2, 0.5] + colorMappingBy: 'index', // 'value' or 'index' or 'id'. + visibleMin: 10, // If area less than this threshold (unit: pixel^2), node will not + // be rendered. Only works when sort is 'asc' or 'desc'. + childrenVisibleMin: null, // If area of a node less than this threshold (unit: pixel^2), + // grandchildren will not show. + // Why grandchildren? If not grandchildren but children, + // some siblings show children and some not, + // the appearance may be mess and not consistent, + levels: [] // Each item: { + // visibleMin, itemStyle, visualDimension, label + // } + // data: { + // value: [], + // children: [], + // link: 'http://xxx.xxx.xxx', + // target: 'blank' or 'self' + // } + }, + + /** + * @override + */ + getInitialData: function(option, ecModel) { + // Create a virtual root. + var root = { + name: option.name, + children: option.data + }; + + completeTreeValue(root); + + var levels = option.levels || []; + + levels = option.levels = setDefault(levels, ecModel); + + var treeOption = {}; + + treeOption.levels = levels; + + // Make sure always a new tree is created when setOption, + // in TreemapView, we check whether oldTree === newTree + // to choose mappings approach among old shapes and new shapes. + return Tree.createTree(root, this, treeOption).data; + }, + + optionUpdated: function() { + this.resetViewRoot(); + }, + + /** + * @override + * @param {number} dataIndex + * @param {boolean} [mutipleSeries=false] + */ + formatTooltip: function(dataIndex) { + var data = this.getData(); + var value = this.getRawValue(dataIndex); + var formattedValue = isArray(value) ? + addCommas(value[0]) : addCommas(value); + var name = data.getName(dataIndex); + + return encodeHTML(name + ': ' + formattedValue); + }, + + /** + * Add tree path to tooltip param + * + * @override + * @param {number} dataIndex + * @return {Object} + */ + getDataParams: function(dataIndex) { + var params = SeriesModel.prototype.getDataParams.apply(this, arguments); + + var node = this.getData().tree.getNodeByDataIndex(dataIndex); + params.treePathInfo = wrapTreePathInfo(node, this); + + return params; + }, + + /** + * @public + * @param {Object} layoutInfo { + * x: containerGroup x + * y: containerGroup y + * width: containerGroup width + * height: containerGroup height + * } + */ + setLayoutInfo: function(layoutInfo) { + /** + * @readOnly + * @type {Object} + */ + this.layoutInfo = this.layoutInfo || {}; + extend(this.layoutInfo, layoutInfo); + }, + + /** + * @param {string} id + * @return {number} index + */ + mapIdToIndex: function(id) { + // A feature is implemented: + // index is monotone increasing with the sequence of + // input id at the first time. + // This feature can make sure that each data item and its + // mapped color have the same index between data list and + // color list at the beginning, which is useful for user + // to adjust data-color mapping. + + /** + * @private + * @type {Object} + */ + var idIndexMap = this._idIndexMap; + + if (!idIndexMap) { + idIndexMap = this._idIndexMap = createHashMap(); + /** + * @private + * @type {number} + */ + this._idIndexMapCount = 0; + } + + var index = idIndexMap.get(id); + if (index == null) { + idIndexMap.set(id, index = this._idIndexMapCount++); + } + + return index; + }, + + getViewRoot: function() { + return this._viewRoot; + }, + + /** + * @param {module:echarts/data/Tree~Node} [viewRoot] + */ + resetViewRoot: function(viewRoot) { + viewRoot + ? + (this._viewRoot = viewRoot) : + (viewRoot = this._viewRoot); + + var root = this.getRawData().tree.root; + + if (!viewRoot || + (viewRoot !== root && !root.contains(viewRoot)) + ) { + this._viewRoot = root; + } + } + }); + + /** + * @param {Object} dataNode + */ + function completeTreeValue(dataNode) { + // Postorder travel tree. + // If value of none-leaf node is not set, + // calculate it by suming up the value of all children. + var sum = 0; + + each$1(dataNode.children, function(child) { + + completeTreeValue(child); + + var childValue = child.value; + isArray(childValue) && (childValue = childValue[0]); + + sum += childValue; + }); + + var thisValue = dataNode.value; + if (isArray(thisValue)) { + thisValue = thisValue[0]; + } + + if (thisValue == null || isNaN(thisValue)) { + thisValue = sum; + } + // Value should not less than 0. + if (thisValue < 0) { + thisValue = 0; + } + + isArray(dataNode.value) ? + (dataNode.value[0] = thisValue) : + (dataNode.value = thisValue); + } + + /** + * set default to level configuration + */ + function setDefault(levels, ecModel) { + var globalColorList = ecModel.get('color'); + + if (!globalColorList) { + return; + } + + levels = levels || []; + var hasColorDefine; + each$1(levels, function(levelDefine) { + var model = new Model(levelDefine); + var modelColor = model.get('color'); + + if (model.get('itemStyle.color') || + (modelColor && modelColor !== 'none') + ) { + hasColorDefine = true; + } + }); + + if (!hasColorDefine) { + var level0 = levels[0] || (levels[0] = {}); + level0.color = globalColorList.slice(); + } + + return levels; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var TEXT_PADDING = 8; + var ITEM_GAP = 8; + var ARRAY_LENGTH = 5; + + function Breadcrumb(containerGroup) { + /** + * @private + * @type {module:zrender/container/Group} + */ + this.group = new Group(); + + containerGroup.add(this.group); + } + + Breadcrumb.prototype = { + + constructor: Breadcrumb, + + render: function(seriesModel, api, targetNode, onSelect) { + var model = seriesModel.getModel('breadcrumb'); + var thisGroup = this.group; + + thisGroup.removeAll(); + + if (!model.get('show') || !targetNode) { + return; + } + + var normalStyleModel = model.getModel('itemStyle'); + // var emphasisStyleModel = model.getModel('emphasis.itemStyle'); + var textStyleModel = normalStyleModel.getModel('textStyle'); + + var layoutParam = { + pos: { + left: model.get('left'), + right: model.get('right'), + top: model.get('top'), + bottom: model.get('bottom') + }, + box: { + width: api.getWidth(), + height: api.getHeight() + }, + emptyItemWidth: model.get('emptyItemWidth'), + totalWidth: 0, + renderList: [] + }; + + this._prepare(targetNode, layoutParam, textStyleModel); + this._renderContent(seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect); + + positionElement(thisGroup, layoutParam.pos, layoutParam.box); + }, + + /** + * Prepare render list and total width + * @private + */ + _prepare: function(targetNode, layoutParam, textStyleModel) { + for (var node = targetNode; node; node = node.parentNode) { + var text = node.getModel().get('name'); + var textRect = textStyleModel.getTextRect(text); + var itemWidth = Math.max( + textRect.width + TEXT_PADDING * 2, + layoutParam.emptyItemWidth + ); + layoutParam.totalWidth += itemWidth + ITEM_GAP; + layoutParam.renderList.push({ + node: node, + text: text, + width: itemWidth + }); + } + }, + + /** + * @private + */ + _renderContent: function( + seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect + ) { + // Start rendering. + var lastX = 0; + var emptyItemWidth = layoutParam.emptyItemWidth; + var height = seriesModel.get('breadcrumb.height'); + var availableSize = getAvailableSize(layoutParam.pos, layoutParam.box); + var totalWidth = layoutParam.totalWidth; + var renderList = layoutParam.renderList; + + for (var i = renderList.length - 1; i >= 0; i--) { + var item = renderList[i]; + var itemNode = item.node; + var itemWidth = item.width; + var text = item.text; + + // Hdie text and shorten width if necessary. + if (totalWidth > availableSize.width) { + totalWidth -= itemWidth - emptyItemWidth; + itemWidth = emptyItemWidth; + text = null; + } + + var el = new Polygon({ + shape: { + points: makeItemPoints( + lastX, 0, itemWidth, height, + i === renderList.length - 1, i === 0 + ) + }, + style: defaults( + normalStyleModel.getItemStyle(), { + lineJoin: 'bevel', + text: text, + textFill: textStyleModel.getTextColor(), + textFont: textStyleModel.getFont() + } + ), + z: 10, + onclick: curry(onSelect, itemNode) + }); + this.group.add(el); + + packEventData(el, seriesModel, itemNode); + + lastX += itemWidth + ITEM_GAP; + } + }, + + /** + * @override + */ + remove: function() { + this.group.removeAll(); + } + }; + + function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) { + var points = [ + [head ? x : x - ARRAY_LENGTH, y], + [x + itemWidth, y], + [x + itemWidth, y + itemHeight], + [head ? x : x - ARRAY_LENGTH, y + itemHeight] + ]; + !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]); + !head && points.push([x, y + itemHeight / 2]); + return points; + } + + // Package custom mouse event. + function packEventData(el, seriesModel, itemNode) { + el.eventData = { + componentType: 'series', + componentSubType: 'treemap', + seriesIndex: seriesModel.componentIndex, + seriesName: seriesModel.name, + seriesType: 'treemap', + selfType: 'breadcrumb', // Distinguish with click event on treemap node. + nodeData: { + dataIndex: itemNode && itemNode.dataIndex, + name: itemNode && itemNode.name + }, + treePathInfo: itemNode && wrapTreePathInfo(itemNode, seriesModel) + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {number} [time=500] Time in ms + * @param {string} [easing='linear'] + * @param {number} [delay=0] + * @param {Function} [callback] + * + * @example + * // Animate position + * animation + * .createWrap() + * .add(el1, {position: [10, 10]}) + * .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400) + * .done(function () { // done }) + * .start('cubicOut'); + */ + function createWrap() { + + var storage = []; + var elExistsMap = {}; + var doneCallback; + + return { + + /** + * Caution: a el can only be added once, otherwise 'done' + * might not be called. This method checks this (by el.id), + * suppresses adding and returns false when existing el found. + * + * @param {modele:zrender/Element} el + * @param {Object} target + * @param {number} [time=500] + * @param {number} [delay=0] + * @param {string} [easing='linear'] + * @return {boolean} Whether adding succeeded. + * + * @example + * add(el, target, time, delay, easing); + * add(el, target, time, easing); + * add(el, target, time); + * add(el, target); + */ + add: function(el, target, time, delay, easing) { + if (isString(delay)) { + easing = delay; + delay = 0; + } + + if (elExistsMap[el.id]) { + return false; + } + elExistsMap[el.id] = 1; + + storage.push({ + el: el, + target: target, + time: time, + delay: delay, + easing: easing + }); + + return true; + }, + + /** + * Only execute when animation finished. Will not execute when any + * of 'stop' or 'stopAnimation' called. + * + * @param {Function} callback + */ + done: function(callback) { + doneCallback = callback; + return this; + }, + + /** + * Will stop exist animation firstly. + */ + start: function() { + var count = storage.length; + + for (var i = 0, len = storage.length; i < len; i++) { + var item = storage[i]; + item.el.animateTo(item.target, item.time, item.delay, item.easing, done); + } + + return this; + + function done() { + count--; + if (!count) { + storage.length = 0; + elExistsMap = {}; + doneCallback && doneCallback(); + } + } + } + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var bind$1 = bind; + var Group$2 = Group; + var Rect$1 = Rect; + var each$8 = each$1; + + var DRAG_THRESHOLD = 3; + var PATH_LABEL_NOAMAL = ['label']; + var PATH_LABEL_EMPHASIS = ['emphasis', 'label']; + var PATH_UPPERLABEL_NORMAL = ['upperLabel']; + var PATH_UPPERLABEL_EMPHASIS = ['emphasis', 'upperLabel']; + var Z_BASE = 10; // Should bigger than every z. + var Z_BG = 1; + var Z_CONTENT = 2; + + var getItemStyleEmphasis = makeStyleMapper([ + ['fill', 'color'], + // `borderColor` and `borderWidth` has been occupied, + // so use `stroke` to indicate the stroke of the rect. + ['stroke', 'strokeColor'], + ['lineWidth', 'strokeWidth'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ]); + var getItemStyleNormal = function(model) { + // Normal style props should include emphasis style props. + var itemStyle = getItemStyleEmphasis(model); + // Clear styles set by emphasis. + itemStyle.stroke = itemStyle.fill = itemStyle.lineWidth = null; + return itemStyle; + }; + + extendChartView({ + + type: 'treemap', + + /** + * @override + */ + init: function(o, api) { + + /** + * @private + * @type {module:zrender/container/Group} + */ + this._containerGroup; + + /** + * @private + * @type {Object.>} + */ + this._storage = createStorage(); + + /** + * @private + * @type {module:echarts/data/Tree} + */ + this._oldTree; + + /** + * @private + * @type {module:echarts/chart/treemap/Breadcrumb} + */ + this._breadcrumb; + + /** + * @private + * @type {module:echarts/component/helper/RoamController} + */ + this._controller; + + /** + * 'ready', 'animating' + * @private + */ + this._state = 'ready'; + }, + + /** + * @override + */ + render: function(seriesModel, ecModel, api, payload) { + + var models = ecModel.findComponents({ + mainType: 'series', + subType: 'treemap', + query: payload + }); + if (indexOf(models, seriesModel) < 0) { + return; + } + + this.seriesModel = seriesModel; + this.api = api; + this.ecModel = ecModel; + + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, seriesModel); + var payloadType = payload && payload.type; + var layoutInfo = seriesModel.layoutInfo; + var isInit = !this._oldTree; + var thisStorage = this._storage; + + // Mark new root when action is treemapRootToNode. + var reRoot = (payloadType === 'treemapRootToNode' && targetInfo && thisStorage) ? + { + rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()], + direction: payload.direction + } : + null; + + var containerGroup = this._giveContainerGroup(layoutInfo); + + var renderResult = this._doRender(containerGroup, seriesModel, reRoot); + ( + !isInit && ( + !payloadType || + payloadType === 'treemapZoomToNode' || + payloadType === 'treemapRootToNode' + ) + ) ? + this._doAnimation(containerGroup, renderResult, seriesModel, reRoot): renderResult.renderFinally(); + + this._resetController(api); + + this._renderBreadcrumb(seriesModel, api, targetInfo); + }, + + /** + * @private + */ + _giveContainerGroup: function(layoutInfo) { + var containerGroup = this._containerGroup; + if (!containerGroup) { + // FIXME + // 加一层containerGroup是为了clip,但是现在clip功能并没有实现。 + containerGroup = this._containerGroup = new Group$2(); + this._initEvents(containerGroup); + this.group.add(containerGroup); + } + containerGroup.attr('position', [layoutInfo.x, layoutInfo.y]); + + return containerGroup; + }, + + /** + * @private + */ + _doRender: function(containerGroup, seriesModel, reRoot) { + var thisTree = seriesModel.getData().tree; + var oldTree = this._oldTree; + + // Clear last shape records. + var lastsForAnimation = createStorage(); + var thisStorage = createStorage(); + var oldStorage = this._storage; + var willInvisibleEls = []; + var doRenderNode = curry( + renderNode, seriesModel, + thisStorage, oldStorage, reRoot, + lastsForAnimation, willInvisibleEls + ); + + // Notice: when thisTree and oldTree are the same tree (see list.cloneShallow), + // the oldTree is actually losted, so we can not find all of the old graphic + // elements from tree. So we use this stragegy: make element storage, move + // from old storage to new storage, clear old storage. + + dualTravel( + thisTree.root ? [thisTree.root] : [], + (oldTree && oldTree.root) ? [oldTree.root] : [], + containerGroup, + thisTree === oldTree || !oldTree, + 0 + ); + + // Process all removing. + var willDeleteEls = clearStorage(oldStorage); + + this._oldTree = thisTree; + this._storage = thisStorage; + + return { + lastsForAnimation: lastsForAnimation, + willDeleteEls: willDeleteEls, + renderFinally: renderFinally + }; + + function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) { + // When 'render' is triggered by action, + // 'this' and 'old' may be the same tree, + // we use rawIndex in that case. + if (sameTree) { + oldViewChildren = thisViewChildren; + each$8(thisViewChildren, function(child, index) { + !child.isRemoved() && processNode(index, index); + }); + } + // Diff hierarchically (diff only in each subtree, but not whole). + // because, consistency of view is important. + else { + (new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey)) + .add(processNode) + .update(processNode) + .remove(curry(processNode, null)) + .execute(); + } + + function getKey(node) { + // Identify by name or raw index. + return node.getId(); + } + + function processNode(newIndex, oldIndex) { + var thisNode = newIndex != null ? thisViewChildren[newIndex] : null; + var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null; + + var group = doRenderNode(thisNode, oldNode, parentGroup, depth); + + group && dualTravel( + thisNode && thisNode.viewChildren || [], + oldNode && oldNode.viewChildren || [], + group, + sameTree, + depth + 1 + ); + } + } + + function clearStorage(storage) { + var willDeleteEls = createStorage(); + storage && each$8(storage, function(store, storageName) { + var delEls = willDeleteEls[storageName]; + each$8(store, function(el) { + el && (delEls.push(el), el.__tmWillDelete = 1); + }); + }); + return willDeleteEls; + } + + function renderFinally() { + each$8(willDeleteEls, function(els) { + each$8(els, function(el) { + el.parent && el.parent.remove(el); + }); + }); + each$8(willInvisibleEls, function(el) { + el.invisible = true; + // Setting invisible is for optimizing, so no need to set dirty, + // just mark as invisible. + el.dirty(); + }); + } + }, + + /** + * @private + */ + _doAnimation: function(containerGroup, renderResult, seriesModel, reRoot) { + if (!seriesModel.get('animation')) { + return; + } + + var duration = seriesModel.get('animationDurationUpdate'); + var easing = seriesModel.get('animationEasing'); + var animationWrap = createWrap(); + + // Make delete animations. + each$8(renderResult.willDeleteEls, function(store, storageName) { + each$8(store, function(el, rawIndex) { + if (el.invisible) { + return; + } + + var parent = el.parent; // Always has parent, and parent is nodeGroup. + var target; + + if (reRoot && reRoot.direction === 'drillDown') { + target = parent === reRoot.rootNodeGroup + // This is the content element of view root. + // Only `content` will enter this branch, because + // `background` and `nodeGroup` will not be deleted. + ? + { + shape: { + x: 0, + y: 0, + width: parent.__tmNodeWidth, + height: parent.__tmNodeHeight + }, + style: { + opacity: 0 + } + } + // Others. + : + { + style: { + opacity: 0 + } + }; + } else { + var targetX = 0; + var targetY = 0; + + if (!parent.__tmWillDelete) { + // Let node animate to right-bottom corner, cooperating with fadeout, + // which is appropriate for user understanding. + // Divided by 2 for reRoot rolling up effect. + targetX = parent.__tmNodeWidth / 2; + targetY = parent.__tmNodeHeight / 2; + } + + target = storageName === 'nodeGroup' ? + { + position: [targetX, targetY], + style: { + opacity: 0 + } + } : + { + shape: { + x: targetX, + y: targetY, + width: 0, + height: 0 + }, + style: { + opacity: 0 + } + }; + } + + target && animationWrap.add(el, target, duration, easing); + }); + }); + + // Make other animations + each$8(this._storage, function(store, storageName) { + each$8(store, function(el, rawIndex) { + var last = renderResult.lastsForAnimation[storageName][rawIndex]; + var target = {}; + + if (!last) { + return; + } + + if (storageName === 'nodeGroup') { + if (last.old) { + target.position = el.position.slice(); + el.attr('position', last.old); + } + } else { + if (last.old) { + target.shape = extend({}, el.shape); + el.setShape(last.old); + } + + if (last.fadein) { + el.setStyle('opacity', 0); + target.style = { + opacity: 1 + }; + } + // When animation is stopped for succedent animation starting, + // el.style.opacity might not be 1 + else if (el.style.opacity !== 1) { + target.style = { + opacity: 1 + }; + } + } + + animationWrap.add(el, target, duration, easing); + }); + }, this); + + this._state = 'animating'; + + animationWrap + .done(bind$1(function() { + this._state = 'ready'; + renderResult.renderFinally(); + }, this)) + .start(); + }, + + /** + * @private + */ + _resetController: function(api) { + var controller = this._controller; + + // Init controller. + if (!controller) { + controller = this._controller = new RoamController(api.getZr()); + controller.enable(this.seriesModel.get('roam')); + controller.on('pan', bind$1(this._onPan, this)); + controller.on('zoom', bind$1(this._onZoom, this)); + } + + var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight()); + controller.setPointerChecker(function(e, x, y) { + return rect.contain(x, y); + }); + }, + + /** + * @private + */ + _clearController: function() { + var controller = this._controller; + if (controller) { + controller.dispose(); + controller = null; + } + }, + + /** + * @private + */ + _onPan: function(dx, dy) { + if (this._state !== 'animating' && + (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD) + ) { + // These param must not be cached. + var root = this.seriesModel.getData().tree.root; + + if (!root) { + return; + } + + var rootLayout = root.getLayout(); + + if (!rootLayout) { + return; + } + + this.api.dispatchAction({ + type: 'treemapMove', + from: this.uid, + seriesId: this.seriesModel.id, + rootRect: { + x: rootLayout.x + dx, + y: rootLayout.y + dy, + width: rootLayout.width, + height: rootLayout.height + } + }); + } + }, + + /** + * @private + */ + _onZoom: function(scale, mouseX, mouseY) { + if (this._state !== 'animating') { + // These param must not be cached. + var root = this.seriesModel.getData().tree.root; + + if (!root) { + return; + } + + var rootLayout = root.getLayout(); + + if (!rootLayout) { + return; + } + + var rect = new BoundingRect( + rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height + ); + var layoutInfo = this.seriesModel.layoutInfo; + + // Transform mouse coord from global to containerGroup. + mouseX -= layoutInfo.x; + mouseY -= layoutInfo.y; + + // Scale root bounding rect. + var m = create$1(); + translate(m, m, [-mouseX, -mouseY]); + scale$1(m, m, [scale, scale]); + translate(m, m, [mouseX, mouseY]); + + rect.applyTransform(m); + + this.api.dispatchAction({ + type: 'treemapRender', + from: this.uid, + seriesId: this.seriesModel.id, + rootRect: { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + } + }); + } + }, + + /** + * @private + */ + _initEvents: function(containerGroup) { + containerGroup.on('click', function(e) { + if (this._state !== 'ready') { + return; + } + + var nodeClick = this.seriesModel.get('nodeClick', true); + + if (!nodeClick) { + return; + } + + var targetInfo = this.findTarget(e.offsetX, e.offsetY); + + if (!targetInfo) { + return; + } + + var node = targetInfo.node; + if (node.getLayout().isLeafRoot) { + this._rootToNode(targetInfo); + } else { + if (nodeClick === 'zoomToNode') { + this._zoomToNode(targetInfo); + } else if (nodeClick === 'link') { + var itemModel = node.hostTree.data.getItemModel(node.dataIndex); + var link = itemModel.get('link', true); + var linkTarget = itemModel.get('target', true) || 'blank'; + link && window.open(link, linkTarget); + } + } + + }, this); + }, + + /** + * @private + */ + _renderBreadcrumb: function(seriesModel, api, targetInfo) { + if (!targetInfo) { + targetInfo = seriesModel.get('leafDepth', true) != null ? + { + node: seriesModel.getViewRoot() + } + // FIXME + // better way? + // Find breadcrumb tail on center of containerGroup. + : + this.findTarget(api.getWidth() / 2, api.getHeight() / 2); + + if (!targetInfo) { + targetInfo = { + node: seriesModel.getData().tree.root + }; + } + } + + (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group))) + .render(seriesModel, api, targetInfo.node, bind$1(onSelect, this)); + + function onSelect(node) { + if (this._state !== 'animating') { + aboveViewRoot(seriesModel.getViewRoot(), node) ? + this._rootToNode({ + node: node + }) : + this._zoomToNode({ + node: node + }); + } + } + }, + + /** + * @override + */ + remove: function() { + this._clearController(); + this._containerGroup && this._containerGroup.removeAll(); + this._storage = createStorage(); + this._state = 'ready'; + this._breadcrumb && this._breadcrumb.remove(); + }, + + dispose: function() { + this._clearController(); + }, + + /** + * @private + */ + _zoomToNode: function(targetInfo) { + this.api.dispatchAction({ + type: 'treemapZoomToNode', + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: targetInfo.node + }); + }, + + /** + * @private + */ + _rootToNode: function(targetInfo) { + this.api.dispatchAction({ + type: 'treemapRootToNode', + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: targetInfo.node + }); + }, + + /** + * @public + * @param {number} x Global coord x. + * @param {number} y Global coord y. + * @return {Object} info If not found, return undefined; + * @return {number} info.node Target node. + * @return {number} info.offsetX x refer to target node. + * @return {number} info.offsetY y refer to target node. + */ + findTarget: function(x, y) { + var targetInfo; + var viewRoot = this.seriesModel.getViewRoot(); + + viewRoot.eachNode({ + attr: 'viewChildren', + order: 'preorder' + }, function(node) { + var bgEl = this._storage.background[node.getRawIndex()]; + // If invisible, there might be no element. + if (bgEl) { + var point = bgEl.transformCoordToLocal(x, y); + var shape = bgEl.shape; + + // For performance consideration, dont use 'getBoundingRect'. + if (shape.x <= point[0] && + point[0] <= shape.x + shape.width && + shape.y <= point[1] && + point[1] <= shape.y + shape.height + ) { + targetInfo = { + node: node, + offsetX: point[0], + offsetY: point[1] + }; + } else { + return false; // Suppress visit subtree. + } + } + }, this); + + return targetInfo; + } + + }); + + /** + * @inner + */ + function createStorage() { + return { + nodeGroup: [], + background: [], + content: [] + }; + } + + /** + * @inner + * @return Return undefined means do not travel further. + */ + function renderNode( + seriesModel, thisStorage, oldStorage, reRoot, + lastsForAnimation, willInvisibleEls, + thisNode, oldNode, parentGroup, depth + ) { + // Whether under viewRoot. + if (!thisNode) { + // Deleting nodes will be performed finally. This method just find + // element from old storage, or create new element, set them to new + // storage, and set styles. + return; + } + + // ------------------------------------------------------------------- + // Start of closure variables available in "Procedures in renderNode". + + var thisLayout = thisNode.getLayout(); + + if (!thisLayout || !thisLayout.isInView) { + return; + } + + var thisWidth = thisLayout.width; + var thisHeight = thisLayout.height; + var borderWidth = thisLayout.borderWidth; + var thisInvisible = thisLayout.invisible; + + var thisRawIndex = thisNode.getRawIndex(); + var oldRawIndex = oldNode && oldNode.getRawIndex(); + + var thisViewChildren = thisNode.viewChildren; + var upperHeight = thisLayout.upperHeight; + var isParent = thisViewChildren && thisViewChildren.length; + var itemStyleNormalModel = thisNode.getModel('itemStyle'); + var itemStyleEmphasisModel = thisNode.getModel('emphasis.itemStyle'); + + // End of closure ariables available in "Procedures in renderNode". + // ----------------------------------------------------------------- + + // Node group + var group = giveGraphic('nodeGroup', Group$2); + + if (!group) { + return; + } + + parentGroup.add(group); + // x,y are not set when el is above view root. + group.attr('position', [thisLayout.x || 0, thisLayout.y || 0]); + group.__tmNodeWidth = thisWidth; + group.__tmNodeHeight = thisHeight; + + if (thisLayout.isAboveViewRoot) { + return group; + } + + // Background + var bg = giveGraphic('background', Rect$1, depth, Z_BG); + bg && renderBackground(group, bg, isParent && thisLayout.upperHeight); + + // No children, render content. + if (!isParent) { + var content = giveGraphic('content', Rect$1, depth, Z_CONTENT); + content && renderContent(group, content); + } + + return group; + + // ---------------------------- + // | Procedures in renderNode | + // ---------------------------- + + function renderBackground(group, bg, useUpperLabel) { + // For tooltip. + bg.dataIndex = thisNode.dataIndex; + bg.seriesIndex = seriesModel.seriesIndex; + + bg.setShape({ + x: 0, + y: 0, + width: thisWidth, + height: thisHeight + }); + var visualBorderColor = thisNode.getVisual('borderColor', true); + var emphasisBorderColor = itemStyleEmphasisModel.get('borderColor'); + + updateStyle(bg, function() { + var normalStyle = getItemStyleNormal(itemStyleNormalModel); + normalStyle.fill = visualBorderColor; + var emphasisStyle = getItemStyleEmphasis(itemStyleEmphasisModel); + emphasisStyle.fill = emphasisBorderColor; + + if (useUpperLabel) { + var upperLabelWidth = thisWidth - 2 * borderWidth; + + prepareText( + normalStyle, emphasisStyle, visualBorderColor, upperLabelWidth, upperHeight, { + x: borderWidth, + y: 0, + width: upperLabelWidth, + height: upperHeight + } + ); + } + // For old bg. + else { + normalStyle.text = emphasisStyle.text = null; + } + + bg.setStyle(normalStyle); + setHoverStyle(bg, emphasisStyle); + }); + + group.add(bg); + } + + function renderContent(group, content) { + // For tooltip. + content.dataIndex = thisNode.dataIndex; + content.seriesIndex = seriesModel.seriesIndex; + + var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0); + var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0); + + content.culling = true; + content.setShape({ + x: borderWidth, + y: borderWidth, + width: contentWidth, + height: contentHeight + }); + + var visualColor = thisNode.getVisual('color', true); + updateStyle(content, function() { + var normalStyle = getItemStyleNormal(itemStyleNormalModel); + normalStyle.fill = visualColor; + var emphasisStyle = getItemStyleEmphasis(itemStyleEmphasisModel); + + prepareText(normalStyle, emphasisStyle, visualColor, contentWidth, contentHeight); + + content.setStyle(normalStyle); + setHoverStyle(content, emphasisStyle); + }); + + group.add(content); + } + + function updateStyle(element, cb) { + if (!thisInvisible) { + // If invisible, do not set visual, otherwise the element will + // change immediately before animation. We think it is OK to + // remain its origin color when moving out of the view window. + cb(); + + if (!element.__tmWillVisible) { + element.invisible = false; + } + } else { + // Delay invisible setting utill animation finished, + // avoid element vanish suddenly before animation. + !element.invisible && willInvisibleEls.push(element); + } + } + + function prepareText(normalStyle, emphasisStyle, visualColor, width, height, upperLabelRect) { + var nodeModel = thisNode.getModel(); + var text = retrieve( + seriesModel.getFormattedLabel( + thisNode.dataIndex, 'normal', null, null, upperLabelRect ? 'upperLabel' : 'label' + ), + nodeModel.get('name') + ); + if (!upperLabelRect && thisLayout.isLeafRoot) { + var iconChar = seriesModel.get('drillDownIcon', true); + text = iconChar ? iconChar + ' ' + text : text; + } + + var normalLabelModel = nodeModel.getModel( + upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL + ); + var emphasisLabelModel = nodeModel.getModel( + upperLabelRect ? PATH_UPPERLABEL_EMPHASIS : PATH_LABEL_EMPHASIS + ); + + var isShow = normalLabelModel.getShallow('show'); + + setLabelStyle( + normalStyle, emphasisStyle, normalLabelModel, emphasisLabelModel, { + defaultText: isShow ? text : null, + autoColor: visualColor, + isRectText: true + } + ); + + upperLabelRect && (normalStyle.textRect = clone(upperLabelRect)); + + normalStyle.truncate = (isShow && normalLabelModel.get('ellipsis')) ? + { + outerWidth: width, + outerHeight: height, + minChar: 2 + } : + null; + } + + function giveGraphic(storageName, Ctor, depth, z) { + var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex]; + var lasts = lastsForAnimation[storageName]; + + if (element) { + // Remove from oldStorage + oldStorage[storageName][oldRawIndex] = null; + prepareAnimationWhenHasOld(lasts, element, storageName); + } + // If invisible and no old element, do not create new element (for optimizing). + else if (!thisInvisible) { + element = new Ctor({ + z: calculateZ(depth, z) + }); + element.__tmDepth = depth; + element.__tmStorageName = storageName; + prepareAnimationWhenNoOld(lasts, element, storageName); + } + + // Set to thisStorage + return (thisStorage[storageName][thisRawIndex] = element); + } + + function prepareAnimationWhenHasOld(lasts, element, storageName) { + var lastCfg = lasts[thisRawIndex] = {}; + lastCfg.old = storageName === 'nodeGroup' ? + element.position.slice() : + extend({}, element.shape); + } + + // If a element is new, we need to find the animation start point carefully, + // otherwise it will looks strange when 'zoomToNode'. + function prepareAnimationWhenNoOld(lasts, element, storageName) { + var lastCfg = lasts[thisRawIndex] = {}; + var parentNode = thisNode.parentNode; + + if (parentNode && (!reRoot || reRoot.direction === 'drillDown')) { + var parentOldX = 0; + var parentOldY = 0; + + // New nodes appear from right-bottom corner in 'zoomToNode' animation. + // For convenience, get old bounding rect from background. + var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()]; + if (!reRoot && parentOldBg && parentOldBg.old) { + parentOldX = parentOldBg.old.width; + parentOldY = parentOldBg.old.height; + } + + // When no parent old shape found, its parent is new too, + // so we can just use {x:0, y:0}. + lastCfg.old = storageName === 'nodeGroup' ? + [0, parentOldY] : + { + x: parentOldX, + y: parentOldY, + width: 0, + height: 0 + }; + } + + // Fade in, user can be aware that these nodes are new. + lastCfg.fadein = storageName !== 'nodeGroup'; + } + } + + // We can not set all backgroud with the same z, Because the behaviour of + // drill down and roll up differ background creation sequence from tree + // hierarchy sequence, which cause that lowser background element overlap + // upper ones. So we calculate z based on depth. + // Moreover, we try to shrink down z interval to [0, 1] to avoid that + // treemap with large z overlaps other components. + function calculateZ(depth, zInLevel) { + var zb = depth * Z_BASE + zInLevel; + return (zb - 1) / zb; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Treemap action + */ + + var noop$1 = function() {}; + + var actionTypes = [ + 'treemapZoomToNode', + 'treemapRender', + 'treemapMove' + ]; + + for (var i$2 = 0; i$2 < actionTypes.length; i$2++) { + registerAction({ + type: actionTypes[i$2], + update: 'updateView' + }, noop$1); + } + + registerAction({ + type: 'treemapRootToNode', + update: 'updateView' + }, + function(payload, ecModel) { + + ecModel.eachComponent({ + mainType: 'series', + subType: 'treemap', + query: payload + }, + handleRootToNode + ); + + function handleRootToNode(model, index) { + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, model); + + if (targetInfo) { + var originViewRoot = model.getViewRoot(); + if (originViewRoot) { + payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? + 'rollUp' : 'drillDown'; + } + model.resetViewRoot(targetInfo.node); + } + } + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$9 = each$1; + var isObject$5 = isObject$1; + + var CATEGORY_DEFAULT_VISUAL_INDEX = -1; + + /** + * @param {Object} option + * @param {string} [option.type] See visualHandlers. + * @param {string} [option.mappingMethod] 'linear' or 'piecewise' or 'category' or 'fixed' + * @param {Array.=} [option.dataExtent] [minExtent, maxExtent], + * required when mappingMethod is 'linear' + * @param {Array.=} [option.pieceList] [ + * {value: someValue}, + * {interval: [min1, max1], visual: {...}}, + * {interval: [min2, max2]} + * ], + * required when mappingMethod is 'piecewise'. + * Visual for only each piece can be specified. + * @param {Array.=} [option.categories] ['cate1', 'cate2'] + * required when mappingMethod is 'category'. + * If no option.categories, categories is set + * as [0, 1, 2, ...]. + * @param {boolean} [option.loop=false] Whether loop mapping when mappingMethod is 'category'. + * @param {(Array|Object|*)} [option.visual] Visual data. + * when mappingMethod is 'category', + * visual data can be array or object + * (like: {cate1: '#222', none: '#fff'}) + * or primary types (which represents + * defualt category visual), otherwise visual + * can be array or primary (which will be + * normalized to array). + * + */ + var VisualMapping = function(option) { + var mappingMethod = option.mappingMethod; + var visualType = option.type; + + /** + * @readOnly + * @type {Object} + */ + var thisOption = this.option = clone(option); + + /** + * @readOnly + * @type {string} + */ + this.type = visualType; + + /** + * @readOnly + * @type {string} + */ + this.mappingMethod = mappingMethod; + + /** + * @private + * @type {Function} + */ + this._normalizeData = normalizers[mappingMethod]; + + var visualHandler = visualHandlers[visualType]; + + /** + * @public + * @type {Function} + */ + this.applyVisual = visualHandler.applyVisual; + + /** + * @public + * @type {Function} + */ + this.getColorMapper = visualHandler.getColorMapper; + + /** + * @private + * @type {Function} + */ + this._doMap = visualHandler._doMap[mappingMethod]; + + if (mappingMethod === 'piecewise') { + normalizeVisualRange(thisOption); + preprocessForPiecewise(thisOption); + } else if (mappingMethod === 'category') { + thisOption.categories ? + preprocessForSpecifiedCategory(thisOption) + // categories is ordinal when thisOption.categories not specified, + // which need no more preprocess except normalize visual. + : + normalizeVisualRange(thisOption, true); + } else { // mappingMethod === 'linear' or 'fixed' + assert$1(mappingMethod !== 'linear' || thisOption.dataExtent); + normalizeVisualRange(thisOption); + } + }; + + VisualMapping.prototype = { + + constructor: VisualMapping, + + mapValueToVisual: function(value) { + var normalized = this._normalizeData(value); + return this._doMap(normalized, value); + }, + + getNormalizer: function() { + return bind(this._normalizeData, this); + } + }; + + var visualHandlers = VisualMapping.visualHandlers = { + + color: { + + applyVisual: makeApplyVisual('color'), + + /** + * Create a mapper function + * @return {Function} + */ + getColorMapper: function() { + var thisOption = this.option; + + return bind( + thisOption.mappingMethod === 'category' ? + function(value, isNormalized) { + !isNormalized && (value = this._normalizeData(value)); + return doMapCategory.call(this, value); + } : + function(value, isNormalized, out) { + // If output rgb array + // which will be much faster and useful in pixel manipulation + var returnRGBArray = !!out; + !isNormalized && (value = this._normalizeData(value)); + out = fastLerp(value, thisOption.parsedVisual, out); + return returnRGBArray ? out : stringify(out, 'rgba'); + }, + this + ); + }, + + _doMap: { + linear: function(normalized) { + return stringify( + fastLerp(normalized, this.option.parsedVisual), + 'rgba' + ); + }, + category: doMapCategory, + piecewise: function(normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = stringify( + fastLerp(normalized, this.option.parsedVisual), + 'rgba' + ); + } + return result; + }, + fixed: doMapFixed + } + }, + + colorHue: makePartialColorVisualHandler(function(color, value) { + return modifyHSL(color, value); + }), + + colorSaturation: makePartialColorVisualHandler(function(color, value) { + return modifyHSL(color, null, value); + }), + + colorLightness: makePartialColorVisualHandler(function(color, value) { + return modifyHSL(color, null, null, value); + }), + + colorAlpha: makePartialColorVisualHandler(function(color, value) { + return modifyAlpha(color, value); + }), + + opacity: { + applyVisual: makeApplyVisual('opacity'), + _doMap: makeDoMap([0, 1]) + }, + + liftZ: { + applyVisual: makeApplyVisual('liftZ'), + _doMap: { + linear: doMapFixed, + category: doMapFixed, + piecewise: doMapFixed, + fixed: doMapFixed + } + }, + + symbol: { + applyVisual: function(value, getter, setter) { + var symbolCfg = this.mapValueToVisual(value); + if (isString(symbolCfg)) { + setter('symbol', symbolCfg); + } else if (isObject$5(symbolCfg)) { + for (var name in symbolCfg) { + if (symbolCfg.hasOwnProperty(name)) { + setter(name, symbolCfg[name]); + } + } + } + }, + _doMap: { + linear: doMapToArray, + category: doMapCategory, + piecewise: function(normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = doMapToArray.call(this, normalized); + } + return result; + }, + fixed: doMapFixed + } + }, + + symbolSize: { + applyVisual: makeApplyVisual('symbolSize'), + _doMap: makeDoMap([0, 1]) + } + }; + + + function preprocessForPiecewise(thisOption) { + var pieceList = thisOption.pieceList; + thisOption.hasSpecialVisual = false; + + each$1(pieceList, function(piece, index) { + piece.originIndex = index; + // piece.visual is "result visual value" but not + // a visual range, so it does not need to be normalized. + if (piece.visual != null) { + thisOption.hasSpecialVisual = true; + } + }); + } + + function preprocessForSpecifiedCategory(thisOption) { + // Hash categories. + var categories = thisOption.categories; + var visual = thisOption.visual; + + var categoryMap = thisOption.categoryMap = {}; + each$9(categories, function(cate, index) { + categoryMap[cate] = index; + }); + + // Process visual map input. + if (!isArray(visual)) { + var visualArr = []; + + if (isObject$1(visual)) { + each$9(visual, function(v, cate) { + var index = categoryMap[cate]; + visualArr[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v; + }); + } else { // Is primary type, represents default visual. + visualArr[CATEGORY_DEFAULT_VISUAL_INDEX] = visual; + } + + visual = setVisualToOption(thisOption, visualArr); + } + + // Remove categories that has no visual, + // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX. + for (var i = categories.length - 1; i >= 0; i--) { + if (visual[i] == null) { + delete categoryMap[categories[i]]; + categories.pop(); + } + } + } + + function normalizeVisualRange(thisOption, isCategory) { + var visual = thisOption.visual; + var visualArr = []; + + if (isObject$1(visual)) { + each$9(visual, function(v) { + visualArr.push(v); + }); + } else if (visual != null) { + visualArr.push(visual); + } + + var doNotNeedPair = { + color: 1, + symbol: 1 + }; + + if (!isCategory && + visualArr.length === 1 && + !doNotNeedPair.hasOwnProperty(thisOption.type) + ) { + // Do not care visualArr.length === 0, which is illegal. + visualArr[1] = visualArr[0]; + } + + setVisualToOption(thisOption, visualArr); + } + + function makePartialColorVisualHandler(applyValue) { + return { + applyVisual: function(value, getter, setter) { + value = this.mapValueToVisual(value); + // Must not be array value + setter('color', applyValue(getter('color'), value)); + }, + _doMap: makeDoMap([0, 1]) + }; + } + + function doMapToArray(normalized) { + var visual = this.option.visual; + return visual[ + Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true)) + ] || {}; + } + + function makeApplyVisual(visualType) { + return function(value, getter, setter) { + setter(visualType, this.mapValueToVisual(value)); + }; + } + + function doMapCategory(normalized) { + var visual = this.option.visual; + return visual[ + (this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX) ? + normalized % visual.length : + normalized + ]; + } + + function doMapFixed() { + return this.option.visual[0]; + } + + function makeDoMap(sourceExtent) { + return { + linear: function(normalized) { + return linearMap(normalized, sourceExtent, this.option.visual, true); + }, + category: doMapCategory, + piecewise: function(normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = linearMap(normalized, sourceExtent, this.option.visual, true); + } + return result; + }, + fixed: doMapFixed + }; + } + + function getSpecifiedVisual(value) { + var thisOption = this.option; + var pieceList = thisOption.pieceList; + if (thisOption.hasSpecialVisual) { + var pieceIndex = VisualMapping.findPieceIndex(value, pieceList); + var piece = pieceList[pieceIndex]; + if (piece && piece.visual) { + return piece.visual[this.type]; + } + } + } + + function setVisualToOption(thisOption, visualArr) { + thisOption.visual = visualArr; + if (thisOption.type === 'color') { + thisOption.parsedVisual = map(visualArr, function(item) { + return parse(item); + }); + } + return visualArr; + } + + + /** + * Normalizers by mapping methods. + */ + var normalizers = { + + linear: function(value) { + return linearMap(value, this.option.dataExtent, [0, 1], true); + }, + + piecewise: function(value) { + var pieceList = this.option.pieceList; + var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true); + if (pieceIndex != null) { + return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true); + } + }, + + category: function(value) { + var index = this.option.categories ? + this.option.categoryMap[value] : + value; // ordinal + return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index; + }, + + fixed: noop + }; + + + + /** + * List available visual types. + * + * @public + * @return {Array.} + */ + VisualMapping.listVisualTypes = function() { + var visualTypes = []; + each$1(visualHandlers, function(handler, key) { + visualTypes.push(key); + }); + return visualTypes; + }; + + /** + * @public + */ + VisualMapping.addVisualHandler = function(name, handler) { + visualHandlers[name] = handler; + }; + + /** + * @public + */ + VisualMapping.isValidType = function(visualType) { + return visualHandlers.hasOwnProperty(visualType); + }; + + /** + * Convinent method. + * Visual can be Object or Array or primary type. + * + * @public + */ + VisualMapping.eachVisual = function(visual, callback, context) { + if (isObject$1(visual)) { + each$1(visual, callback, context); + } else { + callback.call(context, visual); + } + }; + + VisualMapping.mapVisual = function(visual, callback, context) { + var isPrimary; + var newVisual = isArray(visual) ? + [] : + isObject$1(visual) ? + {} : + (isPrimary = true, null); + + VisualMapping.eachVisual(visual, function(v, key) { + var newVal = callback.call(context, v, key); + isPrimary ? (newVisual = newVal) : (newVisual[key] = newVal); + }); + return newVisual; + }; + + /** + * @public + * @param {Object} obj + * @return {Object} new object containers visual values. + * If no visuals, return null. + */ + VisualMapping.retrieveVisuals = function(obj) { + var ret = {}; + var hasVisual; + + obj && each$9(visualHandlers, function(h, visualType) { + if (obj.hasOwnProperty(visualType)) { + ret[visualType] = obj[visualType]; + hasVisual = true; + } + }); + + return hasVisual ? ret : null; + }; + + /** + * Give order to visual types, considering colorSaturation, colorAlpha depends on color. + * + * @public + * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...} + * IF Array, like: ['color', 'symbol', 'colorSaturation'] + * @return {Array.} Sorted visual types. + */ + VisualMapping.prepareVisualTypes = function(visualTypes) { + if (isObject$5(visualTypes)) { + var types = []; + each$9(visualTypes, function(item, type) { + types.push(type); + }); + visualTypes = types; + } else if (isArray(visualTypes)) { + visualTypes = visualTypes.slice(); + } else { + return []; + } + + visualTypes.sort(function(type1, type2) { + // color should be front of colorSaturation, colorAlpha, ... + // symbol and symbolSize do not matter. + return (type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0) ? + 1 : -1; + }); + + return visualTypes; + }; + + /** + * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'. + * Other visuals are only depends on themself. + * + * @public + * @param {string} visualType1 + * @param {string} visualType2 + * @return {boolean} + */ + VisualMapping.dependsOn = function(visualType1, visualType2) { + return visualType2 === 'color' ? + !!(visualType1 && visualType1.indexOf(visualType2) === 0) : + visualType1 === visualType2; + }; + + /** + * @param {number} value + * @param {Array.} pieceList [{value: ..., interval: [min, max]}, ...] + * Always from small to big. + * @param {boolean} [findClosestWhenOutside=false] + * @return {number} index + */ + VisualMapping.findPieceIndex = function(value, pieceList, findClosestWhenOutside) { + var possibleI; + var abs = Infinity; + + // value has the higher priority. + for (var i = 0, len = pieceList.length; i < len; i++) { + var pieceValue = pieceList[i].value; + if (pieceValue != null) { + if (pieceValue === value + // FIXME + // It is supposed to compare value according to value type of dimension, + // but currently value type can exactly be string or number. + // Compromise for numeric-like string (like '12'), especially + // in the case that visualMap.categories is ['22', '33']. + || + (typeof pieceValue === 'string' && pieceValue === value + '') + ) { + return i; + } + findClosestWhenOutside && updatePossible(pieceValue, i); + } + } + + for (var i = 0, len = pieceList.length; i < len; i++) { + var piece = pieceList[i]; + var interval = piece.interval; + var close = piece.close; + + if (interval) { + if (interval[0] === -Infinity) { + if (littleThan(close[1], value, interval[1])) { + return i; + } + } else if (interval[1] === Infinity) { + if (littleThan(close[0], interval[0], value)) { + return i; + } + } else if ( + littleThan(close[0], interval[0], value) && + littleThan(close[1], value, interval[1]) + ) { + return i; + } + findClosestWhenOutside && updatePossible(interval[0], i); + findClosestWhenOutside && updatePossible(interval[1], i); + } + } + + if (findClosestWhenOutside) { + return value === Infinity ? + pieceList.length - 1 : + value === -Infinity ? + 0 : + possibleI; + } + + function updatePossible(val, index) { + var newAbs = Math.abs(val - value); + if (newAbs < abs) { + abs = newAbs; + possibleI = index; + } + } + + }; + + function littleThan(close, a, b) { + return close ? a <= b : a < b; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var isArray$2 = isArray; + + var ITEM_STYLE_NORMAL = 'itemStyle'; + + var treemapVisual = { + seriesType: 'treemap', + reset: function(seriesModel, ecModel, api, payload) { + var tree = seriesModel.getData().tree; + var root = tree.root; + var seriesItemStyleModel = seriesModel.getModel(ITEM_STYLE_NORMAL); + + if (root.isRemoved()) { + return; + } + + var levelItemStyles = map(tree.levelModels, function(levelModel) { + return levelModel ? levelModel.get(ITEM_STYLE_NORMAL) : null; + }); + + travelTree( + root, // Visual should calculate from tree root but not view root. + {}, + levelItemStyles, + seriesItemStyleModel, + seriesModel.getViewRoot().getAncestors(), + seriesModel + ); + } + }; + + function travelTree( + node, designatedVisual, levelItemStyles, seriesItemStyleModel, + viewRootAncestors, seriesModel + ) { + var nodeModel = node.getModel(); + var nodeLayout = node.getLayout(); + + // Optimize + if (!nodeLayout || nodeLayout.invisible || !nodeLayout.isInView) { + return; + } + + var nodeItemStyleModel = node.getModel(ITEM_STYLE_NORMAL); + var levelItemStyle = levelItemStyles[node.depth]; + var visuals = buildVisuals( + nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel + ); + + // calculate border color + var borderColor = nodeItemStyleModel.get('borderColor'); + var borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation'); + var thisNodeColor; + if (borderColorSaturation != null) { + // For performance, do not always execute 'calculateColor'. + thisNodeColor = calculateColor(visuals, node); + borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor); + } + node.setVisual('borderColor', borderColor); + + var viewChildren = node.viewChildren; + if (!viewChildren || !viewChildren.length) { + thisNodeColor = calculateColor(visuals, node); + // Apply visual to this node. + node.setVisual('color', thisNodeColor); + } else { + var mapping = buildVisualMapping( + node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren + ); + + // Designate visual to children. + each$1(viewChildren, function(child, index) { + // If higher than viewRoot, only ancestors of viewRoot is needed to visit. + if (child.depth >= viewRootAncestors.length || + child === viewRootAncestors[child.depth] + ) { + var childVisual = mapVisual$1( + nodeModel, visuals, child, index, mapping, seriesModel + ); + travelTree( + child, childVisual, levelItemStyles, seriesItemStyleModel, + viewRootAncestors, seriesModel + ); + } + }); + } + } + + function buildVisuals( + nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel + ) { + var visuals = extend({}, designatedVisual); + + each$1(['color', 'colorAlpha', 'colorSaturation'], function(visualName) { + // Priority: thisNode > thisLevel > parentNodeDesignated > seriesModel + var val = nodeItemStyleModel.get(visualName, true); // Ignore parent + val == null && levelItemStyle && (val = levelItemStyle[visualName]); + val == null && (val = designatedVisual[visualName]); + val == null && (val = seriesItemStyleModel.get(visualName)); + + val != null && (visuals[visualName] = val); + }); + + return visuals; + } + + function calculateColor(visuals) { + var color = getValueVisualDefine(visuals, 'color'); + + if (color) { + var colorAlpha = getValueVisualDefine(visuals, 'colorAlpha'); + var colorSaturation = getValueVisualDefine(visuals, 'colorSaturation'); + if (colorSaturation) { + color = modifyHSL(color, null, null, colorSaturation); + } + if (colorAlpha) { + color = modifyAlpha(color, colorAlpha); + } + + return color; + } + } + + function calculateBorderColor(borderColorSaturation, thisNodeColor) { + return thisNodeColor != null ? + modifyHSL(thisNodeColor, null, null, borderColorSaturation) : + null; + } + + function getValueVisualDefine(visuals, name) { + var value = visuals[name]; + if (value != null && value !== 'none') { + return value; + } + } + + function buildVisualMapping( + node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren + ) { + if (!viewChildren || !viewChildren.length) { + return; + } + + var rangeVisual = getRangeVisual(nodeModel, 'color') || + ( + visuals.color != null && + visuals.color !== 'none' && + ( + getRangeVisual(nodeModel, 'colorAlpha') || + getRangeVisual(nodeModel, 'colorSaturation') + ) + ); + + if (!rangeVisual) { + return; + } + + var visualMin = nodeModel.get('visualMin'); + var visualMax = nodeModel.get('visualMax'); + var dataExtent = nodeLayout.dataExtent.slice(); + visualMin != null && visualMin < dataExtent[0] && (dataExtent[0] = visualMin); + visualMax != null && visualMax > dataExtent[1] && (dataExtent[1] = visualMax); + + var colorMappingBy = nodeModel.get('colorMappingBy'); + var opt = { + type: rangeVisual.name, + dataExtent: dataExtent, + visual: rangeVisual.range + }; + if (opt.type === 'color' && + (colorMappingBy === 'index' || colorMappingBy === 'id') + ) { + opt.mappingMethod = 'category'; + opt.loop = true; + // categories is ordinal, so do not set opt.categories. + } else { + opt.mappingMethod = 'linear'; + } + + var mapping = new VisualMapping(opt); + mapping.__drColorMappingBy = colorMappingBy; + + return mapping; + } + + // Notice: If we dont have the attribute 'colorRange', but only use + // attribute 'color' to represent both concepts of 'colorRange' and 'color', + // (It means 'colorRange' when 'color' is Array, means 'color' when not array), + // this problem will be encountered: + // If a level-1 node dont have children, and its siblings has children, + // and colorRange is set on level-1, then the node can not be colored. + // So we separate 'colorRange' and 'color' to different attributes. + function getRangeVisual(nodeModel, name) { + // 'colorRange', 'colorARange', 'colorSRange'. + // If not exsits on this node, fetch from levels and series. + var range = nodeModel.get(name); + return (isArray$2(range) && range.length) ? { + name: name, + range: range + } : null; + } + + function mapVisual$1(nodeModel, visuals, child, index, mapping, seriesModel) { + var childVisuals = extend({}, visuals); + + if (mapping) { + var mappingType = mapping.type; + var colorMappingBy = mappingType === 'color' && mapping.__drColorMappingBy; + var value = + colorMappingBy === 'index' ? + index : + colorMappingBy === 'id' ? + seriesModel.mapIdToIndex(child.getId()) : + child.getValue(nodeModel.get('visualDimension')); + + childVisuals[mappingType] = mapping.mapValueToVisual(value); + } + + return childVisuals; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * The treemap layout implementation references to the treemap + * layout of d3.js (d3/src/layout/treemap.js in v3). The use of + * the source code of this file is also subject to the terms + * and consitions of its license (BSD-3Clause, see + * ). + */ + + var mathMax$4 = Math.max; + var mathMin$4 = Math.min; + var retrieveValue = retrieve; + var each$10 = each$1; + + var PATH_BORDER_WIDTH = ['itemStyle', 'borderWidth']; + var PATH_GAP_WIDTH = ['itemStyle', 'gapWidth']; + var PATH_UPPER_LABEL_SHOW = ['upperLabel', 'show']; + var PATH_UPPER_LABEL_HEIGHT = ['upperLabel', 'height']; + + /** + * @public + */ + var treemapLayout = { + seriesType: 'treemap', + reset: function(seriesModel, ecModel, api, payload) { + // Layout result in each node: + // {x, y, width, height, area, borderWidth} + var ecWidth = api.getWidth(); + var ecHeight = api.getHeight(); + var seriesOption = seriesModel.option; + + var layoutInfo = getLayoutRect( + seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + + var size = seriesOption.size || []; // Compatible with ec2. + var containerWidth = parsePercent$1( + retrieveValue(layoutInfo.width, size[0]), + ecWidth + ); + var containerHeight = parsePercent$1( + retrieveValue(layoutInfo.height, size[1]), + ecHeight + ); + + // Fetch payload info. + var payloadType = payload && payload.type; + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, seriesModel); + var rootRect = (payloadType === 'treemapRender' || payloadType === 'treemapMove') ? + payload.rootRect : null; + var viewRoot = seriesModel.getViewRoot(); + var viewAbovePath = getPathToRoot(viewRoot); + + if (payloadType !== 'treemapMove') { + var rootSize = payloadType === 'treemapZoomToNode' ? + estimateRootSize( + seriesModel, targetInfo, viewRoot, containerWidth, containerHeight + ) : + rootRect ? + [rootRect.width, rootRect.height] : + [containerWidth, containerHeight]; + + var sort = seriesOption.sort; + if (sort && sort !== 'asc' && sort !== 'desc') { + sort = 'desc'; + } + var options = { + squareRatio: seriesOption.squareRatio, + sort: sort, + leafDepth: seriesOption.leafDepth + }; + + // layout should be cleared because using updateView but not update. + viewRoot.hostTree.clearLayouts(); + + // TODO + // optimize: if out of view clip, do not layout. + // But take care that if do not render node out of view clip, + // how to calculate start po + + var viewRootLayout = { + x: 0, + y: 0, + width: rootSize[0], + height: rootSize[1], + area: rootSize[0] * rootSize[1] + }; + viewRoot.setLayout(viewRootLayout); + + squarify(viewRoot, options, false, 0); + // Supplement layout. + var viewRootLayout = viewRoot.getLayout(); + each$10(viewAbovePath, function(node, index) { + var childValue = (viewAbovePath[index + 1] || viewRoot).getValue(); + node.setLayout(extend({ + dataExtent: [childValue, childValue], + borderWidth: 0, + upperHeight: 0 + }, + viewRootLayout + )); + }); + } + + var treeRoot = seriesModel.getData().tree.root; + + treeRoot.setLayout( + calculateRootPosition(layoutInfo, rootRect, targetInfo), + true + ); + + seriesModel.setLayoutInfo(layoutInfo); + + // FIXME + // 现在没有clip功能,暂时取ec高宽。 + prunning( + treeRoot, + // Transform to base element coordinate system. + new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight), + viewAbovePath, + viewRoot, + 0 + ); + } + }; + + /** + * Layout treemap with squarify algorithm. + * @see https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf + * The implementation references to the treemap layout of d3.js. + * See the license statement at the head of this file. + * + * @protected + * @param {module:echarts/data/Tree~TreeNode} node + * @param {Object} options + * @param {string} options.sort 'asc' or 'desc' + * @param {number} options.squareRatio + * @param {boolean} hideChildren + * @param {number} depth + */ + function squarify(node, options, hideChildren, depth) { + var width; + var height; + + if (node.isRemoved()) { + return; + } + + var thisLayout = node.getLayout(); + width = thisLayout.width; + height = thisLayout.height; + + // Considering border and gap + var nodeModel = node.getModel(); + var borderWidth = nodeModel.get(PATH_BORDER_WIDTH); + var halfGapWidth = nodeModel.get(PATH_GAP_WIDTH) / 2; + var upperLabelHeight = getUpperLabelHeight(nodeModel); + var upperHeight = Math.max(borderWidth, upperLabelHeight); + var layoutOffset = borderWidth - halfGapWidth; + var layoutOffsetUpper = upperHeight - halfGapWidth; + var nodeModel = node.getModel(); + + node.setLayout({ + borderWidth: borderWidth, + upperHeight: upperHeight, + upperLabelHeight: upperLabelHeight + }, true); + + width = mathMax$4(width - 2 * layoutOffset, 0); + height = mathMax$4(height - layoutOffset - layoutOffsetUpper, 0); + + var totalArea = width * height; + var viewChildren = initChildren( + node, nodeModel, totalArea, options, hideChildren, depth + ); + + if (!viewChildren.length) { + return; + } + + var rect = { + x: layoutOffset, + y: layoutOffsetUpper, + width: width, + height: height + }; + var rowFixedLength = mathMin$4(width, height); + var best = Infinity; // the best row score so far + var row = []; + row.area = 0; + + for (var i = 0, len = viewChildren.length; i < len;) { + var child = viewChildren[i]; + + row.push(child); + row.area += child.getLayout().area; + var score = worst(row, rowFixedLength, options.squareRatio); + + // continue with this orientation + if (score <= best) { + i++; + best = score; + } + // abort, and try a different orientation + else { + row.area -= row.pop().getLayout().area; + position(row, rowFixedLength, rect, halfGapWidth, false); + rowFixedLength = mathMin$4(rect.width, rect.height); + row.length = row.area = 0; + best = Infinity; + } + } + + if (row.length) { + position(row, rowFixedLength, rect, halfGapWidth, true); + } + + if (!hideChildren) { + var childrenVisibleMin = nodeModel.get('childrenVisibleMin'); + if (childrenVisibleMin != null && totalArea < childrenVisibleMin) { + hideChildren = true; + } + } + + for (var i = 0, len = viewChildren.length; i < len; i++) { + squarify(viewChildren[i], options, hideChildren, depth + 1); + } + } + + /** + * Set area to each child, and calculate data extent for visual coding. + */ + function initChildren(node, nodeModel, totalArea, options, hideChildren, depth) { + var viewChildren = node.children || []; + var orderBy = options.sort; + orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null); + + var overLeafDepth = options.leafDepth != null && options.leafDepth <= depth; + + // leafDepth has higher priority. + if (hideChildren && !overLeafDepth) { + return (node.viewChildren = []); + } + + // Sort children, order by desc. + viewChildren = filter(viewChildren, function(child) { + return !child.isRemoved(); + }); + + sort$1(viewChildren, orderBy); + + var info = statistic(nodeModel, viewChildren, orderBy); + + if (info.sum === 0) { + return (node.viewChildren = []); + } + + info.sum = filterByThreshold(nodeModel, totalArea, info.sum, orderBy, viewChildren); + + if (info.sum === 0) { + return (node.viewChildren = []); + } + + // Set area to each child. + for (var i = 0, len = viewChildren.length; i < len; i++) { + var area = viewChildren[i].getValue() / info.sum * totalArea; + // Do not use setLayout({...}, true), because it is needed to clear last layout. + viewChildren[i].setLayout({ + area: area + }); + } + + if (overLeafDepth) { + viewChildren.length && node.setLayout({ + isLeafRoot: true + }, true); + viewChildren.length = 0; + } + + node.viewChildren = viewChildren; + node.setLayout({ + dataExtent: info.dataExtent + }, true); + + return viewChildren; + } + + /** + * Consider 'visibleMin'. Modify viewChildren and get new sum. + */ + function filterByThreshold(nodeModel, totalArea, sum, orderBy, orderedChildren) { + + // visibleMin is not supported yet when no option.sort. + if (!orderBy) { + return sum; + } + + var visibleMin = nodeModel.get('visibleMin'); + var len = orderedChildren.length; + var deletePoint = len; + + // Always travel from little value to big value. + for (var i = len - 1; i >= 0; i--) { + var value = orderedChildren[ + orderBy === 'asc' ? len - i - 1 : i + ].getValue(); + + if (value / sum * totalArea < visibleMin) { + deletePoint = i; + sum -= value; + } + } + + orderBy === 'asc' ? + orderedChildren.splice(0, len - deletePoint) : + orderedChildren.splice(deletePoint, len - deletePoint); + + return sum; + } + + /** + * Sort + */ + function sort$1(viewChildren, orderBy) { + if (orderBy) { + viewChildren.sort(function(a, b) { + var diff = orderBy === 'asc' ? + a.getValue() - b.getValue() : b.getValue() - a.getValue(); + return diff === 0 ? + (orderBy === 'asc' ? + a.dataIndex - b.dataIndex : b.dataIndex - a.dataIndex + ) : + diff; + }); + } + return viewChildren; + } + + /** + * Statistic + */ + function statistic(nodeModel, children, orderBy) { + // Calculate sum. + var sum = 0; + for (var i = 0, len = children.length; i < len; i++) { + sum += children[i].getValue(); + } + + // Statistic data extent for latter visual coding. + // Notice: data extent should be calculate based on raw children + // but not filtered view children, otherwise visual mapping will not + // be stable when zoom (where children is filtered by visibleMin). + + var dimension = nodeModel.get('visualDimension'); + var dataExtent; + + // The same as area dimension. + if (!children || !children.length) { + dataExtent = [NaN, NaN]; + } else if (dimension === 'value' && orderBy) { + dataExtent = [ + children[children.length - 1].getValue(), + children[0].getValue() + ]; + orderBy === 'asc' && dataExtent.reverse(); + } + // Other dimension. + else { + var dataExtent = [Infinity, -Infinity]; + each$10(children, function(child) { + var value = child.getValue(dimension); + value < dataExtent[0] && (dataExtent[0] = value); + value > dataExtent[1] && (dataExtent[1] = value); + }); + } + + return { + sum: sum, + dataExtent: dataExtent + }; + } + + /** + * Computes the score for the specified row, + * as the worst aspect ratio. + */ + function worst(row, rowFixedLength, ratio) { + var areaMax = 0; + var areaMin = Infinity; + + for (var i = 0, area, len = row.length; i < len; i++) { + area = row[i].getLayout().area; + if (area) { + area < areaMin && (areaMin = area); + area > areaMax && (areaMax = area); + } + } + + var squareArea = row.area * row.area; + var f = rowFixedLength * rowFixedLength * ratio; + + return squareArea ? + mathMax$4( + (f * areaMax) / squareArea, + squareArea / (f * areaMin) + ) : + Infinity; + } + + /** + * Positions the specified row of nodes. Modifies `rect`. + */ + function position(row, rowFixedLength, rect, halfGapWidth, flush) { + // When rowFixedLength === rect.width, + // it is horizontal subdivision, + // rowFixedLength is the width of the subdivision, + // rowOtherLength is the height of the subdivision, + // and nodes will be positioned from left to right. + + // wh[idx0WhenH] means: when horizontal, + // wh[idx0WhenH] => wh[0] => 'width'. + // xy[idx1WhenH] => xy[1] => 'y'. + var idx0WhenH = rowFixedLength === rect.width ? 0 : 1; + var idx1WhenH = 1 - idx0WhenH; + var xy = ['x', 'y']; + var wh = ['width', 'height']; + + var last = rect[xy[idx0WhenH]]; + var rowOtherLength = rowFixedLength ? + row.area / rowFixedLength : 0; + + if (flush || rowOtherLength > rect[wh[idx1WhenH]]) { + rowOtherLength = rect[wh[idx1WhenH]]; // over+underflow + } + for (var i = 0, rowLen = row.length; i < rowLen; i++) { + var node = row[i]; + var nodeLayout = {}; + var step = rowOtherLength ? + node.getLayout().area / rowOtherLength : 0; + + var wh1 = nodeLayout[wh[idx1WhenH]] = mathMax$4(rowOtherLength - 2 * halfGapWidth, 0); + + // We use Math.max/min to avoid negative width/height when considering gap width. + var remain = rect[xy[idx0WhenH]] + rect[wh[idx0WhenH]] - last; + var modWH = (i === rowLen - 1 || remain < step) ? remain : step; + var wh0 = nodeLayout[wh[idx0WhenH]] = mathMax$4(modWH - 2 * halfGapWidth, 0); + + nodeLayout[xy[idx1WhenH]] = rect[xy[idx1WhenH]] + mathMin$4(halfGapWidth, wh1 / 2); + nodeLayout[xy[idx0WhenH]] = last + mathMin$4(halfGapWidth, wh0 / 2); + + last += modWH; + node.setLayout(nodeLayout, true); + } + + rect[xy[idx1WhenH]] += rowOtherLength; + rect[wh[idx1WhenH]] -= rowOtherLength; + } + + // Return [containerWidth, containerHeight] as defualt. + function estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) { + // If targetInfo.node exists, we zoom to the node, + // so estimate whold width and heigth by target node. + var currNode = (targetInfo || {}).node; + var defaultSize = [containerWidth, containerHeight]; + + if (!currNode || currNode === viewRoot) { + return defaultSize; + } + + var parent; + var viewArea = containerWidth * containerHeight; + var area = viewArea * seriesModel.option.zoomToNodeRatio; + + while (parent = currNode.parentNode) { // jshint ignore:line + var sum = 0; + var siblings = parent.children; + + for (var i = 0, len = siblings.length; i < len; i++) { + sum += siblings[i].getValue(); + } + var currNodeValue = currNode.getValue(); + if (currNodeValue === 0) { + return defaultSize; + } + area *= sum / currNodeValue; + + // Considering border, suppose aspect ratio is 1. + var parentModel = parent.getModel(); + var borderWidth = parentModel.get(PATH_BORDER_WIDTH); + var upperHeight = Math.max(borderWidth, getUpperLabelHeight(parentModel, borderWidth)); + area += 4 * borderWidth * borderWidth + + (3 * borderWidth + upperHeight) * Math.pow(area, 0.5); + + area > MAX_SAFE_INTEGER && (area = MAX_SAFE_INTEGER); + + currNode = parent; + } + + area < viewArea && (area = viewArea); + var scale = Math.pow(area / viewArea, 0.5); + + return [containerWidth * scale, containerHeight * scale]; + } + + // Root postion base on coord of containerGroup + function calculateRootPosition(layoutInfo, rootRect, targetInfo) { + if (rootRect) { + return { + x: rootRect.x, + y: rootRect.y + }; + } + + var defaultPosition = { + x: 0, + y: 0 + }; + if (!targetInfo) { + return defaultPosition; + } + + // If targetInfo is fetched by 'retrieveTargetInfo', + // old tree and new tree are the same tree, + // so the node still exists and we can visit it. + + var targetNode = targetInfo.node; + var layout = targetNode.getLayout(); + + if (!layout) { + return defaultPosition; + } + + // Transform coord from local to container. + var targetCenter = [layout.width / 2, layout.height / 2]; + var node = targetNode; + while (node) { + var nodeLayout = node.getLayout(); + targetCenter[0] += nodeLayout.x; + targetCenter[1] += nodeLayout.y; + node = node.parentNode; + } + + return { + x: layoutInfo.width / 2 - targetCenter[0], + y: layoutInfo.height / 2 - targetCenter[1] + }; + } + + // Mark nodes visible for prunning when visual coding and rendering. + // Prunning depends on layout and root position, so we have to do it after layout. + function prunning(node, clipRect, viewAbovePath, viewRoot, depth) { + var nodeLayout = node.getLayout(); + var nodeInViewAbovePath = viewAbovePath[depth]; + var isAboveViewRoot = nodeInViewAbovePath && nodeInViewAbovePath === node; + + if ( + (nodeInViewAbovePath && !isAboveViewRoot) || + (depth === viewAbovePath.length && node !== viewRoot) + ) { + return; + } + + node.setLayout({ + // isInView means: viewRoot sub tree + viewAbovePath + isInView: true, + // invisible only means: outside view clip so that the node can not + // see but still layout for animation preparation but not render. + invisible: !isAboveViewRoot && !clipRect.intersect(nodeLayout), + isAboveViewRoot: isAboveViewRoot + }, true); + + // Transform to child coordinate. + var childClipRect = new BoundingRect( + clipRect.x - nodeLayout.x, + clipRect.y - nodeLayout.y, + clipRect.width, + clipRect.height + ); + + each$10(node.viewChildren || [], function(child) { + prunning(child, childClipRect, viewAbovePath, viewRoot, depth + 1); + }); + } + + function getUpperLabelHeight(model) { + return model.get(PATH_UPPER_LABEL_SHOW) ? model.get(PATH_UPPER_LABEL_HEIGHT) : 0; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(treemapVisual); + registerLayout(treemapLayout); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Graph data structure + * + * @module echarts/data/Graph + * @author Yi Shen(https://www.github.com/pissang) + */ + + // id may be function name of Object, add a prefix to avoid this problem. + function generateNodeKey(id) { + return '_EC_' + id; + } + /** + * @alias module:echarts/data/Graph + * @constructor + * @param {boolean} directed + */ + var Graph = function(directed) { + /** + * 是否是有向图 + * @type {boolean} + * @private + */ + this._directed = directed || false; + + /** + * @type {Array.} + * @readOnly + */ + this.nodes = []; + + /** + * @type {Array.} + * @readOnly + */ + this.edges = []; + + /** + * @type {Object.} + * @private + */ + this._nodesMap = {}; + /** + * @type {Object.} + * @private + */ + this._edgesMap = {}; + + /** + * @type {module:echarts/data/List} + * @readOnly + */ + this.data; + + /** + * @type {module:echarts/data/List} + * @readOnly + */ + this.edgeData; + }; + + var graphProto = Graph.prototype; + /** + * @type {string} + */ + graphProto.type = 'graph'; + + /** + * If is directed graph + * @return {boolean} + */ + graphProto.isDirected = function() { + return this._directed; + }; + + /** + * Add a new node + * @param {string} id + * @param {number} [dataIndex] + */ + graphProto.addNode = function(id, dataIndex) { + id = id || ('' + dataIndex); + + var nodesMap = this._nodesMap; + + if (nodesMap[generateNodeKey(id)]) { + if (__DEV__) { + console.error('Graph nodes have duplicate name or id'); + } + return; + } + + var node = new Node(id, dataIndex); + node.hostGraph = this; + + this.nodes.push(node); + + nodesMap[generateNodeKey(id)] = node; + return node; + }; + + /** + * Get node by data index + * @param {number} dataIndex + * @return {module:echarts/data/Graph~Node} + */ + graphProto.getNodeByIndex = function(dataIndex) { + var rawIdx = this.data.getRawIndex(dataIndex); + return this.nodes[rawIdx]; + }; + /** + * Get node by id + * @param {string} id + * @return {module:echarts/data/Graph.Node} + */ + graphProto.getNodeById = function(id) { + return this._nodesMap[generateNodeKey(id)]; + }; + + /** + * Add a new edge + * @param {number|string|module:echarts/data/Graph.Node} n1 + * @param {number|string|module:echarts/data/Graph.Node} n2 + * @param {number} [dataIndex=-1] + * @return {module:echarts/data/Graph.Edge} + */ + graphProto.addEdge = function(n1, n2, dataIndex) { + var nodesMap = this._nodesMap; + var edgesMap = this._edgesMap; + + // PNEDING + if (typeof n1 === 'number') { + n1 = this.nodes[n1]; + } + if (typeof n2 === 'number') { + n2 = this.nodes[n2]; + } + + if (!Node.isInstance(n1)) { + n1 = nodesMap[generateNodeKey(n1)]; + } + if (!Node.isInstance(n2)) { + n2 = nodesMap[generateNodeKey(n2)]; + } + if (!n1 || !n2) { + return; + } + + var key = n1.id + '-' + n2.id; + // PENDING + if (edgesMap[key]) { + return; + } + + var edge = new Edge(n1, n2, dataIndex); + edge.hostGraph = this; + + if (this._directed) { + n1.outEdges.push(edge); + n2.inEdges.push(edge); + } + n1.edges.push(edge); + if (n1 !== n2) { + n2.edges.push(edge); + } + + this.edges.push(edge); + edgesMap[key] = edge; + + return edge; + }; + + /** + * Get edge by data index + * @param {number} dataIndex + * @return {module:echarts/data/Graph~Node} + */ + graphProto.getEdgeByIndex = function(dataIndex) { + var rawIdx = this.edgeData.getRawIndex(dataIndex); + return this.edges[rawIdx]; + }; + /** + * Get edge by two linked nodes + * @param {module:echarts/data/Graph.Node|string} n1 + * @param {module:echarts/data/Graph.Node|string} n2 + * @return {module:echarts/data/Graph.Edge} + */ + graphProto.getEdge = function(n1, n2) { + if (Node.isInstance(n1)) { + n1 = n1.id; + } + if (Node.isInstance(n2)) { + n2 = n2.id; + } + + var edgesMap = this._edgesMap; + + if (this._directed) { + return edgesMap[n1 + '-' + n2]; + } else { + return edgesMap[n1 + '-' + n2] || + edgesMap[n2 + '-' + n1]; + } + }; + + /** + * Iterate all nodes + * @param {Function} cb + * @param {*} [context] + */ + graphProto.eachNode = function(cb, context) { + var nodes = this.nodes; + var len = nodes.length; + for (var i = 0; i < len; i++) { + if (nodes[i].dataIndex >= 0) { + cb.call(context, nodes[i], i); + } + } + }; + + /** + * Iterate all edges + * @param {Function} cb + * @param {*} [context] + */ + graphProto.eachEdge = function(cb, context) { + var edges = this.edges; + var len = edges.length; + for (var i = 0; i < len; i++) { + if (edges[i].dataIndex >= 0 && + edges[i].node1.dataIndex >= 0 && + edges[i].node2.dataIndex >= 0 + ) { + cb.call(context, edges[i], i); + } + } + }; + + /** + * Breadth first traverse + * @param {Function} cb + * @param {module:echarts/data/Graph.Node} startNode + * @param {string} [direction='none'] 'none'|'in'|'out' + * @param {*} [context] + */ + graphProto.breadthFirstTraverse = function( + cb, startNode, direction, context + ) { + if (!Node.isInstance(startNode)) { + startNode = this._nodesMap[generateNodeKey(startNode)]; + } + if (!startNode) { + return; + } + + var edgeType = direction === 'out' ? + 'outEdges' : (direction === 'in' ? 'inEdges' : 'edges'); + + for (var i = 0; i < this.nodes.length; i++) { + this.nodes[i].__visited = false; + } + + if (cb.call(context, startNode, null)) { + return; + } + + var queue = [startNode]; + while (queue.length) { + var currentNode = queue.shift(); + var edges = currentNode[edgeType]; + + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + var otherNode = e.node1 === currentNode ? + e.node2 : e.node1; + if (!otherNode.__visited) { + if (cb.call(context, otherNode, currentNode)) { + // Stop traversing + return; + } + queue.push(otherNode); + otherNode.__visited = true; + } + } + } + }; + + // TODO + // graphProto.depthFirstTraverse = function ( + // cb, startNode, direction, context + // ) { + + // }; + + // Filter update + graphProto.update = function() { + var data = this.data; + var edgeData = this.edgeData; + var nodes = this.nodes; + var edges = this.edges; + + for (var i = 0, len = nodes.length; i < len; i++) { + nodes[i].dataIndex = -1; + } + for (var i = 0, len = data.count(); i < len; i++) { + nodes[data.getRawIndex(i)].dataIndex = i; + } + + edgeData.filterSelf(function(idx) { + var edge = edges[edgeData.getRawIndex(idx)]; + return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0; + }); + + // Update edge + for (var i = 0, len = edges.length; i < len; i++) { + edges[i].dataIndex = -1; + } + for (var i = 0, len = edgeData.count(); i < len; i++) { + edges[edgeData.getRawIndex(i)].dataIndex = i; + } + }; + + /** + * @return {module:echarts/data/Graph} + */ + graphProto.clone = function() { + var graph = new Graph(this._directed); + var nodes = this.nodes; + var edges = this.edges; + for (var i = 0; i < nodes.length; i++) { + graph.addNode(nodes[i].id, nodes[i].dataIndex); + } + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + graph.addEdge(e.node1.id, e.node2.id, e.dataIndex); + } + return graph; + }; + + + /** + * @alias module:echarts/data/Graph.Node + */ + function Node(id, dataIndex) { + /** + * @type {string} + */ + this.id = id == null ? '' : id; + + /** + * @type {Array.} + */ + this.inEdges = []; + /** + * @type {Array.} + */ + this.outEdges = []; + /** + * @type {Array.} + */ + this.edges = []; + /** + * @type {module:echarts/data/Graph} + */ + this.hostGraph; + + /** + * @type {number} + */ + this.dataIndex = dataIndex == null ? -1 : dataIndex; + } + + Node.prototype = { + + constructor: Node, + + /** + * @return {number} + */ + degree: function() { + return this.edges.length; + }, + + /** + * @return {number} + */ + inDegree: function() { + return this.inEdges.length; + }, + + /** + * @return {number} + */ + outDegree: function() { + return this.outEdges.length; + }, + + /** + * @param {string} [path] + * @return {module:echarts/model/Model} + */ + getModel: function(path) { + if (this.dataIndex < 0) { + return; + } + var graph = this.hostGraph; + var itemModel = graph.data.getItemModel(this.dataIndex); + + return itemModel.getModel(path); + } + }; + + /** + * 图边 + * @alias module:echarts/data/Graph.Edge + * @param {module:echarts/data/Graph.Node} n1 + * @param {module:echarts/data/Graph.Node} n2 + * @param {number} [dataIndex=-1] + */ + function Edge(n1, n2, dataIndex) { + + /** + * 节点1,如果是有向图则为源节点 + * @type {module:echarts/data/Graph.Node} + */ + this.node1 = n1; + + /** + * 节点2,如果是有向图则为目标节点 + * @type {module:echarts/data/Graph.Node} + */ + this.node2 = n2; + + this.dataIndex = dataIndex == null ? -1 : dataIndex; + } + + /** + * @param {string} [path] + * @return {module:echarts/model/Model} + */ + Edge.prototype.getModel = function(path) { + if (this.dataIndex < 0) { + return; + } + var graph = this.hostGraph; + var itemModel = graph.edgeData.getItemModel(this.dataIndex); + + return itemModel.getModel(path); + }; + + var createGraphDataProxyMixin = function(hostName, dataName) { + return { + /** + * @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'. + * @return {number} + */ + getValue: function(dimension) { + var data = this[hostName][dataName]; + return data.get(data.getDimension(dimension || 'value'), this.dataIndex); + }, + + /** + * @param {Object|string} key + * @param {*} [value] + */ + setVisual: function(key, value) { + this.dataIndex >= 0 && + this[hostName][dataName].setItemVisual(this.dataIndex, key, value); + }, + + /** + * @param {string} key + * @return {boolean} + */ + getVisual: function(key, ignoreParent) { + return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent); + }, + + /** + * @param {Object} layout + * @return {boolean} [merge=false] + */ + setLayout: function(layout, merge$$1) { + this.dataIndex >= 0 && + this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge$$1); + }, + + /** + * @return {Object} + */ + getLayout: function() { + return this[hostName][dataName].getItemLayout(this.dataIndex); + }, + + /** + * @return {module:zrender/Element} + */ + getGraphicEl: function() { + return this[hostName][dataName].getItemGraphicEl(this.dataIndex); + }, + + /** + * @return {number} + */ + getRawIndex: function() { + return this[hostName][dataName].getRawIndex(this.dataIndex); + } + }; + }; + + mixin(Node, createGraphDataProxyMixin('hostGraph', 'data')); + mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData')); + + Graph.Node = Node; + Graph.Edge = Edge; + + enableClassCheck(Node); + enableClassCheck(Edge); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var createGraphFromNodeEdge = function(nodes, edges, seriesModel, directed, beforeLink) { + // ??? TODO + // support dataset? + var graph = new Graph(directed); + for (var i = 0; i < nodes.length; i++) { + graph.addNode(retrieve( + // Id, name, dataIndex + nodes[i].id, nodes[i].name, i + ), i); + } + + var linkNameList = []; + var validEdges = []; + var linkCount = 0; + for (var i = 0; i < edges.length; i++) { + var link = edges[i]; + var source = link.source; + var target = link.target; + // addEdge may fail when source or target not exists + if (graph.addEdge(source, target, linkCount)) { + validEdges.push(link); + linkNameList.push(retrieve(link.id, source + ' > ' + target)); + linkCount++; + } + } + + var coordSys = seriesModel.get('coordinateSystem'); + var nodeData; + if (coordSys === 'cartesian2d' || coordSys === 'polar') { + nodeData = createListFromArray(nodes, seriesModel); + } else { + var coordSysCtor = CoordinateSystemManager.get(coordSys); + var coordDimensions = (coordSysCtor && coordSysCtor.type !== 'view') ? + (coordSysCtor.dimensions || []) : []; + // FIXME: Some geo do not need `value` dimenson, whereas `calendar` needs + // `value` dimension, but graph need `value` dimension. It's better to + // uniform this behavior. + if (indexOf(coordDimensions, 'value') < 0) { + coordDimensions.concat(['value']); + } + + var dimensionNames = createDimensions(nodes, { + coordDimensions: coordDimensions + }); + nodeData = new List(dimensionNames, seriesModel); + nodeData.initData(nodes); + } + + var edgeData = new List(['value'], seriesModel); + edgeData.initData(validEdges, linkNameList); + + beforeLink && beforeLink(nodeData, edgeData); + + linkList({ + mainData: nodeData, + struct: graph, + structAttr: 'graph', + datas: { + node: nodeData, + edge: edgeData + }, + datasAttr: { + node: 'data', + edge: 'edgeData' + } + }); + + // Update dataIndex of nodes and edges because invalid edge may be removed + graph.update(); + + return graph; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var GraphSeries = extendSeriesModel({ + + type: 'series.graph', + + init: function(option) { + GraphSeries.superApply(this, 'init', arguments); + + // Provide data for legend select + this.legendDataProvider = function() { + return this._categoriesData; + }; + + this.fillDataTextStyle(option.edges || option.links); + + this._updateCategoriesData(); + }, + + mergeOption: function(option) { + GraphSeries.superApply(this, 'mergeOption', arguments); + + this.fillDataTextStyle(option.edges || option.links); + + this._updateCategoriesData(); + }, + + mergeDefaultAndTheme: function(option) { + GraphSeries.superApply(this, 'mergeDefaultAndTheme', arguments); + defaultEmphasis(option, ['edgeLabel'], ['show']); + }, + + getInitialData: function(option, ecModel) { + var edges = option.edges || option.links || []; + var nodes = option.data || option.nodes || []; + var self = this; + + if (nodes && edges) { + return createGraphFromNodeEdge(nodes, edges, this, true, beforeLink).data; + } + + function beforeLink(nodeData, edgeData) { + // Overwrite nodeData.getItemModel to + nodeData.wrapMethod('getItemModel', function(model) { + var categoriesModels = self._categoriesModels; + var categoryIdx = model.getShallow('category'); + var categoryModel = categoriesModels[categoryIdx]; + if (categoryModel) { + categoryModel.parentModel = model.parentModel; + model.parentModel = categoryModel; + } + return model; + }); + + var edgeLabelModel = self.getModel('edgeLabel'); + // For option `edgeLabel` can be found by label.xxx.xxx on item mode. + var fakeSeriesModel = new Model({ + label: edgeLabelModel.option + }, + edgeLabelModel.parentModel, + ecModel + ); + var emphasisEdgeLabelModel = self.getModel('emphasis.edgeLabel'); + var emphasisFakeSeriesModel = new Model({ + emphasis: { + label: emphasisEdgeLabelModel.option + } + }, + emphasisEdgeLabelModel.parentModel, + ecModel + ); + + edgeData.wrapMethod('getItemModel', function(model) { + model.customizeGetParent(edgeGetParent); + return model; + }); + + function edgeGetParent(path) { + path = this.parsePath(path); + return (path && path[0] === 'label') ? + fakeSeriesModel : + (path && path[0] === 'emphasis' && path[1] === 'label') ? + emphasisFakeSeriesModel : + this.parentModel; + } + } + }, + + /** + * @return {module:echarts/data/Graph} + */ + getGraph: function() { + return this.getData().graph; + }, + + /** + * @return {module:echarts/data/List} + */ + getEdgeData: function() { + return this.getGraph().edgeData; + }, + + /** + * @return {module:echarts/data/List} + */ + getCategoriesData: function() { + return this._categoriesData; + }, + + /** + * @override + */ + formatTooltip: function(dataIndex, multipleSeries, dataType) { + if (dataType === 'edge') { + var nodeData = this.getData(); + var params = this.getDataParams(dataIndex, dataType); + var edge = nodeData.graph.getEdgeByIndex(dataIndex); + var sourceName = nodeData.getName(edge.node1.dataIndex); + var targetName = nodeData.getName(edge.node2.dataIndex); + + var html = []; + sourceName != null && html.push(sourceName); + targetName != null && html.push(targetName); + html = encodeHTML(html.join(' > ')); + + if (params.value) { + html += ' : ' + encodeHTML(params.value); + } + return html; + } else { // dataType === 'node' or empty + return GraphSeries.superApply(this, 'formatTooltip', arguments); + } + }, + + _updateCategoriesData: function() { + var categories = map(this.option.categories || [], function(category) { + // Data must has value + return category.value != null ? category : extend({ + value: 0 + }, category); + }); + var categoriesData = new List(['value'], this); + categoriesData.initData(categories); + + this._categoriesData = categoriesData; + + this._categoriesModels = categoriesData.mapArray(function(idx) { + return categoriesData.getItemModel(idx, true); + }); + }, + + setZoom: function(zoom) { + this.option.zoom = zoom; + }, + + setCenter: function(center) { + this.option.center = center; + }, + + isAnimationEnabled: function() { + return GraphSeries.superCall(this, 'isAnimationEnabled') + // Not enable animation when do force layout + && + !(this.get('layout') === 'force' && this.get('force.layoutAnimation')); + }, + + defaultOption: { + zlevel: 0, + z: 2, + + coordinateSystem: 'view', + + // Default option for all coordinate systems + // xAxisIndex: 0, + // yAxisIndex: 0, + // polarIndex: 0, + // geoIndex: 0, + + legendHoverLink: true, + + hoverAnimation: true, + + layout: null, + + focusNodeAdjacency: false, + + // Configuration of circular layout + circular: { + rotateLabel: false + }, + // Configuration of force directed layout + force: { + initLayout: null, + // Node repulsion. Can be an array to represent range. + repulsion: [0, 50], + gravity: 0.1, + + // Edge length. Can be an array to represent range. + edgeLength: 30, + + layoutAnimation: true + }, + + left: 'center', + top: 'center', + // right: null, + // bottom: null, + // width: '80%', + // height: '80%', + + symbol: 'circle', + symbolSize: 10, + + edgeSymbol: ['none', 'none'], + edgeSymbolSize: 10, + edgeLabel: { + position: 'middle' + }, + + draggable: false, + + roam: false, + + // Default on center of graph + center: null, + + zoom: 1, + // Symbol size scale ratio in roam + nodeScaleRatio: 0.6, + // cursor: null, + + // categories: [], + + // data: [] + // Or + // nodes: [] + // + // links: [] + // Or + // edges: [] + + label: { + show: false, + formatter: '{b}' + }, + + itemStyle: {}, + + lineStyle: { + color: '#aaa', + width: 1, + curveness: 0, + opacity: 0.5 + }, + emphasis: { + label: { + show: true + } + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Line path for bezier and straight line draw + */ + + var straightLineProto = Line.prototype; + var bezierCurveProto = BezierCurve.prototype; + + function isLine(shape) { + return isNaN(+shape.cpx1) || isNaN(+shape.cpy1); + } + + var LinePath = extendShape({ + + type: 'ec-line', + + style: { + stroke: '#000', + fill: null + }, + + shape: { + x1: 0, + y1: 0, + x2: 0, + y2: 0, + percent: 1, + cpx1: null, + cpy1: null + }, + + buildPath: function(ctx, shape) { + (isLine(shape) ? straightLineProto : bezierCurveProto).buildPath(ctx, shape); + }, + + pointAt: function(t) { + return isLine(this.shape) ? + straightLineProto.pointAt.call(this, t) : + bezierCurveProto.pointAt.call(this, t); + }, + + tangentAt: function(t) { + var shape = this.shape; + var p = isLine(shape) ? + [shape.x2 - shape.x1, shape.y2 - shape.y1] : + bezierCurveProto.tangentAt.call(this, t); + return normalize(p, p); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/chart/helper/Line + */ + + var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol']; + + function makeSymbolTypeKey(symbolCategory) { + return '_' + symbolCategory + 'Type'; + } + /** + * @inner + */ + function createSymbol$1(name, lineData, idx) { + var color = lineData.getItemVisual(idx, 'color'); + var symbolType = lineData.getItemVisual(idx, name); + var symbolSize = lineData.getItemVisual(idx, name + 'Size'); + + if (!symbolType || symbolType === 'none') { + return; + } + + if (!isArray(symbolSize)) { + symbolSize = [symbolSize, symbolSize]; + } + var symbolPath = createSymbol( + symbolType, -symbolSize[0] / 2, -symbolSize[1] / 2, + symbolSize[0], symbolSize[1], color + ); + + symbolPath.name = name; + + return symbolPath; + } + + function createLine(points) { + var line = new LinePath({ + name: 'line' + }); + setLinePoints(line.shape, points); + return line; + } + + function setLinePoints(targetShape, points) { + var p1 = points[0]; + var p2 = points[1]; + var cp1 = points[2]; + targetShape.x1 = p1[0]; + targetShape.y1 = p1[1]; + targetShape.x2 = p2[0]; + targetShape.y2 = p2[1]; + targetShape.percent = 1; + + if (cp1) { + targetShape.cpx1 = cp1[0]; + targetShape.cpy1 = cp1[1]; + } else { + targetShape.cpx1 = NaN; + targetShape.cpy1 = NaN; + } + } + + function updateSymbolAndLabelBeforeLineUpdate() { + var lineGroup = this; + var symbolFrom = lineGroup.childOfName('fromSymbol'); + var symbolTo = lineGroup.childOfName('toSymbol'); + var label = lineGroup.childOfName('label'); + // Quick reject + if (!symbolFrom && !symbolTo && label.ignore) { + return; + } + + var invScale = 1; + var parentNode = this.parent; + while (parentNode) { + if (parentNode.scale) { + invScale /= parentNode.scale[0]; + } + parentNode = parentNode.parent; + } + + var line = lineGroup.childOfName('line'); + // If line not changed + // FIXME Parent scale changed + if (!this.__dirty && !line.__dirty) { + return; + } + + var percent = line.shape.percent; + var fromPos = line.pointAt(0); + var toPos = line.pointAt(percent); + + var d = sub([], toPos, fromPos); + normalize(d, d); + + if (symbolFrom) { + symbolFrom.attr('position', fromPos); + var tangent = line.tangentAt(0); + symbolFrom.attr('rotation', Math.PI / 2 - Math.atan2( + tangent[1], tangent[0] + )); + symbolFrom.attr('scale', [invScale * percent, invScale * percent]); + } + if (symbolTo) { + symbolTo.attr('position', toPos); + var tangent = line.tangentAt(1); + symbolTo.attr('rotation', -Math.PI / 2 - Math.atan2( + tangent[1], tangent[0] + )); + symbolTo.attr('scale', [invScale * percent, invScale * percent]); + } + + if (!label.ignore) { + label.attr('position', toPos); + + var textPosition; + var textAlign; + var textVerticalAlign; + + var distance$$1 = 5 * invScale; + // End + if (label.__position === 'end') { + textPosition = [d[0] * distance$$1 + toPos[0], d[1] * distance$$1 + toPos[1]]; + textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center'); + textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle'); + } + // Middle + else if (label.__position === 'middle') { + var halfPercent = percent / 2; + var tangent = line.tangentAt(halfPercent); + var n = [tangent[1], -tangent[0]]; + var cp = line.pointAt(halfPercent); + if (n[1] > 0) { + n[0] = -n[0]; + n[1] = -n[1]; + } + textPosition = [cp[0] + n[0] * distance$$1, cp[1] + n[1] * distance$$1]; + textAlign = 'center'; + textVerticalAlign = 'bottom'; + var rotation = -Math.atan2(tangent[1], tangent[0]); + if (toPos[0] < fromPos[0]) { + rotation = Math.PI + rotation; + } + label.attr('rotation', rotation); + } + // Start + else { + textPosition = [-d[0] * distance$$1 + fromPos[0], -d[1] * distance$$1 + fromPos[1]]; + textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center'); + textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle'); + } + label.attr({ + style: { + // Use the user specified text align and baseline first + textVerticalAlign: label.__verticalAlign || textVerticalAlign, + textAlign: label.__textAlign || textAlign + }, + position: textPosition, + scale: [invScale, invScale] + }); + } + } + + /** + * @constructor + * @extends {module:zrender/graphic/Group} + * @alias {module:echarts/chart/helper/Line} + */ + function Line$1(lineData, idx, seriesScope) { + Group.call(this); + + this._createLine(lineData, idx, seriesScope); + } + + var lineProto = Line$1.prototype; + + // Update symbol position and rotation + lineProto.beforeUpdate = updateSymbolAndLabelBeforeLineUpdate; + + lineProto._createLine = function(lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + var linePoints = lineData.getItemLayout(idx); + + var line = createLine(linePoints); + line.shape.percent = 0; + initProps(line, { + shape: { + percent: 1 + } + }, seriesModel, idx); + + this.add(line); + + var label = new Text({ + name: 'label' + }); + this.add(label); + + each$1(SYMBOL_CATEGORIES, function(symbolCategory) { + var symbol = createSymbol$1(symbolCategory, lineData, idx); + // symbols must added after line to make sure + // it will be updated after line#update. + // Or symbol position and rotation update in line#beforeUpdate will be one frame slow + this.add(symbol); + this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory); + }, this); + + this._updateCommonStl(lineData, idx, seriesScope); + }; + + lineProto.updateData = function(lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + + var line = this.childOfName('line'); + var linePoints = lineData.getItemLayout(idx); + var target = { + shape: {} + }; + setLinePoints(target.shape, linePoints); + updateProps(line, target, seriesModel, idx); + + each$1(SYMBOL_CATEGORIES, function(symbolCategory) { + var symbolType = lineData.getItemVisual(idx, symbolCategory); + var key = makeSymbolTypeKey(symbolCategory); + // Symbol changed + if (this[key] !== symbolType) { + this.remove(this.childOfName(symbolCategory)); + var symbol = createSymbol$1(symbolCategory, lineData, idx); + this.add(symbol); + } + this[key] = symbolType; + }, this); + + this._updateCommonStl(lineData, idx, seriesScope); + }; + + lineProto._updateCommonStl = function(lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + + var line = this.childOfName('line'); + + var lineStyle = seriesScope && seriesScope.lineStyle; + var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle; + var labelModel = seriesScope && seriesScope.labelModel; + var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel; + + // Optimization for large dataset + if (!seriesScope || lineData.hasItemOption) { + var itemModel = lineData.getItemModel(idx); + + lineStyle = itemModel.getModel('lineStyle').getLineStyle(); + hoverLineStyle = itemModel.getModel('emphasis.lineStyle').getLineStyle(); + + labelModel = itemModel.getModel('label'); + hoverLabelModel = itemModel.getModel('emphasis.label'); + } + + var visualColor = lineData.getItemVisual(idx, 'color'); + var visualOpacity = retrieve3( + lineData.getItemVisual(idx, 'opacity'), + lineStyle.opacity, + 1 + ); + + line.useStyle(defaults({ + strokeNoScale: true, + fill: 'none', + stroke: visualColor, + opacity: visualOpacity + }, + lineStyle + )); + line.hoverStyle = hoverLineStyle; + + // Update symbol + each$1(SYMBOL_CATEGORIES, function(symbolCategory) { + var symbol = this.childOfName(symbolCategory); + if (symbol) { + symbol.setColor(visualColor); + symbol.setStyle({ + opacity: visualOpacity + }); + } + }, this); + + var showLabel = labelModel.getShallow('show'); + var hoverShowLabel = hoverLabelModel.getShallow('show'); + + var label = this.childOfName('label'); + var defaultLabelColor; + var baseText; + + // FIXME: the logic below probably should be merged to `graphic.setLabelStyle`. + if (showLabel || hoverShowLabel) { + defaultLabelColor = visualColor || '#000'; + + baseText = seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType); + if (baseText == null) { + var rawVal = seriesModel.getRawValue(idx); + baseText = rawVal == null ? + lineData.getName(idx) : + isFinite(rawVal) ? + round$1(rawVal) : + rawVal; + } + } + var normalText = showLabel ? baseText : null; + var emphasisText = hoverShowLabel ? + retrieve2( + seriesModel.getFormattedLabel(idx, 'emphasis', lineData.dataType), + baseText + ) : + null; + + var labelStyle = label.style; + + // Always set `textStyle` even if `normalStyle.text` is null, because default + // values have to be set on `normalStyle`. + if (normalText != null || emphasisText != null) { + setTextStyle(label.style, labelModel, { + text: normalText + }, { + autoColor: defaultLabelColor + }); + + label.__textAlign = labelStyle.textAlign; + label.__verticalAlign = labelStyle.textVerticalAlign; + // 'start', 'middle', 'end' + label.__position = labelModel.get('position') || 'middle'; + } + + if (emphasisText != null) { + // Only these properties supported in this emphasis style here. + label.hoverStyle = { + text: emphasisText, + textFill: hoverLabelModel.getTextColor(true), + // For merging hover style to normal style, do not use + // `hoverLabelModel.getFont()` here. + fontStyle: hoverLabelModel.getShallow('fontStyle'), + fontWeight: hoverLabelModel.getShallow('fontWeight'), + fontSize: hoverLabelModel.getShallow('fontSize'), + fontFamily: hoverLabelModel.getShallow('fontFamily') + }; + } else { + label.hoverStyle = { + text: null + }; + } + + label.ignore = !showLabel && !hoverShowLabel; + + setHoverStyle(this); + }; + + lineProto.highlight = function() { + this.trigger('emphasis'); + }; + + lineProto.downplay = function() { + this.trigger('normal'); + }; + + lineProto.updateLayout = function(lineData, idx) { + this.setLinePoints(lineData.getItemLayout(idx)); + }; + + lineProto.setLinePoints = function(points) { + var linePath = this.childOfName('line'); + setLinePoints(linePath.shape, points); + linePath.dirty(); + }; + + inherits(Line$1, Group); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/chart/helper/LineDraw + */ + + // import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable'; + + /** + * @alias module:echarts/component/marker/LineDraw + * @constructor + */ + function LineDraw(ctor) { + this._ctor = ctor || Line$1; + + this.group = new Group(); + } + + var lineDrawProto = LineDraw.prototype; + + lineDrawProto.isPersistent = function() { + return true; + }; + + /** + * @param {module:echarts/data/List} lineData + */ + lineDrawProto.updateData = function(lineData) { + var lineDraw = this; + var group = lineDraw.group; + + var oldLineData = lineDraw._lineData; + lineDraw._lineData = lineData; + + // There is no oldLineData only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!oldLineData) { + group.removeAll(); + } + + var seriesScope = makeSeriesScope$1(lineData); + + lineData.diff(oldLineData) + .add(function(idx) { + doAdd(lineDraw, lineData, idx, seriesScope); + }) + .update(function(newIdx, oldIdx) { + doUpdate(lineDraw, oldLineData, lineData, oldIdx, newIdx, seriesScope); + }) + .remove(function(idx) { + group.remove(oldLineData.getItemGraphicEl(idx)); + }) + .execute(); + }; + + function doAdd(lineDraw, lineData, idx, seriesScope) { + var itemLayout = lineData.getItemLayout(idx); + + if (!lineNeedsDraw(itemLayout)) { + return; + } + + var el = new lineDraw._ctor(lineData, idx, seriesScope); + lineData.setItemGraphicEl(idx, el); + lineDraw.group.add(el); + } + + function doUpdate(lineDraw, oldLineData, newLineData, oldIdx, newIdx, seriesScope) { + var itemEl = oldLineData.getItemGraphicEl(oldIdx); + + if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) { + lineDraw.group.remove(itemEl); + return; + } + + if (!itemEl) { + itemEl = new lineDraw._ctor(newLineData, newIdx, seriesScope); + } else { + itemEl.updateData(newLineData, newIdx, seriesScope); + } + + newLineData.setItemGraphicEl(newIdx, itemEl); + + lineDraw.group.add(itemEl); + } + + lineDrawProto.updateLayout = function() { + var lineData = this._lineData; + + // Do not support update layout in incremental mode. + if (!lineData) { + return; + } + + lineData.eachItemGraphicEl(function(el, idx) { + el.updateLayout(lineData, idx); + }, this); + }; + + lineDrawProto.incrementalPrepareUpdate = function(lineData) { + this._seriesScope = makeSeriesScope$1(lineData); + this._lineData = null; + this.group.removeAll(); + }; + + lineDrawProto.incrementalUpdate = function(taskParams, lineData) { + function updateIncrementalAndHover(el) { + if (!el.isGroup) { + el.incremental = el.useHoverLayer = true; + } + } + + for (var idx = taskParams.start; idx < taskParams.end; idx++) { + var itemLayout = lineData.getItemLayout(idx); + + if (lineNeedsDraw(itemLayout)) { + var el = new this._ctor(lineData, idx, this._seriesScope); + el.traverse(updateIncrementalAndHover); + + this.group.add(el); + lineData.setItemGraphicEl(idx, el); + } + } + }; + + function makeSeriesScope$1(lineData) { + var hostModel = lineData.hostModel; + return { + lineStyle: hostModel.getModel('lineStyle').getLineStyle(), + hoverLineStyle: hostModel.getModel('emphasis.lineStyle').getLineStyle(), + labelModel: hostModel.getModel('label'), + hoverLabelModel: hostModel.getModel('emphasis.label') + }; + } + + lineDrawProto.remove = function() { + this._clearIncremental(); + this._incremental = null; + this.group.removeAll(); + }; + + lineDrawProto._clearIncremental = function() { + var incremental = this._incremental; + if (incremental) { + incremental.clearDisplaybles(); + } + }; + + function isPointNaN(pt) { + return isNaN(pt[0]) || isNaN(pt[1]); + } + + function lineNeedsDraw(pts) { + return !isPointNaN(pts[0]) && !isPointNaN(pts[1]); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var v1 = []; + var v2 = []; + var v3 = []; + var quadraticAt$1 = quadraticAt; + var v2DistSquare = distSquare; + var mathAbs$1 = Math.abs; + + function intersectCurveCircle(curvePoints, center, radius) { + var p0 = curvePoints[0]; + var p1 = curvePoints[1]; + var p2 = curvePoints[2]; + + var d = Infinity; + var t; + var radiusSquare = radius * radius; + var interval = 0.1; + + for (var _t = 0.1; _t <= 0.9; _t += 0.1) { + v1[0] = quadraticAt$1(p0[0], p1[0], p2[0], _t); + v1[1] = quadraticAt$1(p0[1], p1[1], p2[1], _t); + var diff = mathAbs$1(v2DistSquare(v1, center) - radiusSquare); + if (diff < d) { + d = diff; + t = _t; + } + } + + // Assume the segment is monotone,Find root through Bisection method + // At most 32 iteration + for (var i = 0; i < 32; i++) { + // var prev = t - interval; + var next = t + interval; + // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev); + // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev); + v2[0] = quadraticAt$1(p0[0], p1[0], p2[0], t); + v2[1] = quadraticAt$1(p0[1], p1[1], p2[1], t); + v3[0] = quadraticAt$1(p0[0], p1[0], p2[0], next); + v3[1] = quadraticAt$1(p0[1], p1[1], p2[1], next); + + var diff = v2DistSquare(v2, center) - radiusSquare; + if (mathAbs$1(diff) < 1e-2) { + break; + } + + // var prevDiff = v2DistSquare(v1, center) - radiusSquare; + var nextDiff = v2DistSquare(v3, center) - radiusSquare; + + interval /= 2; + if (diff < 0) { + if (nextDiff >= 0) { + t = t + interval; + } else { + t = t - interval; + } + } else { + if (nextDiff >= 0) { + t = t - interval; + } else { + t = t + interval; + } + } + } + + return t; + } + + // Adjust edge to avoid + var adjustEdge = function(graph, scale$$1) { + var tmp0 = []; + var quadraticSubdivide$$1 = quadraticSubdivide; + var pts = [ + [], + [], + [] + ]; + var pts2 = [ + [], + [] + ]; + var v = []; + scale$$1 /= 2; + + function getSymbolSize(node) { + var symbolSize = node.getVisual('symbolSize'); + if (symbolSize instanceof Array) { + symbolSize = (symbolSize[0] + symbolSize[1]) / 2; + } + return symbolSize; + } + graph.eachEdge(function(edge, idx) { + var linePoints = edge.getLayout(); + var fromSymbol = edge.getVisual('fromSymbol'); + var toSymbol = edge.getVisual('toSymbol'); + + if (!linePoints.__original) { + linePoints.__original = [ + clone$1(linePoints[0]), + clone$1(linePoints[1]) + ]; + if (linePoints[2]) { + linePoints.__original.push(clone$1(linePoints[2])); + } + } + var originalPoints = linePoints.__original; + // Quadratic curve + if (linePoints[2] != null) { + copy(pts[0], originalPoints[0]); + copy(pts[1], originalPoints[2]); + copy(pts[2], originalPoints[1]); + if (fromSymbol && fromSymbol != 'none') { + var symbolSize = getSymbolSize(edge.node1); + + var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale$$1); + // Subdivide and get the second + quadraticSubdivide$$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0); + pts[0][0] = tmp0[3]; + pts[1][0] = tmp0[4]; + quadraticSubdivide$$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0); + pts[0][1] = tmp0[3]; + pts[1][1] = tmp0[4]; + } + if (toSymbol && toSymbol != 'none') { + var symbolSize = getSymbolSize(edge.node2); + + var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale$$1); + // Subdivide and get the first + quadraticSubdivide$$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0); + pts[1][0] = tmp0[1]; + pts[2][0] = tmp0[2]; + quadraticSubdivide$$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0); + pts[1][1] = tmp0[1]; + pts[2][1] = tmp0[2]; + } + // Copy back to layout + copy(linePoints[0], pts[0]); + copy(linePoints[1], pts[2]); + copy(linePoints[2], pts[1]); + } + // Line + else { + copy(pts2[0], originalPoints[0]); + copy(pts2[1], originalPoints[1]); + + sub(v, pts2[1], pts2[0]); + normalize(v, v); + if (fromSymbol && fromSymbol != 'none') { + + var symbolSize = getSymbolSize(edge.node1); + + scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale$$1); + } + if (toSymbol && toSymbol != 'none') { + var symbolSize = getSymbolSize(edge.node2); + + scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale$$1); + } + copy(linePoints[0], pts2[0]); + copy(linePoints[1], pts2[1]); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var nodeOpacityPath = ['itemStyle', 'opacity']; + var lineOpacityPath = ['lineStyle', 'opacity']; + + function getItemOpacity(item, opacityPath) { + return item.getVisual('opacity') || item.getModel().get(opacityPath); + } + + function fadeOutItem(item, opacityPath, opacityRatio) { + var el = item.getGraphicEl(); + + var opacity = getItemOpacity(item, opacityPath); + if (opacityRatio != null) { + opacity == null && (opacity = 1); + opacity *= opacityRatio; + } + + el.downplay && el.downplay(); + el.traverse(function(child) { + if (child.type !== 'group') { + child.setStyle('opacity', opacity); + } + }); + } + + function fadeInItem(item, opacityPath) { + var opacity = getItemOpacity(item, opacityPath); + var el = item.getGraphicEl(); + + el.highlight && el.highlight(); + el.traverse(function(child) { + if (child.type !== 'group') { + child.setStyle('opacity', opacity); + } + }); + } + + extendChartView({ + + type: 'graph', + + init: function(ecModel, api) { + var symbolDraw = new SymbolDraw(); + var lineDraw = new LineDraw(); + var group = this.group; + + this._controller = new RoamController(api.getZr()); + this._controllerHost = { + target: group + }; + + group.add(symbolDraw.group); + group.add(lineDraw.group); + + this._symbolDraw = symbolDraw; + this._lineDraw = lineDraw; + + this._firstRender = true; + }, + + render: function(seriesModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + + this._model = seriesModel; + this._nodeScaleRatio = seriesModel.get('nodeScaleRatio'); + + var symbolDraw = this._symbolDraw; + var lineDraw = this._lineDraw; + + var group = this.group; + + if (coordSys.type === 'view') { + var groupNewProp = { + position: coordSys.position, + scale: coordSys.scale + }; + if (this._firstRender) { + group.attr(groupNewProp); + } else { + updateProps(group, groupNewProp, seriesModel); + } + } + // Fix edge contact point with node + adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel)); + + var data = seriesModel.getData(); + symbolDraw.updateData(data); + + var edgeData = seriesModel.getEdgeData(); + lineDraw.updateData(edgeData); + + this._updateNodeAndLinkScale(); + + this._updateController(seriesModel, ecModel, api); + + clearTimeout(this._layoutTimeout); + var forceLayout = seriesModel.forceLayout; + var layoutAnimation = seriesModel.get('force.layoutAnimation'); + if (forceLayout) { + this._startForceLayoutIteration(forceLayout, layoutAnimation); + } + + data.eachItemGraphicEl(function(el, idx) { + var itemModel = data.getItemModel(idx); + // Update draggable + el.off('drag').off('dragend'); + var draggable = data.getItemModel(idx).get('draggable'); + if (draggable) { + el.on('drag', function() { + if (forceLayout) { + forceLayout.warmUp(); + !this._layouting && + this._startForceLayoutIteration(forceLayout, layoutAnimation); + forceLayout.setFixed(idx); + // Write position back to layout + data.setItemLayout(idx, el.position); + } + }, this).on('dragend', function() { + if (forceLayout) { + forceLayout.setUnfixed(idx); + } + }, this); + } + el.setDraggable(draggable && forceLayout); + + el.off('mouseover', el.__focusNodeAdjacency); + el.off('mouseout', el.__unfocusNodeAdjacency); + + if (itemModel.get('focusNodeAdjacency')) { + el.on('mouseover', el.__focusNodeAdjacency = function() { + api.dispatchAction({ + type: 'focusNodeAdjacency', + seriesId: seriesModel.id, + dataIndex: el.dataIndex + }); + }); + el.on('mouseout', el.__unfocusNodeAdjacency = function() { + api.dispatchAction({ + type: 'unfocusNodeAdjacency', + seriesId: seriesModel.id + }); + }); + + } + + }, this); + + data.graph.eachEdge(function(edge) { + var el = edge.getGraphicEl(); + + el.off('mouseover', el.__focusNodeAdjacency); + el.off('mouseout', el.__unfocusNodeAdjacency); + + if (edge.getModel().get('focusNodeAdjacency')) { + el.on('mouseover', el.__focusNodeAdjacency = function() { + api.dispatchAction({ + type: 'focusNodeAdjacency', + seriesId: seriesModel.id, + edgeDataIndex: edge.dataIndex + }); + }); + el.on('mouseout', el.__unfocusNodeAdjacency = function() { + api.dispatchAction({ + type: 'unfocusNodeAdjacency', + seriesId: seriesModel.id + }); + }); + } + }); + + var circularRotateLabel = seriesModel.get('layout') === 'circular' && + seriesModel.get('circular.rotateLabel'); + var cx = data.getLayout('cx'); + var cy = data.getLayout('cy'); + data.eachItemGraphicEl(function(el, idx) { + var symbolPath = el.getSymbolPath(); + if (circularRotateLabel) { + var pos = data.getItemLayout(idx); + var rad = Math.atan2(pos[1] - cy, pos[0] - cx); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + var isLeft = pos[0] < cx; + if (isLeft) { + rad = rad - Math.PI; + } + var textPosition = isLeft ? 'left' : 'right'; + symbolPath.setStyle({ + textRotation: -rad, + textPosition: textPosition, + textOrigin: 'center' + }); + symbolPath.hoverStyle && (symbolPath.hoverStyle.textPosition = textPosition); + } else { + symbolPath.setStyle({ + textRotation: 0 + }); + } + }); + + this._firstRender = false; + }, + + dispose: function() { + this._controller && this._controller.dispose(); + this._controllerHost = {}; + }, + + focusNodeAdjacency: function(seriesModel, ecModel, api, payload) { + var data = this._model.getData(); + var graph = data.graph; + var dataIndex = payload.dataIndex; + var edgeDataIndex = payload.edgeDataIndex; + + var node = graph.getNodeByIndex(dataIndex); + var edge = graph.getEdgeByIndex(edgeDataIndex); + + if (!node && !edge) { + return; + } + + graph.eachNode(function(node) { + fadeOutItem(node, nodeOpacityPath, 0.1); + }); + graph.eachEdge(function(edge) { + fadeOutItem(edge, lineOpacityPath, 0.1); + }); + + if (node) { + fadeInItem(node, nodeOpacityPath); + each$1(node.edges, function(adjacentEdge) { + if (adjacentEdge.dataIndex < 0) { + return; + } + fadeInItem(adjacentEdge, lineOpacityPath); + fadeInItem(adjacentEdge.node1, nodeOpacityPath); + fadeInItem(adjacentEdge.node2, nodeOpacityPath); + }); + } + if (edge) { + fadeInItem(edge, lineOpacityPath); + fadeInItem(edge.node1, nodeOpacityPath); + fadeInItem(edge.node2, nodeOpacityPath); + } + }, + + unfocusNodeAdjacency: function(seriesModel, ecModel, api, payload) { + var graph = this._model.getData().graph; + + graph.eachNode(function(node) { + fadeOutItem(node, nodeOpacityPath); + }); + graph.eachEdge(function(edge) { + fadeOutItem(edge, lineOpacityPath); + }); + }, + + _startForceLayoutIteration: function(forceLayout, layoutAnimation) { + var self = this; + (function step() { + forceLayout.step(function(stopped) { + self.updateLayout(self._model); + (self._layouting = !stopped) && ( + layoutAnimation ? + (self._layoutTimeout = setTimeout(step, 16)) : + step() + ); + }); + })(); + }, + + _updateController: function(seriesModel, ecModel, api) { + var controller = this._controller; + var controllerHost = this._controllerHost; + var group = this.group; + + controller.setPointerChecker(function(e, x, y) { + var rect = group.getBoundingRect(); + rect.applyTransform(group.transform); + return rect.contain(x, y) && + !onIrrelevantElement(e, api, seriesModel); + }); + + if (seriesModel.coordinateSystem.type !== 'view') { + controller.disable(); + return; + } + controller.enable(seriesModel.get('roam')); + controllerHost.zoomLimit = seriesModel.get('scaleLimit'); + controllerHost.zoom = seriesModel.coordinateSystem.getZoom(); + + controller + .off('pan') + .off('zoom') + .on('pan', function(dx, dy) { + updateViewOnPan(controllerHost, dx, dy); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'graphRoam', + dx: dx, + dy: dy + }); + }) + .on('zoom', function(zoom, mouseX, mouseY) { + updateViewOnZoom(controllerHost, zoom, mouseX, mouseY); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'graphRoam', + zoom: zoom, + originX: mouseX, + originY: mouseY + }); + this._updateNodeAndLinkScale(); + adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel)); + this._lineDraw.updateLayout(); + }, this); + }, + + _updateNodeAndLinkScale: function() { + var seriesModel = this._model; + var data = seriesModel.getData(); + + var nodeScale = this._getNodeGlobalScale(seriesModel); + var invScale = [nodeScale, nodeScale]; + + data.eachItemGraphicEl(function(el, idx) { + el.attr('scale', invScale); + }); + }, + + _getNodeGlobalScale: function(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys.type !== 'view') { + return 1; + } + + var nodeScaleRatio = this._nodeScaleRatio; + + var groupScale = coordSys.scale; + var groupZoom = (groupScale && groupScale[0]) || 1; + // Scale node when zoom changes + var roamZoom = coordSys.getZoom(); + var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1; + + return nodeScale / groupZoom; + }, + + updateLayout: function(seriesModel) { + adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel)); + + this._symbolDraw.updateLayout(); + this._lineDraw.updateLayout(); + }, + + remove: function(ecModel, api) { + this._symbolDraw && this._symbolDraw.remove(); + this._lineDraw && this._lineDraw.remove(); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var actionInfo = { + type: 'graphRoam', + event: 'graphRoam', + update: 'none' + }; + + /** + * @payload + * @property {string} name Series name + * @property {number} [dx] + * @property {number} [dy] + * @property {number} [zoom] + * @property {number} [originX] + * @property {number} [originY] + */ + registerAction(actionInfo, function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + query: payload + }, function(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + + var res = updateCenterAndZoom(coordSys, payload); + + seriesModel.setCenter && + seriesModel.setCenter(res.center); + + seriesModel.setZoom && + seriesModel.setZoom(res.zoom); + }); + }); + + + /** + * @payload + * @property {number} [seriesIndex] + * @property {string} [seriesId] + * @property {string} [seriesName] + * @property {number} [dataIndex] + */ + registerAction({ + type: 'focusNodeAdjacency', + event: 'focusNodeAdjacency', + update: 'series.graph:focusNodeAdjacency' + }, function() {}); + + /** + * @payload + * @property {number} [seriesIndex] + * @property {string} [seriesId] + * @property {string} [seriesName] + */ + registerAction({ + type: 'unfocusNodeAdjacency', + event: 'unfocusNodeAdjacency', + update: 'series.graph:unfocusNodeAdjacency' + }, function() {}); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var categoryFilter = function(ecModel) { + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (!legendModels || !legendModels.length) { + return; + } + ecModel.eachSeriesByType('graph', function(graphSeries) { + var categoriesData = graphSeries.getCategoriesData(); + var graph = graphSeries.getGraph(); + var data = graph.data; + + var categoryNames = categoriesData.mapArray(categoriesData.getName); + + data.filterSelf(function(idx) { + var model = data.getItemModel(idx); + var category = model.getShallow('category'); + if (category != null) { + if (typeof category === 'number') { + category = categoryNames[category]; + } + // If in any legend component the status is not selected. + for (var i = 0; i < legendModels.length; i++) { + if (!legendModels[i].isSelected(category)) { + return false; + } + } + } + return true; + }); + }, this); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var categoryVisual = function(ecModel) { + + var paletteScope = {}; + ecModel.eachSeriesByType('graph', function(seriesModel) { + var categoriesData = seriesModel.getCategoriesData(); + var data = seriesModel.getData(); + + var categoryNameIdxMap = {}; + + categoriesData.each(function(idx) { + var name = categoriesData.getName(idx); + // Add prefix to avoid conflict with Object.prototype. + categoryNameIdxMap['ec-' + name] = idx; + + var itemModel = categoriesData.getItemModel(idx); + var color = itemModel.get('itemStyle.color') || + seriesModel.getColorFromPalette(name, paletteScope); + categoriesData.setItemVisual(idx, 'color', color); + }); + + // Assign category color to visual + if (categoriesData.count()) { + data.each(function(idx) { + var model = data.getItemModel(idx); + var category = model.getShallow('category'); + if (category != null) { + if (typeof category === 'string') { + category = categoryNameIdxMap['ec-' + category]; + } + if (!data.getItemVisual(idx, 'color', true)) { + data.setItemVisual( + idx, 'color', + categoriesData.getItemVisual(category, 'color') + ); + } + } + }); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + function normalize$1(a) { + if (!(a instanceof Array)) { + a = [a, a]; + } + return a; + } + + var edgeVisual = function(ecModel) { + ecModel.eachSeriesByType('graph', function(seriesModel) { + var graph = seriesModel.getGraph(); + var edgeData = seriesModel.getEdgeData(); + var symbolType = normalize$1(seriesModel.get('edgeSymbol')); + var symbolSize = normalize$1(seriesModel.get('edgeSymbolSize')); + + var colorQuery = 'lineStyle.color'.split('.'); + var opacityQuery = 'lineStyle.opacity'.split('.'); + + edgeData.setVisual('fromSymbol', symbolType && symbolType[0]); + edgeData.setVisual('toSymbol', symbolType && symbolType[1]); + edgeData.setVisual('fromSymbolSize', symbolSize && symbolSize[0]); + edgeData.setVisual('toSymbolSize', symbolSize && symbolSize[1]); + edgeData.setVisual('color', seriesModel.get(colorQuery)); + edgeData.setVisual('opacity', seriesModel.get(opacityQuery)); + + edgeData.each(function(idx) { + var itemModel = edgeData.getItemModel(idx); + var edge = graph.getEdgeByIndex(idx); + var symbolType = normalize$1(itemModel.getShallow('symbol', true)); + var symbolSize = normalize$1(itemModel.getShallow('symbolSize', true)); + // Edge visual must after node visual + var color = itemModel.get(colorQuery); + var opacity = itemModel.get(opacityQuery); + switch (color) { + case 'source': + color = edge.node1.getVisual('color'); + break; + case 'target': + color = edge.node2.getVisual('color'); + break; + } + + symbolType[0] && edge.setVisual('fromSymbol', symbolType[0]); + symbolType[1] && edge.setVisual('toSymbol', symbolType[1]); + symbolSize[0] && edge.setVisual('fromSymbolSize', symbolSize[0]); + symbolSize[1] && edge.setVisual('toSymbolSize', symbolSize[1]); + + edge.setVisual('color', color); + edge.setVisual('opacity', opacity); + }); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function simpleLayout$1(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + var graph = seriesModel.getGraph(); + + graph.eachNode(function(node) { + var model = node.getModel(); + node.setLayout([+model.get('x'), +model.get('y')]); + }); + + simpleLayoutEdge(graph); + } + + function simpleLayoutEdge(graph) { + graph.eachEdge(function(edge) { + var curveness = edge.getModel().get('lineStyle.curveness') || 0; + var p1 = clone$1(edge.node1.getLayout()); + var p2 = clone$1(edge.node2.getLayout()); + var points = [p1, p2]; + if (+curveness) { + points.push([ + (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness, + (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness + ]); + } + edge.setLayout(points); + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var simpleLayout = function(ecModel, api) { + ecModel.eachSeriesByType('graph', function(seriesModel) { + var layout = seriesModel.get('layout'); + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + var data = seriesModel.getData(); + + var dimensions = []; + each$1(coordSys.dimensions, function(coordDim) { + dimensions = dimensions.concat(data.mapDimension(coordDim, true)); + }); + + for (var dataIndex = 0; dataIndex < data.count(); dataIndex++) { + var value = []; + var hasValue = false; + for (var i = 0; i < dimensions.length; i++) { + var val = data.get(dimensions[i], dataIndex); + if (!isNaN(val)) { + hasValue = true; + } + value.push(val); + } + if (hasValue) { + data.setItemLayout(dataIndex, coordSys.dataToPoint(value)); + } else { + // Also {Array.}, not undefined to avoid if...else... statement + data.setItemLayout(dataIndex, [NaN, NaN]); + } + } + + simpleLayoutEdge(data.graph); + } else if (!layout || layout === 'none') { + simpleLayout$1(seriesModel); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function circularLayout$1(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + + var rect = coordSys.getBoundingRect(); + + var nodeData = seriesModel.getData(); + var graph = nodeData.graph; + + var angle = 0; + var sum = nodeData.getSum('value'); + var unitAngle = Math.PI * 2 / (sum || nodeData.count()); + + var cx = rect.width / 2 + rect.x; + var cy = rect.height / 2 + rect.y; + + var r = Math.min(rect.width, rect.height) / 2; + + graph.eachNode(function(node) { + var value = node.getValue('value'); + + angle += unitAngle * (sum ? value : 1) / 2; + + node.setLayout([ + r * Math.cos(angle) + cx, + r * Math.sin(angle) + cy + ]); + + angle += unitAngle * (sum ? value : 1) / 2; + }); + + nodeData.setLayout({ + cx: cx, + cy: cy + }); + + graph.eachEdge(function(edge) { + var curveness = edge.getModel().get('lineStyle.curveness') || 0; + var p1 = clone$1(edge.node1.getLayout()); + var p2 = clone$1(edge.node2.getLayout()); + var cp1; + var x12 = (p1[0] + p2[0]) / 2; + var y12 = (p1[1] + p2[1]) / 2; + if (+curveness) { + curveness *= 3; + cp1 = [ + cx * curveness + x12 * (1 - curveness), + cy * curveness + y12 * (1 - curveness) + ]; + } + edge.setLayout([p1, p2, cp1]); + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var circularLayout = function(ecModel) { + ecModel.eachSeriesByType('graph', function(seriesModel) { + if (seriesModel.get('layout') === 'circular') { + circularLayout$1(seriesModel); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * The layout implementation references to d3.js. The use of + * the source code of this file is also subject to the terms + * and consitions of its license (BSD-3Clause, see + * ). + */ + + var scaleAndAdd$2 = scaleAndAdd; + + // function adjacentNode(n, e) { + // return e.n1 === n ? e.n2 : e.n1; + // } + + function forceLayout$1(nodes, edges, opts) { + var rect = opts.rect; + var width = rect.width; + var height = rect.height; + var center = [rect.x + width / 2, rect.y + height / 2]; + // var scale = opts.scale || 1; + var gravity = opts.gravity == null ? 0.1 : opts.gravity; + + // for (var i = 0; i < edges.length; i++) { + // var e = edges[i]; + // var n1 = e.n1; + // var n2 = e.n2; + // n1.edges = n1.edges || []; + // n2.edges = n2.edges || []; + // n1.edges.push(e); + // n2.edges.push(e); + // } + // Init position + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + if (!n.p) { + // Use the position from first adjecent node with defined position + // Or use a random position + // From d3 + // if (n.edges) { + // var j = -1; + // while (++j < n.edges.length) { + // var e = n.edges[j]; + // var other = adjacentNode(n, e); + // if (other.p) { + // n.p = vec2.clone(other.p); + // break; + // } + // } + // } + // if (!n.p) { + n.p = create( + width * (Math.random() - 0.5) + center[0], + height * (Math.random() - 0.5) + center[1] + ); + // } + } + n.pp = clone$1(n.p); + n.edges = null; + } + + // Formula in 'Graph Drawing by Force-directed Placement' + // var k = scale * Math.sqrt(width * height / nodes.length); + // var k2 = k * k; + + var friction = 0.6; + + return { + warmUp: function() { + friction = 0.5; + }, + + setFixed: function(idx) { + nodes[idx].fixed = true; + }, + + setUnfixed: function(idx) { + nodes[idx].fixed = false; + }, + + step: function(cb) { + var v12 = []; + var nLen = nodes.length; + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + var n1 = e.n1; + var n2 = e.n2; + + sub(v12, n2.p, n1.p); + var d = len(v12) - e.d; + var w = n2.w / (n1.w + n2.w); + + if (isNaN(w)) { + w = 0; + } + + normalize(v12, v12); + + !n1.fixed && scaleAndAdd$2(n1.p, n1.p, v12, w * d * friction); + !n2.fixed && scaleAndAdd$2(n2.p, n2.p, v12, -(1 - w) * d * friction); + } + // Gravity + for (var i = 0; i < nLen; i++) { + var n = nodes[i]; + if (!n.fixed) { + sub(v12, center, n.p); + // var d = vec2.len(v12); + // vec2.scale(v12, v12, 1 / d); + // var gravityFactor = gravity; + scaleAndAdd$2(n.p, n.p, v12, gravity * friction); + } + } + + // Repulsive + // PENDING + for (var i = 0; i < nLen; i++) { + var n1 = nodes[i]; + for (var j = i + 1; j < nLen; j++) { + var n2 = nodes[j]; + sub(v12, n2.p, n1.p); + var d = len(v12); + if (d === 0) { + // Random repulse + set(v12, Math.random() - 0.5, Math.random() - 0.5); + d = 1; + } + var repFact = (n1.rep + n2.rep) / d / d; + !n1.fixed && scaleAndAdd$2(n1.pp, n1.pp, v12, repFact); + !n2.fixed && scaleAndAdd$2(n2.pp, n2.pp, v12, -repFact); + } + } + var v = []; + for (var i = 0; i < nLen; i++) { + var n = nodes[i]; + if (!n.fixed) { + sub(v, n.p, n.pp); + scaleAndAdd$2(n.p, n.p, v, friction); + copy(n.pp, n.p); + } + } + + friction = friction * 0.992; + + cb && cb(nodes, edges, friction < 0.01); + } + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var forceLayout = function(ecModel) { + ecModel.eachSeriesByType('graph', function(graphSeries) { + var coordSys = graphSeries.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + if (graphSeries.get('layout') === 'force') { + var preservedPoints = graphSeries.preservedPoints || {}; + var graph = graphSeries.getGraph(); + var nodeData = graph.data; + var edgeData = graph.edgeData; + var forceModel = graphSeries.getModel('force'); + var initLayout = forceModel.get('initLayout'); + if (graphSeries.preservedPoints) { + nodeData.each(function(idx) { + var id = nodeData.getId(idx); + nodeData.setItemLayout(idx, preservedPoints[id] || [NaN, NaN]); + }); + } else if (!initLayout || initLayout === 'none') { + simpleLayout$1(graphSeries); + } else if (initLayout === 'circular') { + circularLayout$1(graphSeries); + } + + var nodeDataExtent = nodeData.getDataExtent('value'); + var edgeDataExtent = edgeData.getDataExtent('value'); + // var edgeDataExtent = edgeData.getDataExtent('value'); + var repulsion = forceModel.get('repulsion'); + var edgeLength = forceModel.get('edgeLength'); + if (!isArray(repulsion)) { + repulsion = [repulsion, repulsion]; + } + if (!isArray(edgeLength)) { + edgeLength = [edgeLength, edgeLength]; + } + // Larger value has smaller length + edgeLength = [edgeLength[1], edgeLength[0]]; + + var nodes = nodeData.mapArray('value', function(value, idx) { + var point = nodeData.getItemLayout(idx); + var rep = linearMap(value, nodeDataExtent, repulsion); + if (isNaN(rep)) { + rep = (repulsion[0] + repulsion[1]) / 2; + } + return { + w: rep, + rep: rep, + fixed: nodeData.getItemModel(idx).get('fixed'), + p: (!point || isNaN(point[0]) || isNaN(point[1])) ? null : point + }; + }); + var edges = edgeData.mapArray('value', function(value, idx) { + var edge = graph.getEdgeByIndex(idx); + var d = linearMap(value, edgeDataExtent, edgeLength); + if (isNaN(d)) { + d = (edgeLength[0] + edgeLength[1]) / 2; + } + return { + n1: nodes[edge.node1.dataIndex], + n2: nodes[edge.node2.dataIndex], + d: d, + curveness: edge.getModel().get('lineStyle.curveness') || 0 + }; + }); + + var coordSys = graphSeries.coordinateSystem; + var rect = coordSys.getBoundingRect(); + var forceInstance = forceLayout$1(nodes, edges, { + rect: rect, + gravity: forceModel.get('gravity') + }); + var oldStep = forceInstance.step; + forceInstance.step = function(cb) { + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i].fixed) { + // Write back to layout instance + copy(nodes[i].p, graph.getNodeByIndex(i).getLayout()); + } + } + oldStep(function(nodes, edges, stopped) { + for (var i = 0, l = nodes.length; i < l; i++) { + if (!nodes[i].fixed) { + graph.getNodeByIndex(i).setLayout(nodes[i].p); + } + preservedPoints[nodeData.getId(i)] = nodes[i].p; + } + for (var i = 0, l = edges.length; i < l; i++) { + var e = edges[i]; + var edge = graph.getEdgeByIndex(i); + var p1 = e.n1.p; + var p2 = e.n2.p; + var points = edge.getLayout(); + points = points ? points.slice() : []; + points[0] = points[0] || []; + points[1] = points[1] || []; + copy(points[0], p1); + copy(points[1], p2); + if (+e.curveness) { + points[2] = [ + (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness, + (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness + ]; + } + edge.setLayout(points); + } + // Update layout + + cb && cb(stopped); + }); + }; + graphSeries.forceLayout = forceInstance; + graphSeries.preservedPoints = preservedPoints; + + // Step to get the layout + forceInstance.step(); + } else { + // Remove prev injected forceLayout instance + graphSeries.forceLayout = null; + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME Where to create the simple view coordinate system + function getViewRect$1(seriesModel, api, aspect) { + var option = seriesModel.getBoxLayoutParams(); + option.aspect = aspect; + return getLayoutRect(option, { + width: api.getWidth(), + height: api.getHeight() + }); + } + + var createView = function(ecModel, api) { + var viewList = []; + ecModel.eachSeriesByType('graph', function(seriesModel) { + var coordSysType = seriesModel.get('coordinateSystem'); + if (!coordSysType || coordSysType === 'view') { + + var data = seriesModel.getData(); + var positions = data.mapArray(function(idx) { + var itemModel = data.getItemModel(idx); + return [+itemModel.get('x'), +itemModel.get('y')]; + }); + + var min = []; + var max = []; + + fromPoints(positions, min, max); + + // If width or height is 0 + if (max[0] - min[0] === 0) { + max[0] += 1; + min[0] -= 1; + } + if (max[1] - min[1] === 0) { + max[1] += 1; + min[1] -= 1; + } + var aspect = (max[0] - min[0]) / (max[1] - min[1]); + // FIXME If get view rect after data processed? + var viewRect = getViewRect$1(seriesModel, api, aspect); + // Position may be NaN, use view rect instead + if (isNaN(aspect)) { + min = [viewRect.x, viewRect.y]; + max = [viewRect.x + viewRect.width, viewRect.y + viewRect.height]; + } + + var bbWidth = max[0] - min[0]; + var bbHeight = max[1] - min[1]; + + var viewWidth = viewRect.width; + var viewHeight = viewRect.height; + + var viewCoordSys = seriesModel.coordinateSystem = new View(); + viewCoordSys.zoomLimit = seriesModel.get('scaleLimit'); + + viewCoordSys.setBoundingRect( + min[0], min[1], bbWidth, bbHeight + ); + viewCoordSys.setViewRect( + viewRect.x, viewRect.y, viewWidth, viewHeight + ); + + // Update roam info + viewCoordSys.setCenter(seriesModel.get('center')); + viewCoordSys.setZoom(seriesModel.get('zoom')); + + viewList.push(viewCoordSys); + } + }); + + return viewList; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerProcessor(categoryFilter); + + registerVisual(visualSymbol('graph', 'circle', null)); + registerVisual(categoryVisual); + registerVisual(edgeVisual); + + registerLayout(simpleLayout); + registerLayout(circularLayout); + registerLayout(forceLayout); + + // Graph view coordinate system + registerCoordinateSystem('graphView', { + create: createView + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var GaugeSeries = SeriesModel.extend({ + + type: 'series.gauge', + + getInitialData: function(option, ecModel) { + var dataOpt = option.data || []; + if (!isArray(dataOpt)) { + dataOpt = [dataOpt]; + } + option.data = dataOpt; + return createListSimply(this, ['value']); + }, + + defaultOption: { + zlevel: 0, + z: 2, + // 默认全局居中 + center: ['50%', '50%'], + legendHoverLink: true, + radius: '75%', + startAngle: 225, + endAngle: -45, + clockwise: true, + // 最小值 + min: 0, + // 最大值 + max: 100, + // 分割段数,默认为10 + splitNumber: 10, + // 坐标轴线 + axisLine: { + // 默认显示,属性show控制显示与否 + show: true, + lineStyle: { // 属性lineStyle控制线条样式 + color: [ + [0.2, '#91c7ae'], + [0.8, '#63869e'], + [1, '#c23531'] + ], + width: 30 + } + }, + // 分隔线 + splitLine: { + // 默认显示,属性show控制显示与否 + show: true, + // 属性length控制线长 + length: 30, + // 属性lineStyle(详见lineStyle)控制线条样式 + lineStyle: { + color: '#eee', + width: 2, + type: 'solid' + } + }, + // 坐标轴小标记 + axisTick: { + // 属性show控制显示与否,默认不显示 + show: true, + // 每份split细分多少段 + splitNumber: 5, + // 属性length控制线长 + length: 8, + // 属性lineStyle控制线条样式 + lineStyle: { + color: '#eee', + width: 1, + type: 'solid' + } + }, + axisLabel: { + show: true, + distance: 5, + // formatter: null, + color: 'auto' + }, + pointer: { + show: true, + length: '80%', + width: 8 + }, + itemStyle: { + color: 'auto' + }, + title: { + show: true, + // x, y,单位px + offsetCenter: [0, '-40%'], + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#333', + fontSize: 15 + }, + detail: { + show: true, + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 0, + borderColor: '#ccc', + width: 100, + height: null, // self-adaption + padding: [5, 10], + // x, y,单位px + offsetCenter: [0, '40%'], + // formatter: null, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: 'auto', + fontSize: 30 + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PointerPath = Path.extend({ + + type: 'echartsGaugePointer', + + shape: { + angle: 0, + + width: 10, + + r: 10, + + x: 0, + + y: 0 + }, + + buildPath: function(ctx, shape) { + var mathCos = Math.cos; + var mathSin = Math.sin; + + var r = shape.r; + var width = shape.width; + var angle = shape.angle; + var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2); + var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2); + + angle = shape.angle - Math.PI / 2; + ctx.moveTo(x, y); + ctx.lineTo( + shape.x + mathCos(angle) * width, + shape.y + mathSin(angle) * width + ); + ctx.lineTo( + shape.x + mathCos(shape.angle) * r, + shape.y + mathSin(shape.angle) * r + ); + ctx.lineTo( + shape.x - mathCos(angle) * width, + shape.y - mathSin(angle) * width + ); + ctx.lineTo(x, y); + return; + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function parsePosition(seriesModel, api) { + var center = seriesModel.get('center'); + var width = api.getWidth(); + var height = api.getHeight(); + var size = Math.min(width, height); + var cx = parsePercent$1(center[0], api.getWidth()); + var cy = parsePercent$1(center[1], api.getHeight()); + var r = parsePercent$1(seriesModel.get('radius'), size / 2); + + return { + cx: cx, + cy: cy, + r: r + }; + } + + function formatLabel(label, labelFormatter) { + if (labelFormatter) { + if (typeof labelFormatter === 'string') { + label = labelFormatter.replace('{value}', label != null ? label : ''); + } else if (typeof labelFormatter === 'function') { + label = labelFormatter(label); + } + } + + return label; + } + + var PI2$5 = Math.PI * 2; + + var GaugeView = Chart.extend({ + + type: 'gauge', + + render: function(seriesModel, ecModel, api) { + + this.group.removeAll(); + + var colorList = seriesModel.get('axisLine.lineStyle.color'); + var posInfo = parsePosition(seriesModel, api); + + this._renderMain( + seriesModel, ecModel, api, colorList, posInfo + ); + }, + + dispose: function() {}, + + _renderMain: function(seriesModel, ecModel, api, colorList, posInfo) { + var group = this.group; + + var axisLineModel = seriesModel.getModel('axisLine'); + var lineStyleModel = axisLineModel.getModel('lineStyle'); + + var clockwise = seriesModel.get('clockwise'); + var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI; + var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI; + + var angleRangeSpan = (endAngle - startAngle) % PI2$5; + + var prevEndAngle = startAngle; + var axisLineWidth = lineStyleModel.get('width'); + + for (var i = 0; i < colorList.length; i++) { + // Clamp + var percent = Math.min(Math.max(colorList[i][0], 0), 1); + var endAngle = startAngle + angleRangeSpan * percent; + var sector = new Sector({ + shape: { + startAngle: prevEndAngle, + endAngle: endAngle, + cx: posInfo.cx, + cy: posInfo.cy, + clockwise: clockwise, + r0: posInfo.r - axisLineWidth, + r: posInfo.r + }, + silent: true + }); + + sector.setStyle({ + fill: colorList[i][1] + }); + + sector.setStyle(lineStyleModel.getLineStyle( + // Because we use sector to simulate arc + // so the properties for stroking are useless + ['color', 'borderWidth', 'borderColor'] + )); + + group.add(sector); + + prevEndAngle = endAngle; + } + + var getColor = function(percent) { + // Less than 0 + if (percent <= 0) { + return colorList[0][1]; + } + for (var i = 0; i < colorList.length; i++) { + if (colorList[i][0] >= percent && + (i === 0 ? 0 : colorList[i - 1][0]) < percent + ) { + return colorList[i][1]; + } + } + // More than 1 + return colorList[i - 1][1]; + }; + + if (!clockwise) { + var tmp = startAngle; + startAngle = endAngle; + endAngle = tmp; + } + + this._renderTicks( + seriesModel, ecModel, api, getColor, posInfo, + startAngle, endAngle, clockwise + ); + + this._renderPointer( + seriesModel, ecModel, api, getColor, posInfo, + startAngle, endAngle, clockwise + ); + + this._renderTitle( + seriesModel, ecModel, api, getColor, posInfo + ); + this._renderDetail( + seriesModel, ecModel, api, getColor, posInfo + ); + }, + + _renderTicks: function( + seriesModel, ecModel, api, getColor, posInfo, + startAngle, endAngle, clockwise + ) { + var group = this.group; + var cx = posInfo.cx; + var cy = posInfo.cy; + var r = posInfo.r; + + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + + var splitLineModel = seriesModel.getModel('splitLine'); + var tickModel = seriesModel.getModel('axisTick'); + var labelModel = seriesModel.getModel('axisLabel'); + + var splitNumber = seriesModel.get('splitNumber'); + var subSplitNumber = tickModel.get('splitNumber'); + + var splitLineLen = parsePercent$1( + splitLineModel.get('length'), r + ); + var tickLen = parsePercent$1( + tickModel.get('length'), r + ); + + var angle = startAngle; + var step = (endAngle - startAngle) / splitNumber; + var subStep = step / subSplitNumber; + + var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle(); + var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle(); + + for (var i = 0; i <= splitNumber; i++) { + var unitX = Math.cos(angle); + var unitY = Math.sin(angle); + // Split line + if (splitLineModel.get('show')) { + var splitLine = new Line({ + shape: { + x1: unitX * r + cx, + y1: unitY * r + cy, + x2: unitX * (r - splitLineLen) + cx, + y2: unitY * (r - splitLineLen) + cy + }, + style: splitLineStyle, + silent: true + }); + if (splitLineStyle.stroke === 'auto') { + splitLine.setStyle({ + stroke: getColor(i / splitNumber) + }); + } + + group.add(splitLine); + } + + // Label + if (labelModel.get('show')) { + var label = formatLabel( + round$1(i / splitNumber * (maxVal - minVal) + minVal), + labelModel.get('formatter') + ); + var distance = labelModel.get('distance'); + var autoColor = getColor(i / splitNumber); + + group.add(new Text({ + style: setTextStyle({}, labelModel, { + text: label, + x: unitX * (r - splitLineLen - distance) + cx, + y: unitY * (r - splitLineLen - distance) + cy, + textVerticalAlign: unitY < -0.4 ? 'top' : (unitY > 0.4 ? 'bottom' : 'middle'), + textAlign: unitX < -0.4 ? 'left' : (unitX > 0.4 ? 'right' : 'center') + }, { + autoColor: autoColor + }), + silent: true + })); + } + + // Axis tick + if (tickModel.get('show') && i !== splitNumber) { + for (var j = 0; j <= subSplitNumber; j++) { + var unitX = Math.cos(angle); + var unitY = Math.sin(angle); + var tickLine = new Line({ + shape: { + x1: unitX * r + cx, + y1: unitY * r + cy, + x2: unitX * (r - tickLen) + cx, + y2: unitY * (r - tickLen) + cy + }, + silent: true, + style: tickLineStyle + }); + + if (tickLineStyle.stroke === 'auto') { + tickLine.setStyle({ + stroke: getColor((i + j / subSplitNumber) / splitNumber) + }); + } + + group.add(tickLine); + angle += subStep; + } + angle -= subStep; + } else { + angle += step; + } + } + }, + + _renderPointer: function( + seriesModel, ecModel, api, getColor, posInfo, + startAngle, endAngle, clockwise + ) { + + var group = this.group; + var oldData = this._data; + + if (!seriesModel.get('pointer.show')) { + // Remove old element + oldData && oldData.eachItemGraphicEl(function(el) { + group.remove(el); + }); + return; + } + + var valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')]; + var angleExtent = [startAngle, endAngle]; + + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + + data.diff(oldData) + .add(function(idx) { + var pointer = new PointerPath({ + shape: { + angle: startAngle + } + }); + + initProps(pointer, { + shape: { + angle: linearMap(data.get(valueDim, idx), valueExtent, angleExtent, true) + } + }, seriesModel); + + group.add(pointer); + data.setItemGraphicEl(idx, pointer); + }) + .update(function(newIdx, oldIdx) { + var pointer = oldData.getItemGraphicEl(oldIdx); + + updateProps(pointer, { + shape: { + angle: linearMap(data.get(valueDim, newIdx), valueExtent, angleExtent, true) + } + }, seriesModel); + + group.add(pointer); + data.setItemGraphicEl(newIdx, pointer); + }) + .remove(function(idx) { + var pointer = oldData.getItemGraphicEl(idx); + group.remove(pointer); + }) + .execute(); + + data.eachItemGraphicEl(function(pointer, idx) { + var itemModel = data.getItemModel(idx); + var pointerModel = itemModel.getModel('pointer'); + + pointer.setShape({ + x: posInfo.cx, + y: posInfo.cy, + width: parsePercent$1( + pointerModel.get('width'), posInfo.r + ), + r: parsePercent$1(pointerModel.get('length'), posInfo.r) + }); + + pointer.useStyle(itemModel.getModel('itemStyle').getItemStyle()); + + if (pointer.style.fill === 'auto') { + pointer.setStyle('fill', getColor( + linearMap(data.get(valueDim, idx), valueExtent, [0, 1], true) + )); + } + + setHoverStyle( + pointer, itemModel.getModel('emphasis.itemStyle').getItemStyle() + ); + }); + + this._data = data; + }, + + _renderTitle: function( + seriesModel, ecModel, api, getColor, posInfo + ) { + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var titleModel = seriesModel.getModel('title'); + if (titleModel.get('show')) { + var offsetCenter = titleModel.get('offsetCenter'); + var x = posInfo.cx + parsePercent$1(offsetCenter[0], posInfo.r); + var y = posInfo.cy + parsePercent$1(offsetCenter[1], posInfo.r); + + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + var value = seriesModel.getData().get(valueDim, 0); + var autoColor = getColor( + linearMap(value, [minVal, maxVal], [0, 1], true) + ); + + this.group.add(new Text({ + silent: true, + style: setTextStyle({}, titleModel, { + x: x, + y: y, + // FIXME First data name ? + text: data.getName(0), + textAlign: 'center', + textVerticalAlign: 'middle' + }, { + autoColor: autoColor, + forceRich: true + }) + })); + } + }, + + _renderDetail: function( + seriesModel, ecModel, api, getColor, posInfo + ) { + var detailModel = seriesModel.getModel('detail'); + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + if (detailModel.get('show')) { + var offsetCenter = detailModel.get('offsetCenter'); + var x = posInfo.cx + parsePercent$1(offsetCenter[0], posInfo.r); + var y = posInfo.cy + parsePercent$1(offsetCenter[1], posInfo.r); + var width = parsePercent$1(detailModel.get('width'), posInfo.r); + var height = parsePercent$1(detailModel.get('height'), posInfo.r); + var data = seriesModel.getData(); + var value = data.get(data.mapDimension('value'), 0); + var autoColor = getColor( + linearMap(value, [minVal, maxVal], [0, 1], true) + ); + + this.group.add(new Text({ + silent: true, + style: setTextStyle({}, detailModel, { + x: x, + y: y, + text: formatLabel( + // FIXME First data name ? + value, detailModel.get('formatter') + ), + textWidth: isNaN(width) ? null : width, + textHeight: isNaN(height) ? null : height, + textAlign: 'center', + textVerticalAlign: 'middle' + }, { + autoColor: autoColor, + forceRich: true + }) + })); + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var FunnelSeries = extendSeriesModel({ + + type: 'series.funnel', + + init: function(option) { + FunnelSeries.superApply(this, 'init', arguments); + + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendDataProvider = function() { + return this.getRawData(); + }; + // Extend labelLine emphasis + this._defaultLabelLine(option); + }, + + getInitialData: function(option, ecModel) { + return createListSimply(this, ['value']); + }, + + _defaultLabelLine: function(option) { + // Extend labelLine emphasis + defaultEmphasis(option, 'labelLine', ['show']); + + var labelLineNormalOpt = option.labelLine; + var labelLineEmphasisOpt = option.emphasis.labelLine; + // Not show label line if `label.normal.show = false` + labelLineNormalOpt.show = labelLineNormalOpt.show && + option.label.show; + labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && + option.emphasis.label.show; + }, + + // Overwrite + getDataParams: function(dataIndex) { + var data = this.getData(); + var params = FunnelSeries.superCall(this, 'getDataParams', dataIndex); + var valueDim = data.mapDimension('value'); + var sum = data.getSum(valueDim); + // Percent is 0 if sum is 0 + params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) / sum * 100).toFixed(2); + + params.$vars.push('percent'); + return params; + }, + + defaultOption: { + zlevel: 0, // 一级层叠 + z: 2, // 二级层叠 + legendHoverLink: true, + left: 80, + top: 60, + right: 80, + bottom: 60, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + + // 默认取数据最小最大值 + // min: 0, + // max: 100, + minSize: '0%', + maxSize: '100%', + sort: 'descending', // 'ascending', 'descending' + gap: 0, + funnelAlign: 'center', + label: { + show: true, + position: 'outer' + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + }, + labelLine: { + show: true, + length: 20, + lineStyle: { + // color: 各异, + width: 1, + type: 'solid' + } + }, + itemStyle: { + // color: 各异, + borderColor: '#fff', + borderWidth: 1 + }, + emphasis: { + label: { + show: true + } + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Piece of pie including Sector, Label, LabelLine + * @constructor + * @extends {module:zrender/graphic/Group} + */ + function FunnelPiece(data, idx) { + + Group.call(this); + + var polygon = new Polygon(); + var labelLine = new Polyline(); + var text = new Text(); + this.add(polygon); + this.add(labelLine); + this.add(text); + + this.updateData(data, idx, true); + + // Hover to change label and labelLine + function onEmphasis() { + labelLine.ignore = labelLine.hoverIgnore; + text.ignore = text.hoverIgnore; + } + + function onNormal() { + labelLine.ignore = labelLine.normalIgnore; + text.ignore = text.normalIgnore; + } + this.on('emphasis', onEmphasis) + .on('normal', onNormal) + .on('mouseover', onEmphasis) + .on('mouseout', onNormal); + } + + var funnelPieceProto = FunnelPiece.prototype; + + var opacityAccessPath = ['itemStyle', 'opacity']; + funnelPieceProto.updateData = function(data, idx, firstCreate) { + + var polygon = this.childAt(0); + + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var opacity = data.getItemModel(idx).get(opacityAccessPath); + opacity = opacity == null ? 1 : opacity; + + // Reset style + polygon.useStyle({}); + + if (firstCreate) { + polygon.setShape({ + points: layout.points + }); + polygon.setStyle({ + opacity: 0 + }); + initProps(polygon, { + style: { + opacity: opacity + } + }, seriesModel, idx); + } else { + updateProps(polygon, { + style: { + opacity: opacity + }, + shape: { + points: layout.points + } + }, seriesModel, idx); + } + + // Update common style + var itemStyleModel = itemModel.getModel('itemStyle'); + var visualColor = data.getItemVisual(idx, 'color'); + + polygon.setStyle( + defaults({ + lineJoin: 'round', + fill: visualColor + }, + itemStyleModel.getItemStyle(['opacity']) + ) + ); + polygon.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle(); + + this._updateLabel(data, idx); + + setHoverStyle(this); + }; + + funnelPieceProto._updateLabel = function(data, idx) { + + var labelLine = this.childAt(1); + var labelText = this.childAt(2); + + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var labelLayout = layout.label; + var visualColor = data.getItemVisual(idx, 'color'); + + updateProps(labelLine, { + shape: { + points: labelLayout.linePoints || labelLayout.linePoints + } + }, seriesModel, idx); + + updateProps(labelText, { + style: { + x: labelLayout.x, + y: labelLayout.y + } + }, seriesModel, idx); + labelText.attr({ + rotation: labelLayout.rotation, + origin: [labelLayout.x, labelLayout.y], + z2: 10 + }); + + var labelModel = itemModel.getModel('label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + var labelLineModel = itemModel.getModel('labelLine'); + var labelLineHoverModel = itemModel.getModel('emphasis.labelLine'); + var visualColor = data.getItemVisual(idx, 'color'); + + setLabelStyle( + labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel, { + labelFetcher: data.hostModel, + labelDataIndex: idx, + defaultText: data.getName(idx), + autoColor: visualColor, + useInsideStyle: !!labelLayout.inside + }, { + textAlign: labelLayout.textAlign, + textVerticalAlign: labelLayout.verticalAlign + } + ); + + labelText.ignore = labelText.normalIgnore = !labelModel.get('show'); + labelText.hoverIgnore = !labelHoverModel.get('show'); + + labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show'); + labelLine.hoverIgnore = !labelLineHoverModel.get('show'); + + // Default use item visual color + labelLine.setStyle({ + stroke: visualColor + }); + labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle()); + + labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle(); + }; + + inherits(FunnelPiece, Group); + + + var FunnelView = Chart.extend({ + + type: 'funnel', + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var oldData = this._data; + + var group = this.group; + + data.diff(oldData) + .add(function(idx) { + var funnelPiece = new FunnelPiece(data, idx); + + data.setItemGraphicEl(idx, funnelPiece); + + group.add(funnelPiece); + }) + .update(function(newIdx, oldIdx) { + var piePiece = oldData.getItemGraphicEl(oldIdx); + + piePiece.updateData(data, newIdx); + + group.add(piePiece); + data.setItemGraphicEl(newIdx, piePiece); + }) + .remove(function(idx) { + var piePiece = oldData.getItemGraphicEl(idx); + group.remove(piePiece); + }) + .execute(); + + this._data = data; + }, + + remove: function() { + this.group.removeAll(); + this._data = null; + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function getViewRect$2(seriesModel, api) { + return getLayoutRect( + seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + } + + function getSortedIndices(data, sort) { + var valueDim = data.mapDimension('value'); + var valueArr = data.mapArray(valueDim, function(val) { + return val; + }); + var indices = []; + var isAscending = sort === 'ascending'; + for (var i = 0, len = data.count(); i < len; i++) { + indices[i] = i; + } + + // Add custom sortable function & none sortable opetion by "options.sort" + if (typeof sort === 'function') { + indices.sort(sort); + } else if (sort !== 'none') { + indices.sort(function(a, b) { + return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a]; + }); + } + return indices; + } + + function labelLayout$1(data) { + data.each(function(idx) { + var itemModel = data.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + var labelPosition = labelModel.get('position'); + + var labelLineModel = itemModel.getModel('labelLine'); + + var layout = data.getItemLayout(idx); + var points = layout.points; + + var isLabelInside = labelPosition === 'inner' || + labelPosition === 'inside' || labelPosition === 'center'; + + var textAlign; + var textX; + var textY; + var linePoints; + + if (isLabelInside) { + textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4; + textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4; + textAlign = 'center'; + linePoints = [ + [textX, textY], + [textX, textY] + ]; + } else { + var x1; + var y1; + var x2; + var labelLineLen = labelLineModel.get('length'); + if (labelPosition === 'left') { + // Left side + x1 = (points[3][0] + points[0][0]) / 2; + y1 = (points[3][1] + points[0][1]) / 2; + x2 = x1 - labelLineLen; + textX = x2 - 5; + textAlign = 'right'; + } else { + // Right side + x1 = (points[1][0] + points[2][0]) / 2; + y1 = (points[1][1] + points[2][1]) / 2; + x2 = x1 + labelLineLen; + textX = x2 + 5; + textAlign = 'left'; + } + var y2 = y1; + + linePoints = [ + [x1, y1], + [x2, y2] + ]; + textY = y2; + } + + layout.label = { + linePoints: linePoints, + x: textX, + y: textY, + verticalAlign: 'middle', + textAlign: textAlign, + inside: isLabelInside + }; + }); + } + + var funnelLayout = function(ecModel, api, payload) { + ecModel.eachSeriesByType('funnel', function(seriesModel) { + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var sort = seriesModel.get('sort'); + var viewRect = getViewRect$2(seriesModel, api); + var indices = getSortedIndices(data, sort); + + var sizeExtent = [ + parsePercent$1(seriesModel.get('minSize'), viewRect.width), + parsePercent$1(seriesModel.get('maxSize'), viewRect.width) + ]; + var dataExtent = data.getDataExtent(valueDim); + var min = seriesModel.get('min'); + var max = seriesModel.get('max'); + if (min == null) { + min = Math.min(dataExtent[0], 0); + } + if (max == null) { + max = dataExtent[1]; + } + + var funnelAlign = seriesModel.get('funnelAlign'); + var gap = seriesModel.get('gap'); + var itemHeight = (viewRect.height - gap * (data.count() - 1)) / data.count(); + + var y = viewRect.y; + + var getLinePoints = function(idx, offY) { + // End point index is data.count() and we assign it 0 + var val = data.get(valueDim, idx) || 0; + var itemWidth = linearMap(val, [min, max], sizeExtent, true); + var x0; + switch (funnelAlign) { + case 'left': + x0 = viewRect.x; + break; + case 'center': + x0 = viewRect.x + (viewRect.width - itemWidth) / 2; + break; + case 'right': + x0 = viewRect.x + viewRect.width - itemWidth; + break; + } + return [ + [x0, offY], + [x0 + itemWidth, offY] + ]; + }; + + if (sort === 'ascending') { + // From bottom to top + itemHeight = -itemHeight; + gap = -gap; + y += viewRect.height; + indices = indices.reverse(); + } + + for (var i = 0; i < indices.length; i++) { + var idx = indices[i]; + var nextIdx = indices[i + 1]; + + var itemModel = data.getItemModel(idx); + var height = itemModel.get('itemStyle.height'); + if (height == null) { + height = itemHeight; + } else { + height = parsePercent$1(height, viewRect.height); + if (sort === 'ascending') { + height = -height; + } + } + + var start = getLinePoints(idx, y); + var end = getLinePoints(nextIdx, y + height); + + y += height + gap; + + data.setItemLayout(idx, { + points: start.concat(end.slice().reverse()) + }); + } + + labelLayout$1(data); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(dataColor('funnel')); + registerLayout(funnelLayout); + registerProcessor(dataFilter('funnel')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var parallelPreprocessor = function(option) { + createParallelIfNeeded(option); + mergeAxisOptionFromParallel(option); + }; + + /** + * Create a parallel coordinate if not exists. + * @inner + */ + function createParallelIfNeeded(option) { + if (option.parallel) { + return; + } + + var hasParallelSeries = false; + + each$1(option.series, function(seriesOpt) { + if (seriesOpt && seriesOpt.type === 'parallel') { + hasParallelSeries = true; + } + }); + + if (hasParallelSeries) { + option.parallel = [{}]; + } + } + + /** + * Merge aixs definition from parallel option (if exists) to axis option. + * @inner + */ + function mergeAxisOptionFromParallel(option) { + var axes = normalizeToArray(option.parallelAxis); + + each$1(axes, function(axisOption) { + if (!isObject$1(axisOption)) { + return; + } + + var parallelIndex = axisOption.parallelIndex || 0; + var parallelOption = normalizeToArray(option.parallel)[parallelIndex]; + + if (parallelOption && parallelOption.parallelAxisDefault) { + merge(axisOption, parallelOption.parallelAxisDefault, false); + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @constructor module:echarts/coord/parallel/ParallelAxis + * @extends {module:echarts/coord/Axis} + * @param {string} dim + * @param {*} scale + * @param {Array.} coordExtent + * @param {string} axisType + */ + var ParallelAxis = function(dim, scale, coordExtent, axisType, axisIndex) { + + Axis.call(this, dim, scale, coordExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = axisType || 'value'; + + /** + * @type {number} + * @readOnly + */ + this.axisIndex = axisIndex; + }; + + ParallelAxis.prototype = { + + constructor: ParallelAxis, + + /** + * Axis model + * @param {module:echarts/coord/parallel/AxisModel} + */ + model: null, + + /** + * @override + */ + isHorizontal: function() { + return this.coordinateSystem.getModel().get('layout') !== 'horizontal'; + } + + }; + + inherits(ParallelAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Calculate slider move result. + * Usage: + * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as + * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`. + * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`. + * + * @param {number} delta Move length. + * @param {Array.} handleEnds handleEnds[0] can be bigger then handleEnds[1]. + * handleEnds will be modified in this method. + * @param {Array.} extent handleEnds is restricted by extent. + * extent[0] should less or equals than extent[1]. + * @param {number|string} handleIndex Can be 'all', means that both move the two handleEnds, + * where the input minSpan and maxSpan will not work. + * @param {number} [minSpan] The range of dataZoom can not be smaller than that. + * If not set, handle0 and cross handle1. If set as a non-negative + * number (including `0`), handles will push each other when reaching + * the minSpan. + * @param {number} [maxSpan] The range of dataZoom can not be larger than that. + * @return {Array.} The input handleEnds. + */ + var sliderMove = function(delta, handleEnds, extent, handleIndex, minSpan, maxSpan) { + // Normalize firstly. + handleEnds[0] = restrict$1(handleEnds[0], extent); + handleEnds[1] = restrict$1(handleEnds[1], extent); + + delta = delta || 0; + + var extentSpan = extent[1] - extent[0]; + + // Notice maxSpan and minSpan can be null/undefined. + if (minSpan != null) { + minSpan = restrict$1(minSpan, [0, extentSpan]); + } + if (maxSpan != null) { + maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0); + } + if (handleIndex === 'all') { + minSpan = maxSpan = Math.abs(handleEnds[1] - handleEnds[0]); + handleIndex = 0; + } + + var originalDistSign = getSpanSign(handleEnds, handleIndex); + + handleEnds[handleIndex] += delta; + + // Restrict in extent. + var extentMinSpan = minSpan || 0; + var realExtent = extent.slice(); + originalDistSign.sign < 0 ? (realExtent[0] += extentMinSpan) : (realExtent[1] -= extentMinSpan); + handleEnds[handleIndex] = restrict$1(handleEnds[handleIndex], realExtent); + + // Expand span. + var currDistSign = getSpanSign(handleEnds, handleIndex); + if (minSpan != null && ( + currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan + )) { + // If minSpan exists, 'cross' is forbinden. + handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan; + } + + // Shrink span. + var currDistSign = getSpanSign(handleEnds, handleIndex); + if (maxSpan != null && currDistSign.span > maxSpan) { + handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan; + } + + return handleEnds; + }; + + function getSpanSign(handleEnds, handleIndex) { + var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex]; + // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0] + // is at left of handleEnds[1] for non-cross case. + return { + span: Math.abs(dist), + sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1 + }; + } + + function restrict$1(value, extend) { + return Math.min(extend[1], Math.max(extend[0], value)); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Parallel Coordinates + * + */ + + var each$11 = each$1; + var mathMin$5 = Math.min; + var mathMax$5 = Math.max; + var mathFloor$2 = Math.floor; + var mathCeil$2 = Math.ceil; + var round$2 = round$1; + + var PI$3 = Math.PI; + + function Parallel(parallelModel, ecModel, api) { + + /** + * key: dimension + * @type {Object.} + * @private + */ + this._axesMap = createHashMap(); + + /** + * key: dimension + * value: {position: [], rotation, } + * @type {Object.} + * @private + */ + this._axesLayout = {}; + + /** + * Always follow axis order. + * @type {Array.} + * @readOnly + */ + this.dimensions = parallelModel.dimensions; + + /** + * @type {module:zrender/core/BoundingRect} + */ + this._rect; + + /** + * @type {module:echarts/coord/parallel/ParallelModel} + */ + this._model = parallelModel; + + this._init(parallelModel, ecModel, api); + } + + Parallel.prototype = { + + type: 'parallel', + + constructor: Parallel, + + /** + * Initialize cartesian coordinate systems + * @private + */ + _init: function(parallelModel, ecModel, api) { + + var dimensions = parallelModel.dimensions; + var parallelAxisIndex = parallelModel.parallelAxisIndex; + + each$11(dimensions, function(dim, idx) { + + var axisIndex = parallelAxisIndex[idx]; + var axisModel = ecModel.getComponent('parallelAxis', axisIndex); + + var axis = this._axesMap.set(dim, new ParallelAxis( + dim, + createScaleByModel(axisModel), + [0, 0], + axisModel.get('type'), + axisIndex + )); + + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + + // Injection + axisModel.axis = axis; + axis.model = axisModel; + axis.coordinateSystem = axisModel.coordinateSystem = this; + + }, this); + }, + + /** + * Update axis scale after data processed + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + update: function(ecModel, api) { + this._updateAxesFromSeries(this._model, ecModel); + }, + + /** + * @override + */ + containPoint: function(point) { + var layoutInfo = this._makeLayoutInfo(); + var axisBase = layoutInfo.axisBase; + var layoutBase = layoutInfo.layoutBase; + var pixelDimIndex = layoutInfo.pixelDimIndex; + var pAxis = point[1 - pixelDimIndex]; + var pLayout = point[pixelDimIndex]; + + return pAxis >= axisBase && + pAxis <= axisBase + layoutInfo.axisLength && + pLayout >= layoutBase && + pLayout <= layoutBase + layoutInfo.layoutLength; + }, + + getModel: function() { + return this._model; + }, + + /** + * Update properties from series + * @private + */ + _updateAxesFromSeries: function(parallelModel, ecModel) { + ecModel.eachSeries(function(seriesModel) { + + if (!parallelModel.contains(seriesModel, ecModel)) { + return; + } + + var data = seriesModel.getData(); + + each$11(this.dimensions, function(dim) { + var axis = this._axesMap.get(dim); + axis.scale.unionExtentFromData(data, data.mapDimension(dim)); + niceScaleExtent(axis.scale, axis.model); + }, this); + }, this); + }, + + /** + * Resize the parallel coordinate system. + * @param {module:echarts/coord/parallel/ParallelModel} parallelModel + * @param {module:echarts/ExtensionAPI} api + */ + resize: function(parallelModel, api) { + this._rect = getLayoutRect( + parallelModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + + this._layoutAxes(); + }, + + /** + * @return {module:zrender/core/BoundingRect} + */ + getRect: function() { + return this._rect; + }, + + /** + * @private + */ + _makeLayoutInfo: function() { + var parallelModel = this._model; + var rect = this._rect; + var xy = ['x', 'y']; + var wh = ['width', 'height']; + var layout = parallelModel.get('layout'); + var pixelDimIndex = layout === 'horizontal' ? 0 : 1; + var layoutLength = rect[wh[pixelDimIndex]]; + var layoutExtent = [0, layoutLength]; + var axisCount = this.dimensions.length; + + var axisExpandWidth = restrict(parallelModel.get('axisExpandWidth'), layoutExtent); + var axisExpandCount = restrict(parallelModel.get('axisExpandCount') || 0, [0, axisCount]); + var axisExpandable = parallelModel.get('axisExpandable') && + axisCount > 3 && + axisCount > axisExpandCount && + axisExpandCount > 1 && + axisExpandWidth > 0 && + layoutLength > 0; + + // `axisExpandWindow` is According to the coordinates of [0, axisExpandLength], + // for sake of consider the case that axisCollapseWidth is 0 (when screen is narrow), + // where collapsed axes should be overlapped. + var axisExpandWindow = parallelModel.get('axisExpandWindow'); + var winSize; + if (!axisExpandWindow) { + winSize = restrict(axisExpandWidth * (axisExpandCount - 1), layoutExtent); + var axisExpandCenter = parallelModel.get('axisExpandCenter') || mathFloor$2(axisCount / 2); + axisExpandWindow = [axisExpandWidth * axisExpandCenter - winSize / 2]; + axisExpandWindow[1] = axisExpandWindow[0] + winSize; + } else { + winSize = restrict(axisExpandWindow[1] - axisExpandWindow[0], layoutExtent); + axisExpandWindow[1] = axisExpandWindow[0] + winSize; + } + + var axisCollapseWidth = (layoutLength - winSize) / (axisCount - axisExpandCount); + // Avoid axisCollapseWidth is too small. + axisCollapseWidth < 3 && (axisCollapseWidth = 0); + + // Find the first and last indices > ewin[0] and < ewin[1]. + var winInnerIndices = [ + mathFloor$2(round$2(axisExpandWindow[0] / axisExpandWidth, 1)) + 1, + mathCeil$2(round$2(axisExpandWindow[1] / axisExpandWidth, 1)) - 1 + ]; + + // Pos in ec coordinates. + var axisExpandWindow0Pos = axisCollapseWidth / axisExpandWidth * axisExpandWindow[0]; + + return { + layout: layout, + pixelDimIndex: pixelDimIndex, + layoutBase: rect[xy[pixelDimIndex]], + layoutLength: layoutLength, + axisBase: rect[xy[1 - pixelDimIndex]], + axisLength: rect[wh[1 - pixelDimIndex]], + axisExpandable: axisExpandable, + axisExpandWidth: axisExpandWidth, + axisCollapseWidth: axisCollapseWidth, + axisExpandWindow: axisExpandWindow, + axisCount: axisCount, + winInnerIndices: winInnerIndices, + axisExpandWindow0Pos: axisExpandWindow0Pos + }; + }, + + /** + * @private + */ + _layoutAxes: function() { + var rect = this._rect; + var axes = this._axesMap; + var dimensions = this.dimensions; + var layoutInfo = this._makeLayoutInfo(); + var layout = layoutInfo.layout; + + axes.each(function(axis) { + var axisExtent = [0, layoutInfo.axisLength]; + var idx = axis.inverse ? 1 : 0; + axis.setExtent(axisExtent[idx], axisExtent[1 - idx]); + }); + + each$11(dimensions, function(dim, idx) { + var posInfo = (layoutInfo.axisExpandable ? + layoutAxisWithExpand : layoutAxisWithoutExpand + )(idx, layoutInfo); + + var positionTable = { + horizontal: { + x: posInfo.position, + y: layoutInfo.axisLength + }, + vertical: { + x: 0, + y: posInfo.position + } + }; + var rotationTable = { + horizontal: PI$3 / 2, + vertical: 0 + }; + + var position = [ + positionTable[layout].x + rect.x, + positionTable[layout].y + rect.y + ]; + + var rotation = rotationTable[layout]; + var transform = create$1(); + rotate(transform, transform, rotation); + translate(transform, transform, position); + + // TODO + // tick等排布信息。 + + // TODO + // 根据axis order 更新 dimensions顺序。 + + this._axesLayout[dim] = { + position: position, + rotation: rotation, + transform: transform, + axisNameAvailableWidth: posInfo.axisNameAvailableWidth, + axisLabelShow: posInfo.axisLabelShow, + nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth, + tickDirection: 1, + labelDirection: 1 + }; + }, this); + }, + + /** + * Get axis by dim. + * @param {string} dim + * @return {module:echarts/coord/parallel/ParallelAxis} [description] + */ + getAxis: function(dim) { + return this._axesMap.get(dim); + }, + + /** + * Convert a dim value of a single item of series data to Point. + * @param {*} value + * @param {string} dim + * @return {Array} + */ + dataToPoint: function(value, dim) { + return this.axisCoordToPoint( + this._axesMap.get(dim).dataToCoord(value), + dim + ); + }, + + /** + * Travel data for one time, get activeState of each data item. + * @param {module:echarts/data/List} data + * @param {Functio} cb param: {string} activeState 'active' or 'inactive' or 'normal' + * {number} dataIndex + * @param {number} [start=0] the start dataIndex that travel from. + * @param {number} [end=data.count()] the next dataIndex of the last dataIndex will be travel. + */ + eachActiveState: function(data, callback, start, end) { + start == null && (start = 0); + end == null && (end = data.count()); + + var axesMap = this._axesMap; + var dimensions = this.dimensions; + var dataDimensions = []; + var axisModels = []; + + each$1(dimensions, function(axisDim) { + dataDimensions.push(data.mapDimension(axisDim)); + axisModels.push(axesMap.get(axisDim).model); + }); + + var hasActiveSet = this.hasAxisBrushed(); + + for (var dataIndex = start; dataIndex < end; dataIndex++) { + var activeState; + + if (!hasActiveSet) { + activeState = 'normal'; + } else { + activeState = 'active'; + var values = data.getValues(dataDimensions, dataIndex); + for (var j = 0, lenj = dimensions.length; j < lenj; j++) { + var state = axisModels[j].getActiveState(values[j]); + + if (state === 'inactive') { + activeState = 'inactive'; + break; + } + } + } + + callback(activeState, dataIndex); + } + }, + + /** + * Whether has any activeSet. + * @return {boolean} + */ + hasAxisBrushed: function() { + var dimensions = this.dimensions; + var axesMap = this._axesMap; + var hasActiveSet = false; + + for (var j = 0, lenj = dimensions.length; j < lenj; j++) { + if (axesMap.get(dimensions[j]).model.getActiveState() !== 'normal') { + hasActiveSet = true; + } + } + + return hasActiveSet; + }, + + /** + * Convert coords of each axis to Point. + * Return point. For example: [10, 20] + * @param {Array.} coords + * @param {string} dim + * @return {Array.} + */ + axisCoordToPoint: function(coord, dim) { + var axisLayout = this._axesLayout[dim]; + return applyTransform$1([coord, 0], axisLayout.transform); + }, + + /** + * Get axis layout. + */ + getAxisLayout: function(dim) { + return clone(this._axesLayout[dim]); + }, + + /** + * @param {Array.} point + * @return {Object} {axisExpandWindow, delta, behavior: 'jump' | 'slide' | 'none'}. + */ + getSlidedAxisExpandWindow: function(point) { + var layoutInfo = this._makeLayoutInfo(); + var pixelDimIndex = layoutInfo.pixelDimIndex; + var axisExpandWindow = layoutInfo.axisExpandWindow.slice(); + var winSize = axisExpandWindow[1] - axisExpandWindow[0]; + var extent = [0, layoutInfo.axisExpandWidth * (layoutInfo.axisCount - 1)]; + + // Out of the area of coordinate system. + if (!this.containPoint(point)) { + return { + behavior: 'none', + axisExpandWindow: axisExpandWindow + }; + } + + // Conver the point from global to expand coordinates. + var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos; + + // For dragging operation convenience, the window should not be + // slided when mouse is the center area of the window. + var delta; + var behavior = 'slide'; + var axisCollapseWidth = layoutInfo.axisCollapseWidth; + var triggerArea = this._model.get('axisExpandSlideTriggerArea'); + // But consider touch device, jump is necessary. + var useJump = triggerArea[0] != null; + + if (axisCollapseWidth) { + if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) { + behavior = 'jump'; + delta = pointCoord - winSize * triggerArea[2]; + } else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) { + behavior = 'jump'; + delta = pointCoord - winSize * (1 - triggerArea[2]); + } else { + (delta = pointCoord - winSize * triggerArea[1]) >= 0 + && + (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0 && + (delta = 0); + } + delta *= layoutInfo.axisExpandWidth / axisCollapseWidth; + delta + ? + sliderMove(delta, axisExpandWindow, extent, 'all') + // Avoid nonsense triger on mousemove. + : + (behavior = 'none'); + } + // When screen is too narrow, make it visible and slidable, although it is hard to interact. + else { + var winSize = axisExpandWindow[1] - axisExpandWindow[0]; + var pos = extent[1] * pointCoord / winSize; + axisExpandWindow = [mathMax$5(0, pos - winSize / 2)]; + axisExpandWindow[1] = mathMin$5(extent[1], axisExpandWindow[0] + winSize); + axisExpandWindow[0] = axisExpandWindow[1] - winSize; + } + + return { + axisExpandWindow: axisExpandWindow, + behavior: behavior + }; + } + }; + + function restrict(len, extent) { + return mathMin$5(mathMax$5(len, extent[0]), extent[1]); + } + + function layoutAxisWithoutExpand(axisIndex, layoutInfo) { + var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1); + return { + position: step * axisIndex, + axisNameAvailableWidth: step, + axisLabelShow: true + }; + } + + function layoutAxisWithExpand(axisIndex, layoutInfo) { + var layoutLength = layoutInfo.layoutLength; + var axisExpandWidth = layoutInfo.axisExpandWidth; + var axisCount = layoutInfo.axisCount; + var axisCollapseWidth = layoutInfo.axisCollapseWidth; + var winInnerIndices = layoutInfo.winInnerIndices; + + var position; + var axisNameAvailableWidth = axisCollapseWidth; + var axisLabelShow = false; + var nameTruncateMaxWidth; + + if (axisIndex < winInnerIndices[0]) { + position = axisIndex * axisCollapseWidth; + nameTruncateMaxWidth = axisCollapseWidth; + } else if (axisIndex <= winInnerIndices[1]) { + position = layoutInfo.axisExpandWindow0Pos + + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0]; + axisNameAvailableWidth = axisExpandWidth; + axisLabelShow = true; + } else { + position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth; + nameTruncateMaxWidth = axisCollapseWidth; + } + + return { + position: position, + axisNameAvailableWidth: axisNameAvailableWidth, + axisLabelShow: axisLabelShow, + nameTruncateMaxWidth: nameTruncateMaxWidth + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Parallel coordinate system creater. + */ + + function create$2(ecModel, api) { + var coordSysList = []; + + ecModel.eachComponent('parallel', function(parallelModel, idx) { + var coordSys = new Parallel(parallelModel, ecModel, api); + + coordSys.name = 'parallel_' + idx; + coordSys.resize(parallelModel, api); + + parallelModel.coordinateSystem = coordSys; + coordSys.model = parallelModel; + + coordSysList.push(coordSys); + }); + + // Inject the coordinateSystems into seriesModel + ecModel.eachSeries(function(seriesModel) { + if (seriesModel.get('coordinateSystem') === 'parallel') { + var parallelModel = ecModel.queryComponents({ + mainType: 'parallel', + index: seriesModel.get('parallelIndex'), + id: seriesModel.get('parallelId') + })[0]; + seriesModel.coordinateSystem = parallelModel.coordinateSystem; + } + }); + + return coordSysList; + } + + CoordinateSystemManager.register('parallel', { + create: create$2 + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AxisModel$2 = ComponentModel.extend({ + + type: 'baseParallelAxis', + + /** + * @type {module:echarts/coord/parallel/Axis} + */ + axis: null, + + /** + * @type {Array.} + * @readOnly + */ + activeIntervals: [], + + /** + * @return {Object} + */ + getAreaSelectStyle: function() { + return makeStyleMapper( + [ + ['fill', 'color'], + ['lineWidth', 'borderWidth'], + ['stroke', 'borderColor'], + ['width', 'width'], + ['opacity', 'opacity'] + ] + )(this.getModel('areaSelectStyle')); + }, + + /** + * The code of this feature is put on AxisModel but not ParallelAxis, + * because axisModel can be alive after echarts updating but instance of + * ParallelAxis having been disposed. this._activeInterval should be kept + * when action dispatched (i.e. legend click). + * + * @param {Array.>} intervals interval.length === 0 + * means set all active. + * @public + */ + setActiveIntervals: function(intervals) { + var activeIntervals = this.activeIntervals = clone(intervals); + + // Normalize + if (activeIntervals) { + for (var i = activeIntervals.length - 1; i >= 0; i--) { + asc(activeIntervals[i]); + } + } + }, + + /** + * @param {number|string} [value] When attempting to detect 'no activeIntervals set', + * value can not be input. + * @return {string} 'normal': no activeIntervals set, + * 'active', + * 'inactive'. + * @public + */ + getActiveState: function(value) { + var activeIntervals = this.activeIntervals; + + if (!activeIntervals.length) { + return 'normal'; + } + + if (value == null || isNaN(value)) { + return 'inactive'; + } + + // Simple optimization + if (activeIntervals.length === 1) { + var interval = activeIntervals[0]; + if (interval[0] <= value && value <= interval[1]) { + return 'active'; + } + } else { + for (var i = 0, len = activeIntervals.length; i < len; i++) { + if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) { + return 'active'; + } + } + } + + return 'inactive'; + } + + }); + + var defaultOption$1 = { + + type: 'value', + + /** + * @type {Array.} + */ + dim: null, // 0, 1, 2, ... + + // parallelIndex: null, + + areaSelectStyle: { + width: 20, + borderWidth: 1, + borderColor: 'rgba(160,197,232)', + color: 'rgba(160,197,232)', + opacity: 0.3 + }, + + realtime: true, // Whether realtime update view when select. + + z: 10 + }; + + merge(AxisModel$2.prototype, axisModelCommonMixin); + + function getAxisType$1(axisName, option) { + return option.type || (option.data ? 'category' : 'value'); + } + + axisModelCreator('parallel', AxisModel$2, getAxisType$1, defaultOption$1); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + ComponentModel.extend({ + + type: 'parallel', + + dependencies: ['parallelAxis'], + + /** + * @type {module:echarts/coord/parallel/Parallel} + */ + coordinateSystem: null, + + /** + * Each item like: 'dim0', 'dim1', 'dim2', ... + * @type {Array.} + * @readOnly + */ + dimensions: null, + + /** + * Coresponding to dimensions. + * @type {Array.} + * @readOnly + */ + parallelAxisIndex: null, + + layoutMode: 'box', + + defaultOption: { + zlevel: 0, + z: 0, + left: 80, + top: 60, + right: 80, + bottom: 60, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + + layout: 'horizontal', // 'horizontal' or 'vertical' + + // FIXME + // naming? + axisExpandable: false, + axisExpandCenter: null, + axisExpandCount: 0, + axisExpandWidth: 50, // FIXME '10%' ? + axisExpandRate: 17, + axisExpandDebounce: 50, + // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full. + // Do not doc to user until necessary. + axisExpandSlideTriggerArea: [-0.15, 0.05, 0.4], + axisExpandTriggerOn: 'click', // 'mousemove' or 'click' + + parallelAxisDefault: null + }, + + /** + * @override + */ + init: function() { + ComponentModel.prototype.init.apply(this, arguments); + + this.mergeOption({}); + }, + + /** + * @override + */ + mergeOption: function(newOption) { + var thisOption = this.option; + + newOption && merge(thisOption, newOption, true); + + this._initDimensions(); + }, + + /** + * Whether series or axis is in this coordinate system. + * @param {module:echarts/model/Series|module:echarts/coord/parallel/AxisModel} model + * @param {module:echarts/model/Global} ecModel + */ + contains: function(model, ecModel) { + var parallelIndex = model.get('parallelIndex'); + return parallelIndex != null && + ecModel.getComponent('parallel', parallelIndex) === this; + }, + + setAxisExpand: function(opt) { + each$1( + ['axisExpandable', 'axisExpandCenter', 'axisExpandCount', 'axisExpandWidth', 'axisExpandWindow'], + function(name) { + if (opt.hasOwnProperty(name)) { + this.option[name] = opt[name]; + } + }, + this + ); + }, + + /** + * @private + */ + _initDimensions: function() { + var dimensions = this.dimensions = []; + var parallelAxisIndex = this.parallelAxisIndex = []; + + var axisModels = filter(this.dependentModels.parallelAxis, function(axisModel) { + // Can not use this.contains here, because + // initialization has not been completed yet. + return (axisModel.get('parallelIndex') || 0) === this.componentIndex; + }, this); + + each$1(axisModels, function(axisModel) { + dimensions.push('dim' + axisModel.get('dim')); + parallelAxisIndex.push(axisModel.componentIndex); + }); + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @payload + * @property {string} parallelAxisId + * @property {Array.>} intervals + */ + var actionInfo$1 = { + type: 'axisAreaSelect', + event: 'axisAreaSelected' + // update: 'updateVisual' + }; + + registerAction(actionInfo$1, function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'parallelAxis', + query: payload + }, + function(parallelAxisModel) { + parallelAxisModel.axis.model.setActiveIntervals(payload.intervals); + } + ); + }); + + /** + * @payload + */ + registerAction('parallelAxisExpand', function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'parallel', + query: payload + }, + function(parallelModel) { + parallelModel.setAxisExpand(payload); + } + ); + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var curry$2 = curry; + var each$12 = each$1; + var map$2 = map; + var mathMin$6 = Math.min; + var mathMax$6 = Math.max; + var mathPow$2 = Math.pow; + + var COVER_Z = 10000; + var UNSELECT_THRESHOLD = 6; + var MIN_RESIZE_LINE_WIDTH = 6; + var MUTEX_RESOURCE_KEY = 'globalPan'; + + var DIRECTION_MAP = { + w: [0, 0], + e: [0, 1], + n: [1, 0], + s: [1, 1] + }; + var CURSOR_MAP = { + w: 'ew', + e: 'ew', + n: 'ns', + s: 'ns', + ne: 'nesw', + sw: 'nesw', + nw: 'nwse', + se: 'nwse' + }; + var DEFAULT_BRUSH_OPT = { + brushStyle: { + lineWidth: 2, + stroke: 'rgba(0,0,0,0.3)', + fill: 'rgba(0,0,0,0.1)' + }, + transformable: true, + brushMode: 'single', + removeOnClick: false + }; + + var baseUID = 0; + + /** + * @alias module:echarts/component/helper/BrushController + * @constructor + * @mixin {module:zrender/mixin/Eventful} + * @event module:echarts/component/helper/BrushController#brush + * params: + * areas: Array., coord relates to container group, + * If no container specified, to global. + * opt { + * isEnd: boolean, + * removeOnClick: boolean + * } + * + * @param {module:zrender/zrender~ZRender} zr + */ + function BrushController(zr) { + + if (__DEV__) { + assert$1(zr); + } + + Eventful.call(this); + + /** + * @type {module:zrender/zrender~ZRender} + * @private + */ + this._zr = zr; + + /** + * @type {module:zrender/container/Group} + * @readOnly + */ + this.group = new Group(); + + /** + * Only for drawing (after enabledBrush). + * 'line', 'rect', 'polygon' or false + * If passing false/null/undefined, disable brush. + * If passing 'auto', determined by panel.defaultBrushType + * @private + * @type {string} + */ + this._brushType; + + /** + * Only for drawing (after enabledBrush). + * + * @private + * @type {Object} + */ + this._brushOption; + + /** + * @private + * @type {Object} + */ + this._panels; + + /** + * @private + * @type {Array.} + */ + this._track = []; + + /** + * @private + * @type {boolean} + */ + this._dragging; + + /** + * @private + * @type {Array} + */ + this._covers = []; + + /** + * @private + * @type {moudule:zrender/container/Group} + */ + this._creatingCover; + + /** + * `true` means global panel + * @private + * @type {module:zrender/container/Group|boolean} + */ + this._creatingPanel; + + /** + * @private + * @type {boolean} + */ + this._enableGlobalPan; + + /** + * @private + * @type {boolean} + */ + if (__DEV__) { + this._mounted; + } + + /** + * @private + * @type {string} + */ + this._uid = 'brushController_' + baseUID++; + + /** + * @private + * @type {Object} + */ + this._handlers = {}; + each$12(mouseHandlers, function(handler, eventName) { + this._handlers[eventName] = bind(handler, this); + }, this); + } + + BrushController.prototype = { + + constructor: BrushController, + + /** + * If set to null/undefined/false, select disabled. + * @param {Object} brushOption + * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false + * If passing false/null/undefined, disable brush. + * If passing 'auto', determined by panel.defaultBrushType. + * ('auto' can not be used in global panel) + * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple' + * @param {boolean} [brushOption.transformable=true] + * @param {boolean} [brushOption.removeOnClick=false] + * @param {Object} [brushOption.brushStyle] + * @param {number} [brushOption.brushStyle.width] + * @param {number} [brushOption.brushStyle.lineWidth] + * @param {string} [brushOption.brushStyle.stroke] + * @param {string} [brushOption.brushStyle.fill] + * @param {number} [brushOption.z] + */ + enableBrush: function(brushOption) { + if (__DEV__) { + assert$1(this._mounted); + } + + this._brushType && doDisableBrush(this); + brushOption.brushType && doEnableBrush(this, brushOption); + + return this; + }, + + /** + * @param {Array.} panelOpts If not pass, it is global brush. + * Each items: { + * panelId, // mandatory. + * clipPath, // mandatory. function. + * isTargetByCursor, // mandatory. function. + * defaultBrushType, // optional, only used when brushType is 'auto'. + * getLinearBrushOtherExtent, // optional. function. + * } + */ + setPanels: function(panelOpts) { + if (panelOpts && panelOpts.length) { + var panels = this._panels = {}; + each$1(panelOpts, function(panelOpts) { + panels[panelOpts.panelId] = clone(panelOpts); + }); + } else { + this._panels = null; + } + return this; + }, + + /** + * @param {Object} [opt] + * @return {boolean} [opt.enableGlobalPan=false] + */ + mount: function(opt) { + opt = opt || {}; + + if (__DEV__) { + this._mounted = true; // should be at first. + } + + this._enableGlobalPan = opt.enableGlobalPan; + + var thisGroup = this.group; + this._zr.add(thisGroup); + + thisGroup.attr({ + position: opt.position || [0, 0], + rotation: opt.rotation || 0, + scale: opt.scale || [1, 1] + }); + this._transform = thisGroup.getLocalTransform(); + + return this; + }, + + eachCover: function(cb, context) { + each$12(this._covers, cb, context); + }, + + /** + * Update covers. + * @param {Array.} brushOptionList Like: + * [ + * {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable}, + * {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]}, + * ... + * ] + * `brushType` is required in each cover info. (can not be 'auto') + * `id` is not mandatory. + * `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default. + * If brushOptionList is null/undefined, all covers removed. + */ + updateCovers: function(brushOptionList) { + if (__DEV__) { + assert$1(this._mounted); + } + + brushOptionList = map(brushOptionList, function(brushOption) { + return merge(clone(DEFAULT_BRUSH_OPT), brushOption, true); + }); + + var tmpIdPrefix = '\0-brush-index-'; + var oldCovers = this._covers; + var newCovers = this._covers = []; + var controller = this; + var creatingCover = this._creatingCover; + + (new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey)) + .add(addOrUpdate) + .update(addOrUpdate) + .remove(remove) + .execute(); + + return this; + + function getKey(brushOption, index) { + return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + + '-' + brushOption.brushType; + } + + function oldGetKey(cover, index) { + return getKey(cover.__brushOption, index); + } + + function addOrUpdate(newIndex, oldIndex) { + var newBrushOption = brushOptionList[newIndex]; + // Consider setOption in event listener of brushSelect, + // where updating cover when creating should be forbiden. + if (oldIndex != null && oldCovers[oldIndex] === creatingCover) { + newCovers[newIndex] = oldCovers[oldIndex]; + } else { + var cover = newCovers[newIndex] = oldIndex != null ? + ( + oldCovers[oldIndex].__brushOption = newBrushOption, + oldCovers[oldIndex] + ) : + endCreating(controller, createCover(controller, newBrushOption)); + updateCoverAfterCreation(controller, cover); + } + } + + function remove(oldIndex) { + if (oldCovers[oldIndex] !== creatingCover) { + controller.group.remove(oldCovers[oldIndex]); + } + } + }, + + unmount: function() { + if (__DEV__) { + if (!this._mounted) { + return; + } + } + + this.enableBrush(false); + + // container may 'removeAll' outside. + clearCovers(this); + this._zr.remove(this.group); + + if (__DEV__) { + this._mounted = false; // should be at last. + } + + return this; + }, + + dispose: function() { + this.unmount(); + this.off(); + } + }; + + mixin(BrushController, Eventful); + + function doEnableBrush(controller, brushOption) { + var zr = controller._zr; + + // Consider roam, which takes globalPan too. + if (!controller._enableGlobalPan) { + take(zr, MUTEX_RESOURCE_KEY, controller._uid); + } + + each$12(controller._handlers, function(handler, eventName) { + zr.on(eventName, handler); + }); + + controller._brushType = brushOption.brushType; + controller._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true); + } + + function doDisableBrush(controller) { + var zr = controller._zr; + + release(zr, MUTEX_RESOURCE_KEY, controller._uid); + + each$12(controller._handlers, function(handler, eventName) { + zr.off(eventName, handler); + }); + + controller._brushType = controller._brushOption = null; + } + + function createCover(controller, brushOption) { + var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption); + cover.__brushOption = brushOption; + updateZ$1(cover, brushOption); + controller.group.add(cover); + return cover; + } + + function endCreating(controller, creatingCover) { + var coverRenderer = getCoverRenderer(creatingCover); + if (coverRenderer.endCreating) { + coverRenderer.endCreating(controller, creatingCover); + updateZ$1(creatingCover, creatingCover.__brushOption); + } + return creatingCover; + } + + function updateCoverShape(controller, cover) { + var brushOption = cover.__brushOption; + getCoverRenderer(cover).updateCoverShape( + controller, cover, brushOption.range, brushOption + ); + } + + function updateZ$1(cover, brushOption) { + var z = brushOption.z; + z == null && (z = COVER_Z); + cover.traverse(function(el) { + el.z = z; + el.z2 = z; // Consider in given container. + }); + } + + function updateCoverAfterCreation(controller, cover) { + getCoverRenderer(cover).updateCommon(controller, cover); + updateCoverShape(controller, cover); + } + + function getCoverRenderer(cover) { + return coverRenderers[cover.__brushOption.brushType]; + } + + // return target panel or `true` (means global panel) + function getPanelByPoint(controller, e, localCursorPoint) { + var panels = controller._panels; + if (!panels) { + return true; // Global panel + } + var panel; + var transform = controller._transform; + each$12(panels, function(pn) { + pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn); + }); + return panel; + } + + // Return a panel or true + function getPanelByCover(controller, cover) { + var panels = controller._panels; + if (!panels) { + return true; // Global panel + } + var panelId = cover.__brushOption.panelId; + // User may give cover without coord sys info, + // which is then treated as global panel. + return panelId != null ? panels[panelId] : true; + } + + function clearCovers(controller) { + var covers = controller._covers; + var originalLength = covers.length; + each$12(covers, function(cover) { + controller.group.remove(cover); + }, controller); + covers.length = 0; + + return !!originalLength; + } + + function trigger(controller, opt) { + var areas = map$2(controller._covers, function(cover) { + var brushOption = cover.__brushOption; + var range = clone(brushOption.range); + return { + brushType: brushOption.brushType, + panelId: brushOption.panelId, + range: range + }; + }); + + controller.trigger('brush', areas, { + isEnd: !!opt.isEnd, + removeOnClick: !!opt.removeOnClick + }); + } + + function shouldShowCover(controller) { + var track = controller._track; + + if (!track.length) { + return false; + } + + var p2 = track[track.length - 1]; + var p1 = track[0]; + var dx = p2[0] - p1[0]; + var dy = p2[1] - p1[1]; + var dist = mathPow$2(dx * dx + dy * dy, 0.5); + + return dist > UNSELECT_THRESHOLD; + } + + function getTrackEnds(track) { + var tail = track.length - 1; + tail < 0 && (tail = 0); + return [track[0], track[tail]]; + } + + function createBaseRectCover(doDrift, controller, brushOption, edgeNames) { + var cover = new Group(); + + cover.add(new Rect({ + name: 'main', + style: makeStyle(brushOption), + silent: true, + draggable: true, + cursor: 'move', + drift: curry$2(doDrift, controller, cover, 'nswe'), + ondragend: curry$2(trigger, controller, { + isEnd: true + }) + })); + + each$12( + edgeNames, + function(name) { + cover.add(new Rect({ + name: name, + style: { + opacity: 0 + }, + draggable: true, + silent: true, + invisible: true, + drift: curry$2(doDrift, controller, cover, name), + ondragend: curry$2(trigger, controller, { + isEnd: true + }) + })); + } + ); + + return cover; + } + + function updateBaseRect(controller, cover, localRange, brushOption) { + var lineWidth = brushOption.brushStyle.lineWidth || 0; + var handleSize = mathMax$6(lineWidth, MIN_RESIZE_LINE_WIDTH); + var x = localRange[0][0]; + var y = localRange[1][0]; + var xa = x - lineWidth / 2; + var ya = y - lineWidth / 2; + var x2 = localRange[0][1]; + var y2 = localRange[1][1]; + var x2a = x2 - handleSize + lineWidth / 2; + var y2a = y2 - handleSize + lineWidth / 2; + var width = x2 - x; + var height = y2 - y; + var widtha = width + lineWidth; + var heighta = height + lineWidth; + + updateRectShape(controller, cover, 'main', x, y, width, height); + + if (brushOption.transformable) { + updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta); + updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta); + updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize); + updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize); + + updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize); + updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize); + updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize); + updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize); + } + } + + function updateCommon(controller, cover) { + var brushOption = cover.__brushOption; + var transformable = brushOption.transformable; + + var mainEl = cover.childAt(0); + mainEl.useStyle(makeStyle(brushOption)); + mainEl.attr({ + silent: !transformable, + cursor: transformable ? 'move' : 'default' + }); + + each$12( + ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'], + function(name) { + var el = cover.childOfName(name); + var globalDir = getGlobalDirection(controller, name); + + el && el.attr({ + silent: !transformable, + invisible: !transformable, + cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null + }); + } + ); + } + + function updateRectShape(controller, cover, name, x, y, w, h) { + var el = cover.childOfName(name); + el && el.setShape(pointsToRect( + clipByPanel(controller, cover, [ + [x, y], + [x + w, y + h] + ]) + )); + } + + function makeStyle(brushOption) { + return defaults({ + strokeNoScale: true + }, brushOption.brushStyle); + } + + function formatRectRange(x, y, x2, y2) { + var min = [mathMin$6(x, x2), mathMin$6(y, y2)]; + var max = [mathMax$6(x, x2), mathMax$6(y, y2)]; + + return [ + [min[0], max[0]], // x range + [min[1], max[1]] // y range + ]; + } + + function getTransform$1(controller) { + return getTransform(controller.group); + } + + function getGlobalDirection(controller, localDirection) { + if (localDirection.length > 1) { + localDirection = localDirection.split(''); + var globalDir = [ + getGlobalDirection(controller, localDirection[0]), + getGlobalDirection(controller, localDirection[1]) + ]; + (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse(); + return globalDir.join(''); + } else { + var map$$1 = { + w: 'left', + e: 'right', + n: 'top', + s: 'bottom' + }; + var inverseMap = { + left: 'w', + right: 'e', + top: 'n', + bottom: 's' + }; + var globalDir = transformDirection( + map$$1[localDirection], getTransform$1(controller) + ); + return inverseMap[globalDir]; + } + } + + function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) { + var brushOption = cover.__brushOption; + var rectRange = toRectRange(brushOption.range); + var localDelta = toLocalDelta(controller, dx, dy); + + each$12(name.split(''), function(namePart) { + var ind = DIRECTION_MAP[namePart]; + rectRange[ind[0]][ind[1]] += localDelta[ind[0]]; + }); + + brushOption.range = fromRectRange(formatRectRange( + rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1] + )); + + updateCoverAfterCreation(controller, cover); + trigger(controller, { + isEnd: false + }); + } + + function driftPolygon(controller, cover, dx, dy, e) { + var range = cover.__brushOption.range; + var localDelta = toLocalDelta(controller, dx, dy); + + each$12(range, function(point) { + point[0] += localDelta[0]; + point[1] += localDelta[1]; + }); + + updateCoverAfterCreation(controller, cover); + trigger(controller, { + isEnd: false + }); + } + + function toLocalDelta(controller, dx, dy) { + var thisGroup = controller.group; + var localD = thisGroup.transformCoordToLocal(dx, dy); + var localZero = thisGroup.transformCoordToLocal(0, 0); + + return [localD[0] - localZero[0], localD[1] - localZero[1]]; + } + + function clipByPanel(controller, cover, data) { + var panel = getPanelByCover(controller, cover); + + return (panel && panel !== true) ? + panel.clipPath(data, controller._transform) : + clone(data); + } + + function pointsToRect(points) { + var xmin = mathMin$6(points[0][0], points[1][0]); + var ymin = mathMin$6(points[0][1], points[1][1]); + var xmax = mathMax$6(points[0][0], points[1][0]); + var ymax = mathMax$6(points[0][1], points[1][1]); + + return { + x: xmin, + y: ymin, + width: xmax - xmin, + height: ymax - ymin + }; + } + + function resetCursor(controller, e, localCursorPoint) { + // Check active + if (!controller._brushType) { + return; + } + + var zr = controller._zr; + var covers = controller._covers; + var currPanel = getPanelByPoint(controller, e, localCursorPoint); + + // Check whether in covers. + if (!controller._dragging) { + for (var i = 0; i < covers.length; i++) { + var brushOption = covers[i].__brushOption; + if (currPanel && + (currPanel === true || brushOption.panelId === currPanel.panelId) && + coverRenderers[brushOption.brushType].contain( + covers[i], localCursorPoint[0], localCursorPoint[1] + ) + ) { + // Use cursor style set on cover. + return; + } + } + } + + currPanel && zr.setCursorStyle('crosshair'); + } + + function preventDefault(e) { + var rawE = e.event; + rawE.preventDefault && rawE.preventDefault(); + } + + function mainShapeContain(cover, x, y) { + return cover.childOfName('main').contain(x, y); + } + + function updateCoverByMouse(controller, e, localCursorPoint, isEnd) { + var creatingCover = controller._creatingCover; + var panel = controller._creatingPanel; + var thisBrushOption = controller._brushOption; + var eventParams; + + controller._track.push(localCursorPoint.slice()); + + if (shouldShowCover(controller) || creatingCover) { + + if (panel && !creatingCover) { + thisBrushOption.brushMode === 'single' && clearCovers(controller); + var brushOption = clone(thisBrushOption); + brushOption.brushType = determineBrushType(brushOption.brushType, panel); + brushOption.panelId = panel === true ? null : panel.panelId; + creatingCover = controller._creatingCover = createCover(controller, brushOption); + controller._covers.push(creatingCover); + } + + if (creatingCover) { + var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)]; + var coverBrushOption = creatingCover.__brushOption; + + coverBrushOption.range = coverRenderer.getCreatingRange( + clipByPanel(controller, creatingCover, controller._track) + ); + + if (isEnd) { + endCreating(controller, creatingCover); + coverRenderer.updateCommon(controller, creatingCover); + } + + updateCoverShape(controller, creatingCover); + + eventParams = { + isEnd: isEnd + }; + } + } else if ( + isEnd && + thisBrushOption.brushMode === 'single' && + thisBrushOption.removeOnClick + ) { + // Help user to remove covers easily, only by a tiny drag, in 'single' mode. + // But a single click do not clear covers, because user may have casual + // clicks (for example, click on other component and do not expect covers + // disappear). + // Only some cover removed, trigger action, but not every click trigger action. + if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) { + eventParams = { + isEnd: isEnd, + removeOnClick: true + }; + } + } + + return eventParams; + } + + function determineBrushType(brushType, panel) { + if (brushType === 'auto') { + if (__DEV__) { + assert$1( + panel && panel.defaultBrushType, + 'MUST have defaultBrushType when brushType is "atuo"' + ); + } + return panel.defaultBrushType; + } + return brushType; + } + + var mouseHandlers = { + + mousedown: function(e) { + if (this._dragging) { + // In case some browser do not support globalOut, + // and release mose out side the browser. + handleDragEnd.call(this, e); + } else if (!e.target || !e.target.draggable) { + + preventDefault(e); + + var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY); + + this._creatingCover = null; + var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint); + + if (panel) { + this._dragging = true; + this._track = [localCursorPoint.slice()]; + } + } + }, + + mousemove: function(e) { + var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY); + + resetCursor(this, e, localCursorPoint); + + if (this._dragging) { + + preventDefault(e); + + var eventParams = updateCoverByMouse(this, e, localCursorPoint, false); + + eventParams && trigger(this, eventParams); + } + }, + + mouseup: handleDragEnd //, + + // FIXME + // in tooltip, globalout should not be triggered. + // globalout: handleDragEnd + }; + + function handleDragEnd(e) { + if (this._dragging) { + + preventDefault(e); + + var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY); + var eventParams = updateCoverByMouse(this, e, localCursorPoint, true); + + this._dragging = false; + this._track = []; + this._creatingCover = null; + + // trigger event shoule be at final, after procedure will be nested. + eventParams && trigger(this, eventParams); + } + } + + /** + * key: brushType + * @type {Object} + */ + var coverRenderers = { + + lineX: getLineRenderer(0), + + lineY: getLineRenderer(1), + + rect: { + createCover: function(controller, brushOption) { + return createBaseRectCover( + curry$2( + driftRect, + function(range) { + return range; + }, + function(range) { + return range; + } + ), + controller, + brushOption, + ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'] + ); + }, + getCreatingRange: function(localTrack) { + var ends = getTrackEnds(localTrack); + return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]); + }, + updateCoverShape: function(controller, cover, localRange, brushOption) { + updateBaseRect(controller, cover, localRange, brushOption); + }, + updateCommon: updateCommon, + contain: mainShapeContain + }, + + polygon: { + createCover: function(controller, brushOption) { + var cover = new Group(); + + // Do not use graphic.Polygon because graphic.Polyline do not close the + // border of the shape when drawing, which is a better experience for user. + cover.add(new Polyline({ + name: 'main', + style: makeStyle(brushOption), + silent: true + })); + + return cover; + }, + getCreatingRange: function(localTrack) { + return localTrack; + }, + endCreating: function(controller, cover) { + cover.remove(cover.childAt(0)); + // Use graphic.Polygon close the shape. + cover.add(new Polygon({ + name: 'main', + draggable: true, + drift: curry$2(driftPolygon, controller, cover), + ondragend: curry$2(trigger, controller, { + isEnd: true + }) + })); + }, + updateCoverShape: function(controller, cover, localRange, brushOption) { + cover.childAt(0).setShape({ + points: clipByPanel(controller, cover, localRange) + }); + }, + updateCommon: updateCommon, + contain: mainShapeContain + } + }; + + function getLineRenderer(xyIndex) { + return { + createCover: function(controller, brushOption) { + return createBaseRectCover( + curry$2( + driftRect, + function(range) { + var rectRange = [range, [0, 100]]; + xyIndex && rectRange.reverse(); + return rectRange; + }, + function(rectRange) { + return rectRange[xyIndex]; + } + ), + controller, + brushOption, + [ + ['w', 'e'], + ['n', 's'] + ][xyIndex] + ); + }, + getCreatingRange: function(localTrack) { + var ends = getTrackEnds(localTrack); + var min = mathMin$6(ends[0][xyIndex], ends[1][xyIndex]); + var max = mathMax$6(ends[0][xyIndex], ends[1][xyIndex]); + + return [min, max]; + }, + updateCoverShape: function(controller, cover, localRange, brushOption) { + var otherExtent; + // If brushWidth not specified, fit the panel. + var panel = getPanelByCover(controller, cover); + if (panel !== true && panel.getLinearBrushOtherExtent) { + otherExtent = panel.getLinearBrushOtherExtent( + xyIndex, controller._transform + ); + } else { + var zr = controller._zr; + otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]]; + } + var rectRange = [localRange, otherExtent]; + xyIndex && rectRange.reverse(); + + updateBaseRect(controller, cover, rectRange, brushOption); + }, + updateCommon: updateCommon, + contain: mainShapeContain + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function makeRectPanelClipPath(rect) { + rect = normalizeRect(rect); + return function(localPoints, transform) { + return clipPointsByRect(localPoints, rect); + }; + } + + function makeLinearBrushOtherExtent(rect, specifiedXYIndex) { + rect = normalizeRect(rect); + return function(xyIndex) { + var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex; + var brushWidth = idx ? rect.width : rect.height; + var base = idx ? rect.x : rect.y; + return [base, base + (brushWidth || 0)]; + }; + } + + function makeRectIsTargetByCursor(rect, api, targetModel) { + rect = normalizeRect(rect); + return function(e, localCursorPoint, transform) { + return rect.contain(localCursorPoint[0], localCursorPoint[1]) && + !onIrrelevantElement(e, api, targetModel); + }; + } + + // Consider width/height is negative. + function normalizeRect(rect) { + return BoundingRect.create(rect); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var elementList = ['axisLine', 'axisTickLabel', 'axisName']; + + var AxisView$2 = extendComponentView({ + + type: 'parallelAxis', + + /** + * @override + */ + init: function(ecModel, api) { + AxisView$2.superApply(this, 'init', arguments); + + /** + * @type {module:echarts/component/helper/BrushController} + */ + (this._brushController = new BrushController(api.getZr())) + .on('brush', bind(this._onBrush, this)); + }, + + /** + * @override + */ + render: function(axisModel, ecModel, api, payload) { + if (fromAxisAreaSelect(axisModel, ecModel, payload)) { + return; + } + + this.axisModel = axisModel; + this.api = api; + + this.group.removeAll(); + + var oldAxisGroup = this._axisGroup; + this._axisGroup = new Group(); + this.group.add(this._axisGroup); + + if (!axisModel.get('show')) { + return; + } + + var coordSysModel = getCoordSysModel(axisModel, ecModel); + var coordSys = coordSysModel.coordinateSystem; + + var areaSelectStyle = axisModel.getAreaSelectStyle(); + var areaWidth = areaSelectStyle.width; + + var dim = axisModel.axis.dim; + var axisLayout = coordSys.getAxisLayout(dim); + + var builderOpt = extend({ + strokeContainThreshold: areaWidth + }, + axisLayout + ); + + var axisBuilder = new AxisBuilder(axisModel, builderOpt); + + each$1(elementList, axisBuilder.add, axisBuilder); + + this._axisGroup.add(axisBuilder.getGroup()); + + this._refreshBrushController( + builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api + ); + + var animationModel = (payload && payload.animation === false) ? null : axisModel; + groupTransition(oldAxisGroup, this._axisGroup, animationModel); + }, + + // /** + // * @override + // */ + // updateVisual: function (axisModel, ecModel, api, payload) { + // this._brushController && this._brushController + // .updateCovers(getCoverInfoList(axisModel)); + // }, + + _refreshBrushController: function( + builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api + ) { + // After filtering, axis may change, select area needs to be update. + var extent = axisModel.axis.getExtent(); + var extentLen = extent[1] - extent[0]; + var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value. + + // width/height might be negative, which will be + // normalized in BoundingRect. + var rect = BoundingRect.create({ + x: extent[0], + y: -areaWidth / 2, + width: extentLen, + height: areaWidth + }); + rect.x -= extra; + rect.width += 2 * extra; + + this._brushController + .mount({ + enableGlobalPan: true, + rotation: builderOpt.rotation, + position: builderOpt.position + }) + .setPanels([{ + panelId: 'pl', + clipPath: makeRectPanelClipPath(rect), + isTargetByCursor: makeRectIsTargetByCursor(rect, api, coordSysModel), + getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect, 0) + }]) + .enableBrush({ + brushType: 'lineX', + brushStyle: areaSelectStyle, + removeOnClick: true + }) + .updateCovers(getCoverInfoList(axisModel)); + }, + + _onBrush: function(coverInfoList, opt) { + // Do not cache these object, because the mey be changed. + var axisModel = this.axisModel; + var axis = axisModel.axis; + var intervals = map(coverInfoList, function(coverInfo) { + return [ + axis.coordToData(coverInfo.range[0], true), + axis.coordToData(coverInfo.range[1], true) + ]; + }); + + // If realtime is true, action is not dispatched on drag end, because + // the drag end emits the same params with the last drag move event, + // and may have some delay when using touch pad. + if (!axisModel.option.realtime === opt.isEnd || opt.removeOnClick) { // jshint ignore:line + this.api.dispatchAction({ + type: 'axisAreaSelect', + parallelAxisId: axisModel.id, + intervals: intervals + }); + } + }, + + /** + * @override + */ + dispose: function() { + this._brushController.dispose(); + } + }); + + function fromAxisAreaSelect(axisModel, ecModel, payload) { + return payload && + payload.type === 'axisAreaSelect' && + ecModel.findComponents({ + mainType: 'parallelAxis', + query: payload + })[0] === axisModel; + } + + function getCoverInfoList(axisModel) { + var axis = axisModel.axis; + return map(axisModel.activeIntervals, function(interval) { + return { + brushType: 'lineX', + panelId: 'pl', + range: [ + axis.dataToCoord(interval[0], true), + axis.dataToCoord(interval[1], true) + ] + }; + }); + } + + function getCoordSysModel(axisModel, ecModel) { + return ecModel.getComponent( + 'parallel', axisModel.get('parallelIndex') + ); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var CLICK_THRESHOLD = 5; // > 4 + + // Parallel view + extendComponentView({ + type: 'parallel', + + render: function(parallelModel, ecModel, api) { + this._model = parallelModel; + this._api = api; + + if (!this._handlers) { + this._handlers = {}; + each$1(handlers, function(handler, eventName) { + api.getZr().on(eventName, this._handlers[eventName] = bind(handler, this)); + }, this); + } + + createOrUpdate( + this, + '_throttledDispatchExpand', + parallelModel.get('axisExpandRate'), + 'fixRate' + ); + }, + + dispose: function(ecModel, api) { + each$1(this._handlers, function(handler, eventName) { + api.getZr().off(eventName, handler); + }); + this._handlers = null; + }, + + /** + * @param {Object} [opt] If null, cancle the last action triggering for debounce. + */ + _throttledDispatchExpand: function(opt) { + this._dispatchExpand(opt); + }, + + _dispatchExpand: function(opt) { + opt && this._api.dispatchAction( + extend({ + type: 'parallelAxisExpand' + }, opt) + ); + } + + }); + + var handlers = { + + mousedown: function(e) { + if (checkTrigger(this, 'click')) { + this._mouseDownPoint = [e.offsetX, e.offsetY]; + } + }, + + mouseup: function(e) { + var mouseDownPoint = this._mouseDownPoint; + + if (checkTrigger(this, 'click') && mouseDownPoint) { + var point = [e.offsetX, e.offsetY]; + var dist = Math.pow(mouseDownPoint[0] - point[0], 2) + + Math.pow(mouseDownPoint[1] - point[1], 2); + + if (dist > CLICK_THRESHOLD) { + return; + } + + var result = this._model.coordinateSystem.getSlidedAxisExpandWindow( + [e.offsetX, e.offsetY] + ); + + result.behavior !== 'none' && this._dispatchExpand({ + axisExpandWindow: result.axisExpandWindow + }); + } + + this._mouseDownPoint = null; + }, + + mousemove: function(e) { + // Should do nothing when brushing. + if (this._mouseDownPoint || !checkTrigger(this, 'mousemove')) { + return; + } + var model = this._model; + var result = model.coordinateSystem.getSlidedAxisExpandWindow( + [e.offsetX, e.offsetY] + ); + + var behavior = result.behavior; + behavior === 'jump' && this._throttledDispatchExpand.debounceNextCall(model.get('axisExpandDebounce')); + this._throttledDispatchExpand( + behavior === 'none' ? + null // Cancle the last trigger, in case that mouse slide out of the area quickly. + : + { + axisExpandWindow: result.axisExpandWindow, + // Jumping uses animation, and sliding suppresses animation. + animation: behavior === 'jump' ? null : false + } + ); + } + }; + + function checkTrigger(view, triggerOn) { + var model = view._model; + return model.get('axisExpandable') && model.get('axisExpandTriggerOn') === triggerOn; + } + + registerPreprocessor(parallelPreprocessor); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.parallel', + + dependencies: ['parallel'], + + visualColorAccessPath: 'lineStyle.color', + + getInitialData: function(option, ecModel) { + var source = this.getSource(); + + setEncodeAndDimensions(source, this); + + return createListFromArray(source, this); + }, + + /** + * User can get data raw indices on 'axisAreaSelected' event received. + * + * @public + * @param {string} activeState 'active' or 'inactive' or 'normal' + * @return {Array.} Raw indices + */ + getRawIndicesByActiveState: function(activeState) { + var coordSys = this.coordinateSystem; + var data = this.getData(); + var indices = []; + + coordSys.eachActiveState(data, function(theActiveState, dataIndex) { + if (activeState === theActiveState) { + indices.push(data.getRawIndex(dataIndex)); + } + }); + + return indices; + }, + + defaultOption: { + zlevel: 0, // 一级层叠 + z: 2, // 二级层叠 + + coordinateSystem: 'parallel', + parallelIndex: 0, + + label: { + show: false + }, + + inactiveOpacity: 0.05, + activeOpacity: 1, + + lineStyle: { + width: 1, + opacity: 0.45, + type: 'solid' + }, + emphasis: { + label: { + show: false + } + }, + + progressive: 500, + smooth: false, // true | false | number + + animationEasing: 'linear' + } + }); + + function setEncodeAndDimensions(source, seriesModel) { + // The mapping of parallelAxis dimension to data dimension can + // be specified in parallelAxis.option.dim. For example, if + // parallelAxis.option.dim is 'dim3', it mapping to the third + // dimension of data. But `data.encode` has higher priority. + // Moreover, parallelModel.dimension should not be regarded as data + // dimensions. Consider dimensions = ['dim4', 'dim2', 'dim6']; + + if (source.encodeDefine) { + return; + } + + var parallelModel = seriesModel.ecModel.getComponent( + 'parallel', seriesModel.get('parallelIndex') + ); + if (!parallelModel) { + return; + } + + var encodeDefine = source.encodeDefine = createHashMap(); + each$1(parallelModel.dimensions, function(axisDim) { + var dataDimIndex = convertDimNameToNumber(axisDim); + encodeDefine.set(axisDim, dataDimIndex); + }); + } + + function convertDimNameToNumber(dimName) { + return +dimName.replace('dim', ''); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var DEFAULT_SMOOTH = 0.3; + + var ParallelView = Chart.extend({ + + type: 'parallel', + + init: function() { + + /** + * @type {module:zrender/container/Group} + * @private + */ + this._dataGroup = new Group(); + + this.group.add(this._dataGroup); + + /** + * @type {module:echarts/data/List} + */ + this._data; + + /** + * @type {boolean} + */ + this._initialized; + }, + + /** + * @override + */ + render: function(seriesModel, ecModel, api, payload) { + var dataGroup = this._dataGroup; + var data = seriesModel.getData(); + var oldData = this._data; + var coordSys = seriesModel.coordinateSystem; + var dimensions = coordSys.dimensions; + var seriesScope = makeSeriesScope$2(seriesModel); + + data.diff(oldData) + .add(add) + .update(update) + .remove(remove) + .execute(); + + function add(newDataIndex) { + var line = addEl(data, dataGroup, newDataIndex, dimensions, coordSys); + updateElCommon(line, data, newDataIndex, seriesScope); + } + + function update(newDataIndex, oldDataIndex) { + var line = oldData.getItemGraphicEl(oldDataIndex); + var points = createLinePoints(data, newDataIndex, dimensions, coordSys); + data.setItemGraphicEl(newDataIndex, line); + var animationModel = (payload && payload.animation === false) ? null : seriesModel; + updateProps(line, { + shape: { + points: points + } + }, animationModel, newDataIndex); + + updateElCommon(line, data, newDataIndex, seriesScope); + } + + function remove(oldDataIndex) { + var line = oldData.getItemGraphicEl(oldDataIndex); + dataGroup.remove(line); + } + + // First create + if (!this._initialized) { + this._initialized = true; + var clipPath = createGridClipShape$1( + coordSys, seriesModel, + function() { + // Callback will be invoked immediately if there is no animation + setTimeout(function() { + dataGroup.removeClipPath(); + }); + } + ); + dataGroup.setClipPath(clipPath); + } + + this._data = data; + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + this._initialized = true; + this._data = null; + this._dataGroup.removeAll(); + }, + + incrementalRender: function(taskParams, seriesModel, ecModel) { + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var dimensions = coordSys.dimensions; + var seriesScope = makeSeriesScope$2(seriesModel); + + for (var dataIndex = taskParams.start; dataIndex < taskParams.end; dataIndex++) { + var line = addEl(data, this._dataGroup, dataIndex, dimensions, coordSys); + line.incremental = true; + updateElCommon(line, data, dataIndex, seriesScope); + } + }, + + dispose: function() {}, + + // _renderForProgressive: function (seriesModel) { + // var dataGroup = this._dataGroup; + // var data = seriesModel.getData(); + // var oldData = this._data; + // var coordSys = seriesModel.coordinateSystem; + // var dimensions = coordSys.dimensions; + // var option = seriesModel.option; + // var progressive = option.progressive; + // var smooth = option.smooth ? SMOOTH : null; + + // // In progressive animation is disabled, so use simple data diff, + // // which effects performance less. + // // (Typically performance for data with length 7000+ like: + // // simpleDiff: 60ms, addEl: 184ms, + // // in RMBP 2.4GHz intel i7, OSX 10.9 chrome 50.0.2661.102 (64-bit)) + // if (simpleDiff(oldData, data, dimensions)) { + // dataGroup.removeAll(); + // data.each(function (dataIndex) { + // addEl(data, dataGroup, dataIndex, dimensions, coordSys); + // }); + // } + + // updateElCommon(data, progressive, smooth); + + // // Consider switch between progressive and not. + // data.__plProgressive = true; + // this._data = data; + // }, + + /** + * @override + */ + remove: function() { + this._dataGroup && this._dataGroup.removeAll(); + this._data = null; + } + }); + + function createGridClipShape$1(coordSys, seriesModel, cb) { + var parallelModel = coordSys.model; + var rect = coordSys.getRect(); + var rectEl = new Rect({ + shape: { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + } + }); + + var dim = parallelModel.get('layout') === 'horizontal' ? 'width' : 'height'; + rectEl.setShape(dim, 0); + initProps(rectEl, { + shape: { + width: rect.width, + height: rect.height + } + }, seriesModel, cb); + return rectEl; + } + + function createLinePoints(data, dataIndex, dimensions, coordSys) { + var points = []; + for (var i = 0; i < dimensions.length; i++) { + var dimName = dimensions[i]; + var value = data.get(data.mapDimension(dimName), dataIndex); + if (!isEmptyValue(value, coordSys.getAxis(dimName).type)) { + points.push(coordSys.dataToPoint(value, dimName)); + } + } + return points; + } + + function addEl(data, dataGroup, dataIndex, dimensions, coordSys) { + var points = createLinePoints(data, dataIndex, dimensions, coordSys); + var line = new Polyline({ + shape: { + points: points + }, + silent: true, + z2: 10 + }); + dataGroup.add(line); + data.setItemGraphicEl(dataIndex, line); + return line; + } + + function makeSeriesScope$2(seriesModel) { + var smooth = seriesModel.get('smooth', true); + smooth === true && (smooth = DEFAULT_SMOOTH); + return { + lineStyle: seriesModel.getModel('lineStyle').getLineStyle(), + smooth: smooth != null ? smooth : DEFAULT_SMOOTH + }; + } + + function updateElCommon(el, data, dataIndex, seriesScope) { + var lineStyle = seriesScope.lineStyle; + + if (data.hasItemOption) { + var lineStyleModel = data.getItemModel(dataIndex).getModel('lineStyle'); + lineStyle = lineStyleModel.getLineStyle(); + } + + el.useStyle(lineStyle); + + var elStyle = el.style; + elStyle.fill = null; + // lineStyle.color have been set to itemVisual in module:echarts/visual/seriesColor. + elStyle.stroke = data.getItemVisual(dataIndex, 'color'); + // lineStyle.opacity have been set to itemVisual in parallelVisual. + elStyle.opacity = data.getItemVisual(dataIndex, 'opacity'); + + seriesScope.smooth && (el.shape.smooth = seriesScope.smooth); + } + + // function simpleDiff(oldData, newData, dimensions) { + // var oldLen; + // if (!oldData + // || !oldData.__plProgressive + // || (oldLen = oldData.count()) !== newData.count() + // ) { + // return true; + // } + + // var dimLen = dimensions.length; + // for (var i = 0; i < oldLen; i++) { + // for (var j = 0; j < dimLen; j++) { + // if (oldData.get(dimensions[j], i) !== newData.get(dimensions[j], i)) { + // return true; + // } + // } + // } + + // return false; + // } + + // FIXME + // 公用方法? + function isEmptyValue(val, axisType) { + return axisType === 'category' ? + val == null : + (val == null || isNaN(val)); // axisType === 'value' + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var opacityAccessPath$1 = ['lineStyle', 'normal', 'opacity']; + + var parallelVisual = { + + seriesType: 'parallel', + + reset: function(seriesModel, ecModel, api) { + + var itemStyleModel = seriesModel.getModel('itemStyle'); + var lineStyleModel = seriesModel.getModel('lineStyle'); + var globalColors = ecModel.get('color'); + + var color = lineStyleModel.get('color') || + itemStyleModel.get('color') || + globalColors[seriesModel.seriesIndex % globalColors.length]; + var inactiveOpacity = seriesModel.get('inactiveOpacity'); + var activeOpacity = seriesModel.get('activeOpacity'); + var lineStyle = seriesModel.getModel('lineStyle').getLineStyle(); + + var coordSys = seriesModel.coordinateSystem; + var data = seriesModel.getData(); + + var opacityMap = { + normal: lineStyle.opacity, + active: activeOpacity, + inactive: inactiveOpacity + }; + + data.setVisual('color', color); + + function progress(params, data) { + coordSys.eachActiveState(data, function(activeState, dataIndex) { + var opacity = opacityMap[activeState]; + if (activeState === 'normal' && data.hasItemOption) { + var itemOpacity = data.getItemModel(dataIndex).get(opacityAccessPath$1, true); + itemOpacity != null && (opacity = itemOpacity); + } + data.setItemVisual(dataIndex, 'opacity', opacity); + }, params.start, params.end); + } + + return { + progress: progress + }; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(parallelVisual); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Get initial data and define sankey view's series model + * @author Deqing Li(annong035@gmail.com) + */ + + var SankeySeries = SeriesModel.extend({ + + type: 'series.sankey', + + layoutInfo: null, + + /** + * Init a graph data structure from data in option series + * + * @param {Object} option the object used to config echarts view + * @return {module:echarts/data/List} storage initial data + */ + getInitialData: function(option) { + var links = option.edges || option.links; + var nodes = option.data || option.nodes; + if (nodes && links) { + var graph = createGraphFromNodeEdge(nodes, links, this, true); + return graph.data; + } + }, + + setNodePosition: function(dataIndex, localPosition) { + var dataItem = this.option.data[dataIndex]; + dataItem.localX = localPosition[0]; + dataItem.localY = localPosition[1]; + }, + + /** + * Return the graphic data structure + * + * @return {module:echarts/data/Graph} graphic data structure + */ + getGraph: function() { + return this.getData().graph; + }, + + /** + * Get edge data of graphic data structure + * + * @return {module:echarts/data/List} data structure of list + */ + getEdgeData: function() { + return this.getGraph().edgeData; + }, + + /** + * @override + */ + formatTooltip: function(dataIndex, multipleSeries, dataType) { + // dataType === 'node' or empty do not show tooltip by default + if (dataType === 'edge') { + var params = this.getDataParams(dataIndex, dataType); + var rawDataOpt = params.data; + var html = rawDataOpt.source + ' -- ' + rawDataOpt.target; + if (params.value) { + html += ' : ' + params.value; + } + return encodeHTML(html); + } + + return SankeySeries.superCall(this, 'formatTooltip', dataIndex, multipleSeries); + }, + + defaultOption: { + zlevel: 0, + z: 2, + + coordinateSystem: 'view', + + layout: null, + + // the position of the whole view + left: '5%', + top: '5%', + right: '20%', + bottom: '5%', + + // the dx of the node + nodeWidth: 20, + + // the vertical distance between two nodes + nodeGap: 8, + + // control if the node can move or not + draggable: true, + + // the number of iterations to change the position of the node + layoutIterations: 32, + + label: { + show: true, + position: 'right', + color: '#000', + fontSize: 12 + }, + + itemStyle: { + borderWidth: 1, + borderColor: '#333' + }, + + lineStyle: { + color: '#314656', + opacity: 0.2, + curveness: 0.5 + }, + + emphasis: { + label: { + show: true + }, + lineStyle: { + opacity: 0.6 + } + }, + + animationEasing: 'linear', + + animationDuration: 1000 + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file The file used to draw sankey view + * @author Deqing Li(annong035@gmail.com) + */ + + var SankeyShape = extendShape({ + shape: { + x1: 0, + y1: 0, + x2: 0, + y2: 0, + cpx1: 0, + cpy1: 0, + cpx2: 0, + cpy2: 0, + + extent: 0 + }, + + buildPath: function(ctx, shape) { + var halfExtent = shape.extent / 2; + ctx.moveTo(shape.x1, shape.y1 - halfExtent); + ctx.bezierCurveTo( + shape.cpx1, shape.cpy1 - halfExtent, + shape.cpx2, shape.cpy2 - halfExtent, + shape.x2, shape.y2 - halfExtent + ); + ctx.lineTo(shape.x2, shape.y2 + halfExtent); + ctx.bezierCurveTo( + shape.cpx2, shape.cpy2 + halfExtent, + shape.cpx1, shape.cpy1 + halfExtent, + shape.x1, shape.y1 + halfExtent + ); + ctx.closePath(); + } + }); + + extendChartView({ + + type: 'sankey', + + /** + * @private + * @type {module:echarts/chart/sankey/SankeySeries} + */ + _model: null, + + render: function(seriesModel, ecModel, api) { + var graph = seriesModel.getGraph(); + var group = this.group; + var layoutInfo = seriesModel.layoutInfo; + // view width + var width = layoutInfo.width; + // view height + var height = layoutInfo.height; + + var nodeData = seriesModel.getData(); + var edgeData = seriesModel.getData('edge'); + + this._model = seriesModel; + + group.removeAll(); + + group.attr('position', [layoutInfo.x, layoutInfo.y]); + + // generate a bezire Curve for each edge + graph.eachEdge(function(edge) { + var curve = new SankeyShape(); + curve.dataIndex = edge.dataIndex; + curve.seriesIndex = seriesModel.seriesIndex; + curve.dataType = 'edge'; + var lineStyleModel = edge.getModel('lineStyle'); + var curvature = lineStyleModel.get('curveness'); + var n1Layout = edge.node1.getLayout(); + var node1Model = edge.node1.getModel(); + var dragX1 = node1Model.get('localX'); + var dragY1 = node1Model.get('localY'); + var n2Layout = edge.node2.getLayout(); + var node2Model = edge.node2.getModel(); + var dragX2 = node2Model.get('localX'); + var dragY2 = node2Model.get('localY'); + var edgeLayout = edge.getLayout(); + + curve.shape.extent = Math.max(1, edgeLayout.dy); + + var x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + n1Layout.dx; + var y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + edgeLayout.sy + edgeLayout.dy / 2; + var x2 = dragX2 != null ? dragX2 * width : n2Layout.x; + var y2 = (dragY2 != null ? dragY2 * height : n2Layout.y) + edgeLayout.ty + edgeLayout.dy / 2; + var cpx1 = x1 * (1 - curvature) + x2 * curvature; + var cpy1 = y1; + var cpx2 = x1 * curvature + x2 * (1 - curvature); + var cpy2 = y2; + + curve.setShape({ + x1: x1, + y1: y1, + x2: x2, + y2: y2, + cpx1: cpx1, + cpy1: cpy1, + cpx2: cpx2, + cpy2: cpy2 + }); + + curve.setStyle(lineStyleModel.getItemStyle()); + // Special color, use source node color or target node color + switch (curve.style.fill) { + case 'source': + curve.style.fill = edge.node1.getVisual('color'); + break; + case 'target': + curve.style.fill = edge.node2.getVisual('color'); + break; + } + + setHoverStyle(curve, edge.getModel('emphasis.lineStyle').getItemStyle()); + + group.add(curve); + + edgeData.setItemGraphicEl(edge.dataIndex, curve); + }); + + // generate a rect for each node + graph.eachNode(function(node) { + var layout = node.getLayout(); + var itemModel = node.getModel(); + var dragX = itemModel.get('localX'); + var dragY = itemModel.get('localY'); + var labelModel = itemModel.getModel('label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + + var rect = new Rect({ + shape: { + x: dragX != null ? dragX * width : layout.x, + y: dragY != null ? dragY * height : layout.y, + width: layout.dx, + height: layout.dy + }, + style: itemModel.getModel('itemStyle').getItemStyle() + }); + + var hoverStyle = node.getModel('emphasis.itemStyle').getItemStyle(); + + setLabelStyle( + rect.style, hoverStyle, labelModel, labelHoverModel, { + labelFetcher: seriesModel, + labelDataIndex: node.dataIndex, + defaultText: node.id, + isRectText: true + } + ); + + rect.setStyle('fill', node.getVisual('color')); + + setHoverStyle(rect, hoverStyle); + + group.add(rect); + + nodeData.setItemGraphicEl(node.dataIndex, rect); + + rect.dataType = 'node'; + }); + + var draggable = seriesModel.get('draggable'); + if (draggable) { + nodeData.eachItemGraphicEl(function(el, dataIndex) { + el.drift = function(dx, dy) { + this.shape.x += dx; + this.shape.y += dy; + this.dirty(); + api.dispatchAction({ + type: 'dragNode', + seriesId: seriesModel.id, + dataIndex: nodeData.getRawIndex(dataIndex), + localX: this.shape.x / width, + localY: this.shape.y / height + }); + }; + + el.draggable = true; + el.cursor = 'move'; + }); + } + + if (!this._data && seriesModel.get('animation')) { + group.setClipPath(createGridClipShape$2(group.getBoundingRect(), seriesModel, function() { + group.removeClipPath(); + })); + } + + this._data = seriesModel.getData(); + }, + + dispose: function() {} + }); + + // add animation to the view + function createGridClipShape$2(rect, seriesModel, cb) { + var rectEl = new Rect({ + shape: { + x: rect.x - 10, + y: rect.y - 10, + width: 0, + height: rect.height + 20 + } + }); + initProps(rectEl, { + shape: { + width: rect.width + 20, + height: rect.height + 20 + } + }, seriesModel, cb); + + return rectEl; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerAction({ + type: 'dragNode', + event: 'dragNode', + // here can only use 'update' now, other value is not support in echarts. + update: 'update' + }, function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'sankey', + query: payload + }, function(seriesModel) { + seriesModel.setNodePosition(payload.dataIndex, [payload.localX, payload.localY]); + }); + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * The implementation references to d3.js. The use of the source + * code of this file is also subject to the terms and consitions + * of its license (BSD-3Clause, see ). + */ + + + /** + * nest helper used to group by the array. + * can specified the keys and sort the keys. + */ + function nest() { + + var keysFunction = []; + var sortKeysFunction = []; + + /** + * map an Array into the mapObject. + * @param {Array} array + * @param {number} depth + */ + function map$$1(array, depth) { + if (depth >= keysFunction.length) { + return array; + } + var i = -1; + var n = array.length; + var keyFunction = keysFunction[depth++]; + var mapObject = {}; + var valuesByKey = {}; + + while (++i < n) { + var keyValue = keyFunction(array[i]); + var values = valuesByKey[keyValue]; + + if (values) { + values.push(array[i]); + } else { + valuesByKey[keyValue] = [array[i]]; + } + } + + each$1(valuesByKey, function(value, key) { + mapObject[key] = map$$1(value, depth); + }); + + return mapObject; + } + + /** + * transform the Map Object to multidimensional Array + * @param {Object} map + * @param {number} depth + */ + function entriesMap(mapObject, depth) { + if (depth >= keysFunction.length) { + return mapObject; + } + var array = []; + var sortKeyFunction = sortKeysFunction[depth++]; + + each$1(mapObject, function(value, key) { + array.push({ + key: key, + values: entriesMap(value, depth) + }); + }); + + if (sortKeyFunction) { + return array.sort(function(a, b) { + return sortKeyFunction(a.key, b.key); + }); + } else { + return array; + } + } + + return { + /** + * specified the key to groupby the arrays. + * users can specified one more keys. + * @param {Function} d + */ + key: function(d) { + keysFunction.push(d); + return this; + }, + + /** + * specified the comparator to sort the keys + * @param {Function} order + */ + sortKeys: function(order) { + sortKeysFunction[keysFunction.length - 1] = order; + return this; + }, + + /** + * the array to be grouped by. + * @param {Array} array + */ + entries: function(array) { + return entriesMap(map$$1(array, 0), 0); + } + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file The layout algorithm of sankey view + * @author Deqing Li(annong035@gmail.com) + */ + + var sankeyLayout = function(ecModel, api, payload) { + + ecModel.eachSeriesByType('sankey', function(seriesModel) { + + var nodeWidth = seriesModel.get('nodeWidth'); + var nodeGap = seriesModel.get('nodeGap'); + + var layoutInfo = getViewRect$3(seriesModel, api); + + seriesModel.layoutInfo = layoutInfo; + + var width = layoutInfo.width; + var height = layoutInfo.height; + + var graph = seriesModel.getGraph(); + + var nodes = graph.nodes; + var edges = graph.edges; + + computeNodeValues(nodes); + + var filteredNodes = filter(nodes, function(node) { + return node.getLayout().value === 0; + }); + + var iterations = filteredNodes.length !== 0 ? + 0 : seriesModel.get('layoutIterations'); + + layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations); + }); + }; + + /** + * Get the layout position of the whole view + * + * @param {module:echarts/model/Series} seriesModel the model object of sankey series + * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call + * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view + */ + function getViewRect$3(seriesModel, api) { + return getLayoutRect( + seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + } + + function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations) { + computeNodeBreadths(nodes, edges, nodeWidth, width); + computeNodeDepths(nodes, edges, height, nodeGap, iterations); + computeEdgeDepths(nodes); + } + + /** + * Compute the value of each node by summing the associated edge's value + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + */ + function computeNodeValues(nodes) { + each$1(nodes, function(node) { + var value1 = sum(node.outEdges, getEdgeValue); + var value2 = sum(node.inEdges, getEdgeValue); + var value = Math.max(value1, value2); + node.setLayout({ + value: value + }, true); + }); + } + + /** + * Compute the x-position for each node. + * + * Here we use Kahn algorithm to detect cycle when we traverse + * the node to computer the initial x position. + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + * @param {number} nodeWidth the dx of the node + * @param {number} width the whole width of the area to draw the view + */ + function computeNodeBreadths(nodes, edges, nodeWidth, width) { + // Used to mark whether the edge is deleted. if it is deleted, + // the value is 0, otherwise it is 1. + var remainEdges = []; + // Storage each node's indegree. + var indegreeArr = []; + //Used to storage the node with indegree is equal to 0. + var zeroIndegrees = []; + var nextNode = []; + var x = 0; + var kx = 0; + + for (var i = 0; i < edges.length; i++) { + remainEdges[i] = 1; + } + + for (var i = 0; i < nodes.length; i++) { + indegreeArr[i] = nodes[i].inEdges.length; + if (indegreeArr[i] === 0) { + zeroIndegrees.push(nodes[i]); + } + } + + while (zeroIndegrees.length) { + each$1(zeroIndegrees, function(node) { + node.setLayout({ + x: x + }, true); + node.setLayout({ + dx: nodeWidth + }, true); + each$1(node.outEdges, function(edge) { + var indexEdge = edges.indexOf(edge); + remainEdges[indexEdge] = 0; + var targetNode = edge.node2; + var nodeIndex = nodes.indexOf(targetNode); + if (--indegreeArr[nodeIndex] === 0) { + nextNode.push(targetNode); + } + }); + }); + + ++x; + zeroIndegrees = nextNode; + nextNode = []; + } + + for (var i = 0; i < remainEdges.length; i++) { + if (__DEV__) { + if (remainEdges[i] === 1) { + throw new Error('Sankey is a DAG, the original data has cycle!'); + } + } + } + + moveSinksRight(nodes, x); + kx = (width - nodeWidth) / (x - 1); + + scaleNodeBreadths(nodes, kx); + } + + /** + * All the node without outEgdes are assigned maximum x-position and + * be aligned in the last column. + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + * @param {number} x value (x-1) use to assign to node without outEdges + * as x-position + */ + function moveSinksRight(nodes, x) { + each$1(nodes, function(node) { + if (!node.outEdges.length) { + node.setLayout({ + x: x - 1 + }, true); + } + }); + } + + /** + * Scale node x-position to the width + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + * @param {number} kx multiple used to scale nodes + */ + function scaleNodeBreadths(nodes, kx) { + each$1(nodes, function(node) { + var nodeX = node.getLayout().x * kx; + node.setLayout({ + x: nodeX + }, true); + }); + } + + /** + * Using Gauss-Seidel iterations method to compute the node depth(y-position) + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + * @param {module:echarts/data/Graph~Edge} edges edge of sankey view + * @param {number} height the whole height of the area to draw the view + * @param {number} nodeGap the vertical distance between two nodes + * in the same column. + * @param {number} iterations the number of iterations for the algorithm + */ + function computeNodeDepths(nodes, edges, height, nodeGap, iterations) { + var nodesByBreadth = nest() + .key(function(d) { + return d.getLayout().x; + }) + .sortKeys(ascending) + .entries(nodes) + .map(function(d) { + return d.values; + }); + + initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap); + resolveCollisions(nodesByBreadth, nodeGap, height); + + for (var alpha = 1; iterations > 0; iterations--) { + // 0.99 is a experience parameter, ensure that each iterations of + // changes as small as possible. + alpha *= 0.99; + relaxRightToLeft(nodesByBreadth, alpha); + resolveCollisions(nodesByBreadth, nodeGap, height); + relaxLeftToRight(nodesByBreadth, alpha); + resolveCollisions(nodesByBreadth, nodeGap, height); + } + } + + /** + * Compute the original y-position for each node + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + * @param {Array.>} nodesByBreadth + * group by the array of all sankey nodes based on the nodes x-position. + * @param {module:echarts/data/Graph~Edge} edges edge of sankey view + * @param {number} height the whole height of the area to draw the view + * @param {number} nodeGap the vertical distance between two nodes + */ + function initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap) { + var kyArray = []; + each$1(nodesByBreadth, function(nodes) { + var n = nodes.length; + var sum = 0; + each$1(nodes, function(node) { + sum += node.getLayout().value; + }); + var ky = (height - (n - 1) * nodeGap) / sum; + kyArray.push(ky); + }); + + kyArray.sort(function(a, b) { + return a - b; + }); + var ky0 = kyArray[0]; + + each$1(nodesByBreadth, function(nodes) { + each$1(nodes, function(node, i) { + node.setLayout({ + y: i + }, true); + var nodeDy = node.getLayout().value * ky0; + node.setLayout({ + dy: nodeDy + }, true); + }); + }); + + each$1(edges, function(edge) { + var edgeDy = +edge.getValue() * ky0; + edge.setLayout({ + dy: edgeDy + }, true); + }); + } + + /** + * Resolve the collision of initialized depth (y-position) + * + * @param {Array.>} nodesByBreadth + * group by the array of all sankey nodes based on the nodes x-position. + * @param {number} nodeGap the vertical distance between two nodes + * @param {number} height the whole height of the area to draw the view + */ + function resolveCollisions(nodesByBreadth, nodeGap, height) { + each$1(nodesByBreadth, function(nodes) { + var node; + var dy; + var y0 = 0; + var n = nodes.length; + var i; + + nodes.sort(ascendingDepth); + + for (i = 0; i < n; i++) { + node = nodes[i]; + dy = y0 - node.getLayout().y; + if (dy > 0) { + var nodeY = node.getLayout().y + dy; + node.setLayout({ + y: nodeY + }, true); + } + y0 = node.getLayout().y + node.getLayout().dy + nodeGap; + } + + // If the bottommost node goes outside the bounds, push it back up + dy = y0 - nodeGap - height; + if (dy > 0) { + var nodeY = node.getLayout().y - dy; + node.setLayout({ + y: nodeY + }, true); + y0 = node.getLayout().y; + for (i = n - 2; i >= 0; --i) { + node = nodes[i]; + dy = node.getLayout().y + node.getLayout().dy + nodeGap - y0; + if (dy > 0) { + nodeY = node.getLayout().y - dy; + node.setLayout({ + y: nodeY + }, true); + } + y0 = node.getLayout().y; + } + } + }); + } + + /** + * Change the y-position of the nodes, except most the right side nodes + * + * @param {Array.>} nodesByBreadth + * group by the array of all sankey nodes based on the node x-position. + * @param {number} alpha parameter used to adjust the nodes y-position + */ + function relaxRightToLeft(nodesByBreadth, alpha) { + each$1(nodesByBreadth.slice().reverse(), function(nodes) { + each$1(nodes, function(node) { + if (node.outEdges.length) { + var y = sum(node.outEdges, weightedTarget) / sum(node.outEdges, getEdgeValue); + var nodeY = node.getLayout().y + (y - center$1(node)) * alpha; + node.setLayout({ + y: nodeY + }, true); + } + }); + }); + } + + function weightedTarget(edge) { + return center$1(edge.node2) * edge.getValue(); + } + + /** + * Change the y-position of the nodes, except most the left side nodes + * + * @param {Array.>} nodesByBreadth + * group by the array of all sankey nodes based on the node x-position. + * @param {number} alpha parameter used to adjust the nodes y-position + */ + function relaxLeftToRight(nodesByBreadth, alpha) { + each$1(nodesByBreadth, function(nodes) { + each$1(nodes, function(node) { + if (node.inEdges.length) { + var y = sum(node.inEdges, weightedSource) / sum(node.inEdges, getEdgeValue); + var nodeY = node.getLayout().y + (y - center$1(node)) * alpha; + node.setLayout({ + y: nodeY + }, true); + } + }); + }); + } + + function weightedSource(edge) { + return center$1(edge.node1) * edge.getValue(); + } + + /** + * Compute the depth(y-position) of each edge + * + * @param {module:echarts/data/Graph~Node} nodes node of sankey view + */ + function computeEdgeDepths(nodes) { + each$1(nodes, function(node) { + node.outEdges.sort(ascendingTargetDepth); + node.inEdges.sort(ascendingSourceDepth); + }); + each$1(nodes, function(node) { + var sy = 0; + var ty = 0; + each$1(node.outEdges, function(edge) { + edge.setLayout({ + sy: sy + }, true); + sy += edge.getLayout().dy; + }); + each$1(node.inEdges, function(edge) { + edge.setLayout({ + ty: ty + }, true); + ty += edge.getLayout().dy; + }); + }); + } + + function ascendingTargetDepth(a, b) { + return a.node2.getLayout().y - b.node2.getLayout().y; + } + + function ascendingSourceDepth(a, b) { + return a.node1.getLayout().y - b.node1.getLayout().y; + } + + function sum(array, f) { + var sum = 0; + var len = array.length; + var i = -1; + while (++i < len) { + var value = +f.call(array, array[i], i); + if (!isNaN(value)) { + sum += value; + } + } + return sum; + } + + function center$1(node) { + return node.getLayout().y + node.getLayout().dy / 2; + } + + function ascendingDepth(a, b) { + return a.getLayout().y - b.getLayout().y; + } + + function ascending(a, b) { + return a - b; + } + + function getEdgeValue(edge) { + return edge.getValue(); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Visual encoding for sankey view + * @author Deqing Li(annong035@gmail.com) + */ + + var sankeyVisual = function(ecModel, payload) { + ecModel.eachSeriesByType('sankey', function(seriesModel) { + var graph = seriesModel.getGraph(); + var nodes = graph.nodes; + if (nodes.length) { + var minValue = Infinity; + var maxValue = -Infinity; + each$1(nodes, function(node) { + var nodeValue = node.getLayout().value; + if (nodeValue < minValue) { + minValue = nodeValue; + } + if (nodeValue > maxValue) { + maxValue = nodeValue; + } + }); + + each$1(nodes, function(node) { + var mapping = new VisualMapping({ + type: 'color', + mappingMethod: 'linear', + dataExtent: [minValue, maxValue], + visual: seriesModel.get('color') + }); + + var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value); + node.setVisual('color', mapValueToColor); + // If set itemStyle.normal.color + var itemModel = node.getModel(); + var customColor = itemModel.get('itemStyle.color'); + if (customColor != null) { + node.setVisual('color', customColor); + } + }); + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerLayout(sankeyLayout); + registerVisual(sankeyVisual); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var seriesModelMixin = { + + /** + * @private + * @type {string} + */ + _baseAxisDim: null, + + /** + * @override + */ + getInitialData: function(option, ecModel) { + // When both types of xAxis and yAxis are 'value', layout is + // needed to be specified by user. Otherwise, layout can be + // judged by which axis is category. + + var ordinalMeta; + + var xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex')); + var yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex')); + var xAxisType = xAxisModel.get('type'); + var yAxisType = yAxisModel.get('type'); + var addOrdinal; + + // FIXME + // 考虑时间轴 + + if (xAxisType === 'category') { + option.layout = 'horizontal'; + ordinalMeta = xAxisModel.getOrdinalMeta(); + addOrdinal = true; + } else if (yAxisType === 'category') { + option.layout = 'vertical'; + ordinalMeta = yAxisModel.getOrdinalMeta(); + addOrdinal = true; + } else { + option.layout = option.layout || 'horizontal'; + } + + var coordDims = ['x', 'y']; + var baseAxisDimIndex = option.layout === 'horizontal' ? 0 : 1; + var baseAxisDim = this._baseAxisDim = coordDims[baseAxisDimIndex]; + var otherAxisDim = coordDims[1 - baseAxisDimIndex]; + var axisModels = [xAxisModel, yAxisModel]; + var baseAxisType = axisModels[baseAxisDimIndex].get('type'); + var otherAxisType = axisModels[1 - baseAxisDimIndex].get('type'); + var data = option.data; + + // ??? FIXME make a stage to perform data transfrom. + // MUST create a new data, consider setOption({}) again. + if (data && addOrdinal) { + var newOptionData = []; + each$1(data, function(item, index) { + var newItem; + if (item.value && isArray(item.value)) { + newItem = item.value.slice(); + item.value.unshift(index); + } else if (isArray(item)) { + newItem = item.slice(); + item.unshift(index); + } else { + newItem = item; + } + newOptionData.push(newItem); + }); + option.data = newOptionData; + } + + var defaultValueDimensions = this.defaultValueDimensions; + + return createListSimply( + this, { + coordDimensions: [{ + name: baseAxisDim, + type: getDimensionTypeByAxis(baseAxisType), + ordinalMeta: ordinalMeta, + otherDims: { + tooltip: false, + itemName: 0 + }, + dimsDef: ['base'] + }, { + name: otherAxisDim, + type: getDimensionTypeByAxis(otherAxisType), + dimsDef: defaultValueDimensions.slice() + }], + dimensionsCount: defaultValueDimensions.length + 1 + } + ); + }, + + /** + * If horizontal, base axis is x, otherwise y. + * @override + */ + getBaseAxis: function() { + var dim = this._baseAxisDim; + return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex')).axis; + } + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var BoxplotSeries = SeriesModel.extend({ + + type: 'series.boxplot', + + dependencies: ['xAxis', 'yAxis', 'grid'], + + // TODO + // box width represents group size, so dimension should have 'size'. + + /** + * @see + * The meanings of 'min' and 'max' depend on user, + * and echarts do not need to know it. + * @readOnly + */ + defaultValueDimensions: [{ + name: 'min', + defaultTooltip: true + }, + { + name: 'Q1', + defaultTooltip: true + }, + { + name: 'median', + defaultTooltip: true + }, + { + name: 'Q3', + defaultTooltip: true + }, + { + name: 'max', + defaultTooltip: true + } + ], + + /** + * @type {Array.} + * @readOnly + */ + dimensions: null, + + /** + * @override + */ + defaultOption: { + zlevel: 0, // 一级层叠 + z: 2, // 二级层叠 + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + + hoverAnimation: true, + + // xAxisIndex: 0, + // yAxisIndex: 0, + + layout: null, // 'horizontal' or 'vertical' + boxWidth: [7, 50], // [min, max] can be percent of band width. + + itemStyle: { + color: '#fff', + borderWidth: 1 + }, + + emphasis: { + itemStyle: { + borderWidth: 2, + shadowBlur: 5, + shadowOffsetX: 2, + shadowOffsetY: 2, + shadowColor: 'rgba(0,0,0,0.4)' + } + }, + + animationEasing: 'elasticOut', + animationDuration: 800 + } + }); + + mixin(BoxplotSeries, seriesModelMixin, true); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Update common properties + var NORMAL_ITEM_STYLE_PATH = ['itemStyle']; + var EMPHASIS_ITEM_STYLE_PATH = ['emphasis', 'itemStyle']; + + var BoxplotView = Chart.extend({ + + type: 'boxplot', + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var group = this.group; + var oldData = this._data; + + // There is no old data only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!this._data) { + group.removeAll(); + } + + var constDim = seriesModel.get('layout') === 'horizontal' ? 1 : 0; + + data.diff(oldData) + .add(function(newIdx) { + if (data.hasValue(newIdx)) { + var itemLayout = data.getItemLayout(newIdx); + var symbolEl = createNormalBox(itemLayout, data, newIdx, constDim, true); + data.setItemGraphicEl(newIdx, symbolEl); + group.add(symbolEl); + } + }) + .update(function(newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + + // Empty data + if (!data.hasValue(newIdx)) { + group.remove(symbolEl); + return; + } + + var itemLayout = data.getItemLayout(newIdx); + if (!symbolEl) { + symbolEl = createNormalBox(itemLayout, data, newIdx, constDim); + } else { + updateNormalBoxData(itemLayout, symbolEl, data, newIdx); + } + + group.add(symbolEl); + + data.setItemGraphicEl(newIdx, symbolEl); + }) + .remove(function(oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && group.remove(el); + }) + .execute(); + + this._data = data; + }, + + remove: function(ecModel) { + var group = this.group; + var data = this._data; + this._data = null; + data && data.eachItemGraphicEl(function(el) { + el && group.remove(el); + }); + }, + + dispose: noop + + }); + + + var BoxPath = Path.extend({ + + type: 'boxplotBoxPath', + + shape: {}, + + buildPath: function(ctx, shape) { + var ends = shape.points; + + var i = 0; + ctx.moveTo(ends[i][0], ends[i][1]); + i++; + for (; i < 4; i++) { + ctx.lineTo(ends[i][0], ends[i][1]); + } + ctx.closePath(); + + for (; i < ends.length; i++) { + ctx.moveTo(ends[i][0], ends[i][1]); + i++; + ctx.lineTo(ends[i][0], ends[i][1]); + } + } + }); + + + function createNormalBox(itemLayout, data, dataIndex, constDim, isInit) { + var ends = itemLayout.ends; + + var el = new BoxPath({ + shape: { + points: isInit ? + transInit(ends, constDim, itemLayout) : + ends + } + }); + + updateNormalBoxData(itemLayout, el, data, dataIndex, isInit); + + return el; + } + + function updateNormalBoxData(itemLayout, el, data, dataIndex, isInit) { + var seriesModel = data.hostModel; + var updateMethod = graphic[isInit ? 'initProps' : 'updateProps']; + + updateMethod( + el, { + shape: { + points: itemLayout.ends + } + }, + seriesModel, + dataIndex + ); + + var itemModel = data.getItemModel(dataIndex); + var normalItemStyleModel = itemModel.getModel(NORMAL_ITEM_STYLE_PATH); + var borderColor = data.getItemVisual(dataIndex, 'color'); + + // Exclude borderColor. + var itemStyle = normalItemStyleModel.getItemStyle(['borderColor']); + itemStyle.stroke = borderColor; + itemStyle.strokeNoScale = true; + el.useStyle(itemStyle); + + el.z2 = 100; + + var hoverStyle = itemModel.getModel(EMPHASIS_ITEM_STYLE_PATH).getItemStyle(); + setHoverStyle(el, hoverStyle); + } + + function transInit(points, dim, itemLayout) { + return map(points, function(point) { + point = point.slice(); + point[dim] = itemLayout.initBaseline; + return point; + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var borderColorQuery = ['itemStyle', 'borderColor']; + + var boxplotVisual = function(ecModel, api) { + + var globalColors = ecModel.get('color'); + + ecModel.eachRawSeriesByType('boxplot', function(seriesModel) { + + var defaulColor = globalColors[seriesModel.seriesIndex % globalColors.length]; + var data = seriesModel.getData(); + + data.setVisual({ + legendSymbol: 'roundRect', + // Use name 'color' but not 'borderColor' for legend usage and + // visual coding from other component like dataRange. + color: seriesModel.get(borderColorQuery) || defaulColor + }); + + // Only visible series has each data be visual encoded + if (!ecModel.isSeriesFiltered(seriesModel)) { + data.each(function(idx) { + var itemModel = data.getItemModel(idx); + data.setItemVisual( + idx, { + color: itemModel.get(borderColorQuery, true) + } + ); + }); + } + }); + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$13 = each$1; + + var boxplotLayout = function(ecModel) { + + var groupResult = groupSeriesByAxis(ecModel); + + each$13(groupResult, function(groupItem) { + var seriesModels = groupItem.seriesModels; + + if (!seriesModels.length) { + return; + } + + calculateBase(groupItem); + + each$13(seriesModels, function(seriesModel, idx) { + layoutSingleSeries( + seriesModel, + groupItem.boxOffsetList[idx], + groupItem.boxWidthList[idx] + ); + }); + }); + }; + + /** + * Group series by axis. + */ + function groupSeriesByAxis(ecModel) { + var result = []; + var axisList = []; + + ecModel.eachSeriesByType('boxplot', function(seriesModel) { + var baseAxis = seriesModel.getBaseAxis(); + var idx = indexOf(axisList, baseAxis); + + if (idx < 0) { + idx = axisList.length; + axisList[idx] = baseAxis; + result[idx] = { + axis: baseAxis, + seriesModels: [] + }; + } + + result[idx].seriesModels.push(seriesModel); + }); + + return result; + } + + /** + * Calculate offset and box width for each series. + */ + function calculateBase(groupItem) { + var extent; + var baseAxis = groupItem.axis; + var seriesModels = groupItem.seriesModels; + var seriesCount = seriesModels.length; + + var boxWidthList = groupItem.boxWidthList = []; + var boxOffsetList = groupItem.boxOffsetList = []; + var boundList = []; + + var bandWidth; + if (baseAxis.type === 'category') { + bandWidth = baseAxis.getBandWidth(); + } else { + var maxDataCount = 0; + each$13(seriesModels, function(seriesModel) { + maxDataCount = Math.max(maxDataCount, seriesModel.getData().count()); + }); + extent = baseAxis.getExtent(), + Math.abs(extent[1] - extent[0]) / maxDataCount; + } + + each$13(seriesModels, function(seriesModel) { + var boxWidthBound = seriesModel.get('boxWidth'); + if (!isArray(boxWidthBound)) { + boxWidthBound = [boxWidthBound, boxWidthBound]; + } + boundList.push([ + parsePercent$1(boxWidthBound[0], bandWidth) || 0, + parsePercent$1(boxWidthBound[1], bandWidth) || 0 + ]); + }); + + var availableWidth = bandWidth * 0.8 - 2; + var boxGap = availableWidth / seriesCount * 0.3; + var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount; + var base = boxWidth / 2 - availableWidth / 2; + + each$13(seriesModels, function(seriesModel, idx) { + boxOffsetList.push(base); + base += boxGap + boxWidth; + + boxWidthList.push( + Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1]) + ); + }); + } + + /** + * Calculate points location for each series. + */ + function layoutSingleSeries(seriesModel, offset, boxWidth) { + var coordSys = seriesModel.coordinateSystem; + var data = seriesModel.getData(); + var halfWidth = boxWidth / 2; + var cDimIdx = seriesModel.get('layout') === 'horizontal' ? 0 : 1; + var vDimIdx = 1 - cDimIdx; + var coordDims = ['x', 'y']; + var cDim = data.mapDimension(coordDims[cDimIdx]); + var vDims = data.mapDimension(coordDims[vDimIdx], true); + + if (cDim == null || vDims.length < 5) { + return; + } + + for (var dataIndex = 0; dataIndex < data.count(); dataIndex++) { + var axisDimVal = data.get(cDim, dataIndex); + + var median = getPoint(axisDimVal, vDims[2], dataIndex); + var end1 = getPoint(axisDimVal, vDims[0], dataIndex); + var end2 = getPoint(axisDimVal, vDims[1], dataIndex); + var end4 = getPoint(axisDimVal, vDims[3], dataIndex); + var end5 = getPoint(axisDimVal, vDims[4], dataIndex); + + var ends = []; + addBodyEnd(ends, end2, 0); + addBodyEnd(ends, end4, 1); + + ends.push(end1, end2, end5, end4); + layEndLine(ends, end1); + layEndLine(ends, end5); + layEndLine(ends, median); + + data.setItemLayout(dataIndex, { + initBaseline: median[vDimIdx], + ends: ends + }); + } + + function getPoint(axisDimVal, dimIdx, dataIndex) { + var val = data.get(dimIdx, dataIndex); + var p = []; + p[cDimIdx] = axisDimVal; + p[vDimIdx] = val; + var point; + if (isNaN(axisDimVal) || isNaN(val)) { + point = [NaN, NaN]; + } else { + point = coordSys.dataToPoint(p); + point[cDimIdx] += offset; + } + return point; + } + + function addBodyEnd(ends, point, start) { + var point1 = point.slice(); + var point2 = point.slice(); + point1[cDimIdx] += halfWidth; + point2[cDimIdx] -= halfWidth; + start + ? + ends.push(point1, point2) : + ends.push(point2, point1); + } + + function layEndLine(ends, endCenter) { + var from = endCenter.slice(); + var to = endCenter.slice(); + from[cDimIdx] -= halfWidth; + to[cDimIdx] += halfWidth; + ends.push(from, to); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(boxplotVisual); + registerLayout(boxplotLayout); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var CandlestickSeries = SeriesModel.extend({ + + type: 'series.candlestick', + + dependencies: ['xAxis', 'yAxis', 'grid'], + + /** + * @readOnly + */ + defaultValueDimensions: [{ + name: 'open', + defaultTooltip: true + }, + { + name: 'close', + defaultTooltip: true + }, + { + name: 'lowest', + defaultTooltip: true + }, + { + name: 'highest', + defaultTooltip: true + } + ], + + /** + * @type {Array.} + * @readOnly + */ + dimensions: null, + + /** + * @override + */ + defaultOption: { + zlevel: 0, + z: 2, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + + hoverAnimation: true, + + // xAxisIndex: 0, + // yAxisIndex: 0, + + layout: null, // 'horizontal' or 'vertical' + + itemStyle: { + color: '#c23531', // 阳线 positive + color0: '#314656', // 阴线 negative '#c23531', '#314656' + borderWidth: 1, + // FIXME + // ec2中使用的是lineStyle.color 和 lineStyle.color0 + borderColor: '#c23531', + borderColor0: '#314656' + }, + + emphasis: { + itemStyle: { + borderWidth: 2 + } + }, + + barMaxWidth: null, + barMinWidth: null, + barWidth: null, + + large: true, + largeThreshold: 600, + + progressive: 3e3, + progressiveThreshold: 1e4, + progressiveChunkMode: 'mod', + + animationUpdate: false, + animationEasing: 'linear', + animationDuration: 300 + }, + + /** + * Get dimension for shadow in dataZoom + * @return {string} dimension name + */ + getShadowDim: function() { + return 'open'; + }, + + brushSelector: function(dataIndex, data, selectors) { + var itemLayout = data.getItemLayout(dataIndex); + return itemLayout && selectors.rect(itemLayout.brushRect); + } + + }); + + mixin(CandlestickSeries, seriesModelMixin, true); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var NORMAL_ITEM_STYLE_PATH$1 = ['itemStyle']; + var EMPHASIS_ITEM_STYLE_PATH$1 = ['emphasis', 'itemStyle']; + var SKIP_PROPS = ['color', 'color0', 'borderColor', 'borderColor0']; + + + var CandlestickView = Chart.extend({ + + type: 'candlestick', + + render: function(seriesModel, ecModel, api) { + this._updateDrawMode(seriesModel); + + this._isLargeDraw ? + this._renderLarge(seriesModel) : + this._renderNormal(seriesModel); + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + this._clear(); + this._updateDrawMode(seriesModel); + }, + + incrementalRender: function(params, seriesModel, ecModel, api) { + this._isLargeDraw ? + this._incrementalRenderLarge(params, seriesModel) : + this._incrementalRenderNormal(params, seriesModel); + }, + + _updateDrawMode: function(seriesModel) { + var isLargeDraw = seriesModel.pipelineContext.large; + if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) { + this._isLargeDraw = isLargeDraw; + this._clear(); + } + }, + + _renderNormal: function(seriesModel) { + var data = seriesModel.getData(); + var oldData = this._data; + var group = this.group; + var isSimpleBox = data.getLayout('isSimpleBox'); + + // There is no old data only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!this._data) { + group.removeAll(); + } + + data.diff(oldData) + .add(function(newIdx) { + if (data.hasValue(newIdx)) { + var el; + + var itemLayout = data.getItemLayout(newIdx); + el = createNormalBox$1(itemLayout, newIdx, true); + initProps(el, { + shape: { + points: itemLayout.ends + } + }, seriesModel, newIdx); + + setBoxCommon(el, data, newIdx, isSimpleBox); + + group.add(el); + data.setItemGraphicEl(newIdx, el); + } + }) + .update(function(newIdx, oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + + // Empty data + if (!data.hasValue(newIdx)) { + group.remove(el); + return; + } + + var itemLayout = data.getItemLayout(newIdx); + if (!el) { + el = createNormalBox$1(itemLayout, newIdx); + } else { + updateProps(el, { + shape: { + points: itemLayout.ends + } + }, seriesModel, newIdx); + } + + setBoxCommon(el, data, newIdx, isSimpleBox); + + group.add(el); + data.setItemGraphicEl(newIdx, el); + }) + .remove(function(oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && group.remove(el); + }) + .execute(); + + this._data = data; + }, + + _renderLarge: function(seriesModel) { + this._clear(); + createLarge$1(seriesModel, this.group); + }, + + _incrementalRenderNormal: function(params, seriesModel) { + var data = seriesModel.getData(); + var isSimpleBox = data.getLayout('isSimpleBox'); + + var dataIndex; + while ((dataIndex = params.next()) != null) { + var el; + + var itemLayout = data.getItemLayout(dataIndex); + el = createNormalBox$1(itemLayout, dataIndex); + setBoxCommon(el, data, dataIndex, isSimpleBox); + + el.incremental = true; + this.group.add(el); + } + }, + + _incrementalRenderLarge: function(params, seriesModel) { + createLarge$1(seriesModel, this.group, true); + }, + + remove: function(ecModel) { + this._clear(); + }, + + _clear: function() { + this.group.removeAll(); + this._data = null; + }, + + dispose: noop + + }); + + + var NormalBoxPath = Path.extend({ + + type: 'normalCandlestickBox', + + shape: {}, + + buildPath: function(ctx, shape) { + var ends = shape.points; + + if (this.__simpleBox) { + ctx.moveTo(ends[4][0], ends[4][1]); + ctx.lineTo(ends[6][0], ends[6][1]); + } else { + ctx.moveTo(ends[0][0], ends[0][1]); + ctx.lineTo(ends[1][0], ends[1][1]); + ctx.lineTo(ends[2][0], ends[2][1]); + ctx.lineTo(ends[3][0], ends[3][1]); + ctx.closePath(); + + ctx.moveTo(ends[4][0], ends[4][1]); + ctx.lineTo(ends[5][0], ends[5][1]); + ctx.moveTo(ends[6][0], ends[6][1]); + ctx.lineTo(ends[7][0], ends[7][1]); + } + } + }); + + function createNormalBox$1(itemLayout, dataIndex, isInit) { + var ends = itemLayout.ends; + return new NormalBoxPath({ + shape: { + points: isInit ? + transInit$1(ends, itemLayout) : + ends + }, + z2: 100 + }); + } + + function setBoxCommon(el, data, dataIndex, isSimpleBox) { + var itemModel = data.getItemModel(dataIndex); + var normalItemStyleModel = itemModel.getModel(NORMAL_ITEM_STYLE_PATH$1); + var color = data.getItemVisual(dataIndex, 'color'); + var borderColor = data.getItemVisual(dataIndex, 'borderColor') || color; + + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + var itemStyle = normalItemStyleModel.getItemStyle(SKIP_PROPS); + + el.useStyle(itemStyle); + el.style.strokeNoScale = true; + el.style.fill = color; + el.style.stroke = borderColor; + + el.__simpleBox = isSimpleBox; + + var hoverStyle = itemModel.getModel(EMPHASIS_ITEM_STYLE_PATH$1).getItemStyle(); + setHoverStyle(el, hoverStyle); + } + + function transInit$1(points, itemLayout) { + return map(points, function(point) { + point = point.slice(); + point[1] = itemLayout.initBaseline; + return point; + }); + } + + + + var LargeBoxPath = Path.extend({ + + type: 'largeCandlestickBox', + + shape: {}, + + buildPath: function(ctx, shape) { + // Drawing lines is more efficient than drawing + // a whole line or drawing rects. + var points = shape.points; + for (var i = 0; i < points.length;) { + if (this.__sign === points[i++]) { + var x = points[i++]; + ctx.moveTo(x, points[i++]); + ctx.lineTo(x, points[i++]); + } else { + i += 3; + } + } + } + }); + + function createLarge$1(seriesModel, group, incremental) { + var data = seriesModel.getData(); + var largePoints = data.getLayout('largePoints'); + + var elP = new LargeBoxPath({ + shape: { + points: largePoints + }, + __sign: 1 + }); + group.add(elP); + var elN = new LargeBoxPath({ + shape: { + points: largePoints + }, + __sign: -1 + }); + group.add(elN); + + setLargeStyle$1(1, elP, seriesModel, data); + setLargeStyle$1(-1, elN, seriesModel, data); + + if (incremental) { + elP.incremental = true; + elN.incremental = true; + } + } + + function setLargeStyle$1(sign, el, seriesModel, data) { + var suffix = sign > 0 ? 'P' : 'N'; + var borderColor = data.getVisual('borderColor' + suffix) || + data.getVisual('color' + suffix); + + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + var itemStyle = seriesModel.getModel(NORMAL_ITEM_STYLE_PATH$1).getItemStyle(SKIP_PROPS); + + el.useStyle(itemStyle); + el.style.fill = null; + el.style.stroke = borderColor; + // No different + // el.style.lineWidth = .5; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var preprocessor = function(option) { + if (!option || !isArray(option.series)) { + return; + } + + // Translate 'k' to 'candlestick'. + each$1(option.series, function(seriesItem) { + if (isObject$1(seriesItem) && seriesItem.type === 'k') { + seriesItem.type = 'candlestick'; + } + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var positiveBorderColorQuery = ['itemStyle', 'borderColor']; + var negativeBorderColorQuery = ['itemStyle', 'borderColor0']; + var positiveColorQuery = ['itemStyle', 'color']; + var negativeColorQuery = ['itemStyle', 'color0']; + + var candlestickVisual = { + + seriesType: 'candlestick', + + plan: createRenderPlanner(), + + // For legend. + performRawSeries: true, + + reset: function(seriesModel, ecModel) { + + var data = seriesModel.getData(); + var isLargeRender = seriesModel.pipelineContext.large; + + data.setVisual({ + legendSymbol: 'roundRect', + colorP: getColor(1, seriesModel), + colorN: getColor(-1, seriesModel), + borderColorP: getBorderColor(1, seriesModel), + borderColorN: getBorderColor(-1, seriesModel) + }); + + // Only visible series has each data be visual encoded + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + + return !isLargeRender && { + progress: progress + }; + + + function progress(params, data) { + var dataIndex; + while ((dataIndex = params.next()) != null) { + var itemModel = data.getItemModel(dataIndex); + var sign = data.getItemLayout(dataIndex).sign; + + data.setItemVisual( + dataIndex, { + color: getColor(sign, itemModel), + borderColor: getBorderColor(sign, itemModel) + } + ); + } + } + + function getColor(sign, model) { + return model.get( + sign > 0 ? positiveColorQuery : negativeColorQuery + ); + } + + function getBorderColor(sign, model) { + return model.get( + sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery + ); + } + + } + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var LargeArr$1 = typeof Float32Array !== 'undefined' ? Float32Array : Array; + + var candlestickLayout = { + + seriesType: 'candlestick', + + plan: createRenderPlanner(), + + reset: function(seriesModel) { + + var coordSys = seriesModel.coordinateSystem; + var data = seriesModel.getData(); + var candleWidth = calculateCandleWidth(seriesModel, data); + var cDimIdx = 0; + var vDimIdx = 1; + var coordDims = ['x', 'y']; + var cDim = data.mapDimension(coordDims[cDimIdx]); + var vDims = data.mapDimension(coordDims[vDimIdx], true); + var openDim = vDims[0]; + var closeDim = vDims[1]; + var lowestDim = vDims[2]; + var highestDim = vDims[3]; + + data.setLayout({ + candleWidth: candleWidth, + // The value is experimented visually. + isSimpleBox: candleWidth <= 1.3 + }); + + if (cDim == null || vDims.length < 4) { + return; + } + + return { + progress: seriesModel.pipelineContext.large ? + largeProgress : normalProgress + }; + + function normalProgress(params, data) { + var dataIndex; + while ((dataIndex = params.next()) != null) { + + var axisDimVal = data.get(cDim, dataIndex); + var openVal = data.get(openDim, dataIndex); + var closeVal = data.get(closeDim, dataIndex); + var lowestVal = data.get(lowestDim, dataIndex); + var highestVal = data.get(highestDim, dataIndex); + + var ocLow = Math.min(openVal, closeVal); + var ocHigh = Math.max(openVal, closeVal); + + var ocLowPoint = getPoint(ocLow, axisDimVal); + var ocHighPoint = getPoint(ocHigh, axisDimVal); + var lowestPoint = getPoint(lowestVal, axisDimVal); + var highestPoint = getPoint(highestVal, axisDimVal); + + var ends = []; + addBodyEnd(ends, ocHighPoint, 0); + addBodyEnd(ends, ocLowPoint, 1); + + ends.push( + subPixelOptimizePoint(highestPoint), + subPixelOptimizePoint(ocHighPoint), + subPixelOptimizePoint(lowestPoint), + subPixelOptimizePoint(ocLowPoint) + ); + + data.setItemLayout(dataIndex, { + sign: getSign(data, dataIndex, openVal, closeVal, closeDim), + initBaseline: openVal > closeVal ? + ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx], // open point. + ends: ends, + brushRect: makeBrushRect(lowestVal, highestVal, axisDimVal) + }); + } + + function getPoint(val, axisDimVal) { + var p = []; + p[cDimIdx] = axisDimVal; + p[vDimIdx] = val; + return (isNaN(axisDimVal) || isNaN(val)) ? + [NaN, NaN] : + coordSys.dataToPoint(p); + } + + function addBodyEnd(ends, point, start) { + var point1 = point.slice(); + var point2 = point.slice(); + + point1[cDimIdx] = subPixelOptimize( + point1[cDimIdx] + candleWidth / 2, 1, false + ); + point2[cDimIdx] = subPixelOptimize( + point2[cDimIdx] - candleWidth / 2, 1, true + ); + + start + ? + ends.push(point1, point2) : + ends.push(point2, point1); + } + + function makeBrushRect(lowestVal, highestVal, axisDimVal) { + var pmin = getPoint(lowestVal, axisDimVal); + var pmax = getPoint(highestVal, axisDimVal); + + pmin[cDimIdx] -= candleWidth / 2; + pmax[cDimIdx] -= candleWidth / 2; + + return { + x: pmin[0], + y: pmin[1], + width: vDimIdx ? candleWidth : pmax[0] - pmin[0], + height: vDimIdx ? pmax[1] - pmin[1] : candleWidth + }; + } + + function subPixelOptimizePoint(point) { + point[cDimIdx] = subPixelOptimize(point[cDimIdx], 1); + return point; + } + } + + function largeProgress(params, data) { + // Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...] + var points = new LargeArr$1(params.count * 5); + var offset = 0; + var point; + var tmpIn = []; + var tmpOut = []; + var dataIndex; + + while ((dataIndex = params.next()) != null) { + var axisDimVal = data.get(cDim, dataIndex); + var openVal = data.get(openDim, dataIndex); + var closeVal = data.get(closeDim, dataIndex); + var lowestVal = data.get(lowestDim, dataIndex); + var highestVal = data.get(highestDim, dataIndex); + + if (isNaN(axisDimVal) || isNaN(lowestVal) || isNaN(highestVal)) { + points[offset++] = NaN; + offset += 4; + continue; + } + + points[offset++] = getSign(data, dataIndex, openVal, closeVal, closeDim); + + tmpIn[cDimIdx] = axisDimVal; + + tmpIn[vDimIdx] = lowestVal; + point = coordSys.dataToPoint(tmpIn, null, tmpOut); + points[offset++] = point ? point[0] : NaN; + points[offset++] = point ? point[1] : NaN; + tmpIn[vDimIdx] = highestVal; + point = coordSys.dataToPoint(tmpIn, null, tmpOut); + points[offset++] = point ? point[1] : NaN; + } + + data.setLayout('largePoints', points); + } + } + }; + + function getSign(data, dataIndex, openVal, closeVal, closeDim) { + var sign; + if (openVal > closeVal) { + sign = -1; + } else if (openVal < closeVal) { + sign = 1; + } else { + sign = dataIndex > 0 + // If close === open, compare with close of last record + ? + (data.get(closeDim, dataIndex - 1) <= closeVal ? 1 : -1) + // No record of previous, set to be positive + : + 1; + } + + return sign; + } + + function calculateCandleWidth(seriesModel, data) { + var baseAxis = seriesModel.getBaseAxis(); + var extent; + + var bandWidth = baseAxis.type === 'category' ? + baseAxis.getBandWidth() : + ( + extent = baseAxis.getExtent(), + Math.abs(extent[1] - extent[0]) / data.count() + ); + + var barMaxWidth = parsePercent$1( + retrieve2(seriesModel.get('barMaxWidth'), bandWidth), + bandWidth + ); + var barMinWidth = parsePercent$1( + retrieve2(seriesModel.get('barMinWidth'), 1), + bandWidth + ); + var barWidth = seriesModel.get('barWidth'); + + return barWidth != null ? + parsePercent$1(barWidth, bandWidth) + // Put max outer to ensure bar visible in spite of overlap. + : + Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerPreprocessor(preprocessor); + registerVisual(candlestickVisual); + registerLayout(candlestickLayout); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.effectScatter', + + dependencies: ['grid', 'polar'], + + getInitialData: function(option, ecModel) { + return createListFromArray(this.getSource(), this); + }, + + brushSelector: 'point', + + defaultOption: { + coordinateSystem: 'cartesian2d', + zlevel: 0, + z: 2, + legendHoverLink: true, + + effectType: 'ripple', + + progressive: 0, + + // When to show the effect, option: 'render'|'emphasis' + showEffectOn: 'render', + + // Ripple effect config + rippleEffect: { + period: 4, + // Scale of ripple + scale: 2.5, + // Brush type can be fill or stroke + brushType: 'fill' + }, + + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + + // Polar coordinate system + // polarIndex: 0, + + // Geo coordinate system + // geoIndex: 0, + + // symbol: null, // 图形类型 + symbolSize: 10 // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 + // symbolRotate: null, // 图形旋转控制 + + // large: false, + // Available when large is true + // largeThreshold: 2000, + + // itemStyle: { + // opacity: 1 + // } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Symbol with ripple effect + * @module echarts/chart/helper/EffectSymbol + */ + + var EFFECT_RIPPLE_NUMBER = 3; + + function normalizeSymbolSize$1(symbolSize) { + if (!isArray(symbolSize)) { + symbolSize = [+symbolSize, +symbolSize]; + } + return symbolSize; + } + + function updateRipplePath(rippleGroup, effectCfg) { + rippleGroup.eachChild(function(ripplePath) { + ripplePath.attr({ + z: effectCfg.z, + zlevel: effectCfg.zlevel, + style: { + stroke: effectCfg.brushType === 'stroke' ? effectCfg.color : null, + fill: effectCfg.brushType === 'fill' ? effectCfg.color : null + } + }); + }); + } + /** + * @constructor + * @param {module:echarts/data/List} data + * @param {number} idx + * @extends {module:zrender/graphic/Group} + */ + function EffectSymbol(data, idx) { + Group.call(this); + + var symbol = new SymbolClz$1(data, idx); + var rippleGroup = new Group(); + this.add(symbol); + this.add(rippleGroup); + + rippleGroup.beforeUpdate = function() { + this.attr(symbol.getScale()); + }; + this.updateData(data, idx); + } + + var effectSymbolProto = EffectSymbol.prototype; + + effectSymbolProto.stopEffectAnimation = function() { + this.childAt(1).removeAll(); + }; + + effectSymbolProto.startEffectAnimation = function(effectCfg) { + var symbolType = effectCfg.symbolType; + var color = effectCfg.color; + var rippleGroup = this.childAt(1); + + for (var i = 0; i < EFFECT_RIPPLE_NUMBER; i++) { + // var ripplePath = createSymbol( + // symbolType, -0.5, -0.5, 1, 1, color + // ); + // If width/height are set too small (e.g., set to 1) on ios10 + // and macOS Sierra, a circle stroke become a rect, no matter what + // the scale is set. So we set width/height as 2. See #4136. + var ripplePath = createSymbol( + symbolType, -1, -1, 2, 2, color + ); + ripplePath.attr({ + style: { + strokeNoScale: true + }, + z2: 99, + silent: true, + scale: [0.5, 0.5] + }); + + var delay = -i / EFFECT_RIPPLE_NUMBER * effectCfg.period + effectCfg.effectOffset; + // TODO Configurable effectCfg.period + ripplePath.animate('', true) + .when(effectCfg.period, { + scale: [effectCfg.rippleScale / 2, effectCfg.rippleScale / 2] + }) + .delay(delay) + .start(); + ripplePath.animateStyle(true) + .when(effectCfg.period, { + opacity: 0 + }) + .delay(delay) + .start(); + + rippleGroup.add(ripplePath); + } + + updateRipplePath(rippleGroup, effectCfg); + }; + + /** + * Update effect symbol + */ + effectSymbolProto.updateEffectAnimation = function(effectCfg) { + var oldEffectCfg = this._effectCfg; + var rippleGroup = this.childAt(1); + + // Must reinitialize effect if following configuration changed + var DIFFICULT_PROPS = ['symbolType', 'period', 'rippleScale']; + for (var i = 0; i < DIFFICULT_PROPS.length; i++) { + var propName = DIFFICULT_PROPS[i]; + if (oldEffectCfg[propName] !== effectCfg[propName]) { + this.stopEffectAnimation(); + this.startEffectAnimation(effectCfg); + return; + } + } + + updateRipplePath(rippleGroup, effectCfg); + }; + + /** + * Highlight symbol + */ + effectSymbolProto.highlight = function() { + this.trigger('emphasis'); + }; + + /** + * Downplay symbol + */ + effectSymbolProto.downplay = function() { + this.trigger('normal'); + }; + + /** + * Update symbol properties + * @param {module:echarts/data/List} data + * @param {number} idx + */ + effectSymbolProto.updateData = function(data, idx) { + var seriesModel = data.hostModel; + + this.childAt(0).updateData(data, idx); + + var rippleGroup = this.childAt(1); + var itemModel = data.getItemModel(idx); + var symbolType = data.getItemVisual(idx, 'symbol'); + var symbolSize = normalizeSymbolSize$1(data.getItemVisual(idx, 'symbolSize')); + var color = data.getItemVisual(idx, 'color'); + + rippleGroup.attr('scale', symbolSize); + + rippleGroup.traverse(function(ripplePath) { + ripplePath.attr({ + fill: color + }); + }); + + var symbolOffset = itemModel.getShallow('symbolOffset'); + if (symbolOffset) { + var pos = rippleGroup.position; + pos[0] = parsePercent$1(symbolOffset[0], symbolSize[0]); + pos[1] = parsePercent$1(symbolOffset[1], symbolSize[1]); + } + rippleGroup.rotation = (itemModel.getShallow('symbolRotate') || 0) * Math.PI / 180 || 0; + + var effectCfg = {}; + + effectCfg.showEffectOn = seriesModel.get('showEffectOn'); + effectCfg.rippleScale = itemModel.get('rippleEffect.scale'); + effectCfg.brushType = itemModel.get('rippleEffect.brushType'); + effectCfg.period = itemModel.get('rippleEffect.period') * 1000; + effectCfg.effectOffset = idx / data.count(); + effectCfg.z = itemModel.getShallow('z') || 0; + effectCfg.zlevel = itemModel.getShallow('zlevel') || 0; + effectCfg.symbolType = symbolType; + effectCfg.color = color; + + this.off('mouseover').off('mouseout').off('emphasis').off('normal'); + + if (effectCfg.showEffectOn === 'render') { + this._effectCfg ? + this.updateEffectAnimation(effectCfg) : + this.startEffectAnimation(effectCfg); + + this._effectCfg = effectCfg; + } else { + // Not keep old effect config + this._effectCfg = null; + + this.stopEffectAnimation(); + var symbol = this.childAt(0); + var onEmphasis = function() { + symbol.highlight(); + if (effectCfg.showEffectOn !== 'render') { + this.startEffectAnimation(effectCfg); + } + }; + var onNormal = function() { + symbol.downplay(); + if (effectCfg.showEffectOn !== 'render') { + this.stopEffectAnimation(); + } + }; + this.on('mouseover', onEmphasis, this) + .on('mouseout', onNormal, this) + .on('emphasis', onEmphasis, this) + .on('normal', onNormal, this); + } + + this._effectCfg = effectCfg; + }; + + effectSymbolProto.fadeOut = function(cb) { + this.off('mouseover').off('mouseout').off('emphasis').off('normal'); + cb && cb(); + }; + + inherits(EffectSymbol, Group); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendChartView({ + + type: 'effectScatter', + + init: function() { + this._symbolDraw = new SymbolDraw(EffectSymbol); + }, + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var effectSymbolDraw = this._symbolDraw; + effectSymbolDraw.updateData(data); + this.group.add(effectSymbolDraw.group); + }, + + updateTransform: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + this.group.dirty(); + + var res = pointsLayout().reset(seriesModel); + if (res.progress) { + res.progress({ + start: 0, + end: data.count() + }, data); + } + + this._symbolDraw.updateLayout(data); + }, + + _updateGroupTransform: function(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.getRoamTransform) { + this.group.transform = clone$2(coordSys.getRoamTransform()); + this.group.decomposeTransform(); + } + }, + + remove: function(ecModel, api) { + this._symbolDraw && this._symbolDraw.remove(api); + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(visualSymbol('effectScatter', 'circle')); + registerLayout(pointsLayout('effectScatter')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var Uint32Arr = typeof Uint32Array === 'undefined' ? Array : Uint32Array; + var Float64Arr = typeof Float64Array === 'undefined' ? Array : Float64Array; + + function compatEc2(seriesOpt) { + var data = seriesOpt.data; + if (data && data[0] && data[0][0] && data[0][0].coord) { + if (__DEV__) { + console.warn('Lines data configuration has been changed to' + + ' { coords:[[1,2],[2,3]] }'); + } + seriesOpt.data = map(data, function(itemOpt) { + var coords = [ + itemOpt[0].coord, itemOpt[1].coord + ]; + var target = { + coords: coords + }; + if (itemOpt[0].name) { + target.fromName = itemOpt[0].name; + } + if (itemOpt[1].name) { + target.toName = itemOpt[1].name; + } + return mergeAll([target, itemOpt[0], itemOpt[1]]); + }); + } + } + + var LinesSeries = SeriesModel.extend({ + + type: 'series.lines', + + dependencies: ['grid', 'polar'], + + visualColorAccessPath: 'lineStyle.color', + + init: function(option) { + // The input data may be null/undefined. + option.data = option.data || []; + + // Not using preprocessor because mergeOption may not have series.type + compatEc2(option); + + var result = this._processFlatCoordsArray(option.data); + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + if (result.flatCoords) { + option.data = new Float32Array(result.count); + } + + LinesSeries.superApply(this, 'init', arguments); + }, + + mergeOption: function(option) { + // The input data may be null/undefined. + option.data = option.data || []; + + compatEc2(option); + + if (option.data) { + // Only update when have option data to merge. + var result = this._processFlatCoordsArray(option.data); + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + if (result.flatCoords) { + option.data = new Float32Array(result.count); + } + } + + LinesSeries.superApply(this, 'mergeOption', arguments); + }, + + appendData: function(params) { + var result = this._processFlatCoordsArray(params.data); + if (result.flatCoords) { + if (!this._flatCoords) { + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + } else { + this._flatCoords = concatArray(this._flatCoords, result.flatCoords); + this._flatCoordsOffset = concatArray(this._flatCoordsOffset, result.flatCoordsOffset); + } + params.data = new Float32Array(result.count); + } + + this.getRawData().appendData(params.data); + }, + + _getCoordsFromItemModel: function(idx) { + var itemModel = this.getData().getItemModel(idx); + var coords = (itemModel.option instanceof Array) ? + itemModel.option : itemModel.getShallow('coords'); + + if (__DEV__) { + if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) { + throw new Error('Invalid coords ' + JSON.stringify(coords) + + '. Lines must have 2d coords array in data item.'); + } + } + return coords; + }, + + getLineCoordsCount: function(idx) { + if (this._flatCoordsOffset) { + return this._flatCoordsOffset[idx * 2 + 1]; + } else { + return this._getCoordsFromItemModel(idx).length; + } + }, + + getLineCoords: function(idx, out) { + if (this._flatCoordsOffset) { + var offset = this._flatCoordsOffset[idx * 2]; + var len = this._flatCoordsOffset[idx * 2 + 1]; + for (var i = 0; i < len; i++) { + out[i] = out[i] || []; + out[i][0] = this._flatCoords[offset + i * 2]; + out[i][1] = this._flatCoords[offset + i * 2 + 1]; + } + return len; + } else { + var coords = this._getCoordsFromItemModel(idx); + for (var i = 0; i < coords.length; i++) { + out[i] = out[i] || []; + out[i][0] = coords[i][0]; + out[i][1] = coords[i][1]; + } + return coords.length; + } + }, + + _processFlatCoordsArray: function(data) { + var startOffset = 0; + if (this._flatCoords) { + startOffset = this._flatCoords.length; + } + // Stored as a typed array. In format + // Points Count(2) | x | y | x | y | Points Count(3) | x | y | x | y | x | y | + if (typeof data[0] === 'number') { + var len = data.length; + // Store offset and len of each segment + var coordsOffsetAndLenStorage = new Uint32Arr(len); + var coordsStorage = new Float64Arr(len); + var coordsCursor = 0; + var offsetCursor = 0; + var dataCount = 0; + for (var i = 0; i < len;) { + dataCount++; + var count = data[i++]; + // Offset + coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset; + // Len + coordsOffsetAndLenStorage[offsetCursor++] = count; + for (var k = 0; k < count; k++) { + var x = data[i++]; + var y = data[i++]; + coordsStorage[coordsCursor++] = x; + coordsStorage[coordsCursor++] = y; + + if (i > len) { + if (__DEV__) { + throw new Error('Invalid data format.'); + } + } + } + } + + return { + flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor), + flatCoords: coordsStorage, + count: dataCount + }; + } + + return { + flatCoordsOffset: null, + flatCoords: null, + count: data.length + }; + }, + + getInitialData: function(option, ecModel) { + if (__DEV__) { + var CoordSys = CoordinateSystemManager.get(option.coordinateSystem); + if (!CoordSys) { + throw new Error('Unkown coordinate system ' + option.coordinateSystem); + } + } + + var lineData = new List(['value'], this); + lineData.hasItemOption = false; + + lineData.initData(option.data, [], function(dataItem, dimName, dataIndex, dimIndex) { + // dataItem is simply coords + if (dataItem instanceof Array) { + return NaN; + } else { + lineData.hasItemOption = true; + var value = dataItem.value; + if (value != null) { + return value instanceof Array ? value[dimIndex] : value; + } + } + }); + + return lineData; + }, + + formatTooltip: function(dataIndex) { + var data = this.getData(); + var itemModel = data.getItemModel(dataIndex); + var name = itemModel.get('name'); + if (name) { + return name; + } + var fromName = itemModel.get('fromName'); + var toName = itemModel.get('toName'); + var html = []; + fromName != null && html.push(fromName); + toName != null && html.push(toName); + + return encodeHTML(html.join(' > ')); + }, + + preventIncremental: function() { + return !!this.get('effect.show'); + }, + + getProgressive: function() { + var progressive = this.option.progressive; + if (progressive == null) { + return this.option.large ? 1e4 : this.get('progressive'); + } + return progressive; + }, + + getProgressiveThreshold: function() { + var progressiveThreshold = this.option.progressiveThreshold; + if (progressiveThreshold == null) { + return this.option.large ? 2e4 : this.get('progressiveThreshold'); + } + return progressiveThreshold; + }, + + defaultOption: { + coordinateSystem: 'geo', + zlevel: 0, + z: 2, + legendHoverLink: true, + + hoverAnimation: true, + // Cartesian coordinate system + xAxisIndex: 0, + yAxisIndex: 0, + + symbol: ['none', 'none'], + symbolSize: [10, 10], + // Geo coordinate system + geoIndex: 0, + + effect: { + show: false, + period: 4, + // Animation delay. support callback + // delay: 0, + // If move with constant speed px/sec + // period will be ignored if this property is > 0, + constantSpeed: 0, + symbol: 'circle', + symbolSize: 3, + loop: true, + // Length of trail, 0 - 1 + trailLength: 0.2 + // Same with lineStyle.color + // color + }, + + large: false, + // Available when large is true + largeThreshold: 2000, + + // If lines are polyline + // polyline not support curveness, label, animation + polyline: false, + + label: { + show: false, + position: 'end' + // distance: 5, + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + }, + + lineStyle: { + opacity: 0.5 + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Provide effect for line + * @module echarts/chart/helper/EffectLine + */ + + /** + * @constructor + * @extends {module:zrender/graphic/Group} + * @alias {module:echarts/chart/helper/Line} + */ + function EffectLine(lineData, idx, seriesScope) { + Group.call(this); + + this.add(this.createLine(lineData, idx, seriesScope)); + + this._updateEffectSymbol(lineData, idx); + } + + var effectLineProto = EffectLine.prototype; + + effectLineProto.createLine = function(lineData, idx, seriesScope) { + return new Line$1(lineData, idx, seriesScope); + }; + + effectLineProto._updateEffectSymbol = function(lineData, idx) { + var itemModel = lineData.getItemModel(idx); + var effectModel = itemModel.getModel('effect'); + var size = effectModel.get('symbolSize'); + var symbolType = effectModel.get('symbol'); + if (!isArray(size)) { + size = [size, size]; + } + var color = effectModel.get('color') || lineData.getItemVisual(idx, 'color'); + var symbol = this.childAt(1); + + if (this._symbolType !== symbolType) { + // Remove previous + this.remove(symbol); + + symbol = createSymbol( + symbolType, -0.5, -0.5, 1, 1, color + ); + symbol.z2 = 100; + symbol.culling = true; + + this.add(symbol); + } + + // Symbol may be removed if loop is false + if (!symbol) { + return; + } + + // Shadow color is same with color in default + symbol.setStyle('shadowColor', color); + symbol.setStyle(effectModel.getItemStyle(['color'])); + + symbol.attr('scale', size); + + symbol.setColor(color); + symbol.attr('scale', size); + + this._symbolType = symbolType; + + this._updateEffectAnimation(lineData, effectModel, idx); + }; + + effectLineProto._updateEffectAnimation = function(lineData, effectModel, idx) { + + var symbol = this.childAt(1); + if (!symbol) { + return; + } + + var self = this; + + var points = lineData.getItemLayout(idx); + + var period = effectModel.get('period') * 1000; + var loop = effectModel.get('loop'); + var constantSpeed = effectModel.get('constantSpeed'); + var delayExpr = retrieve(effectModel.get('delay'), function(idx) { + return idx / lineData.count() * period / 3; + }); + var isDelayFunc = typeof delayExpr === 'function'; + + // Ignore when updating + symbol.ignore = true; + + this.updateAnimationPoints(symbol, points); + + if (constantSpeed > 0) { + period = this.getLineLength(symbol) / constantSpeed * 1000; + } + + if (period !== this._period || loop !== this._loop) { + + symbol.stopAnimation(); + + var delay = delayExpr; + if (isDelayFunc) { + delay = delayExpr(idx); + } + if (symbol.__t > 0) { + delay = -period * symbol.__t; + } + symbol.__t = 0; + var animator = symbol.animate('', loop) + .when(period, { + __t: 1 + }) + .delay(delay) + .during(function() { + self.updateSymbolPosition(symbol); + }); + if (!loop) { + animator.done(function() { + self.remove(symbol); + }); + } + animator.start(); + } + + this._period = period; + this._loop = loop; + }; + + effectLineProto.getLineLength = function(symbol) { + // Not so accurate + return (dist(symbol.__p1, symbol.__cp1) + + dist(symbol.__cp1, symbol.__p2)); + }; + + effectLineProto.updateAnimationPoints = function(symbol, points) { + symbol.__p1 = points[0]; + symbol.__p2 = points[1]; + symbol.__cp1 = points[2] || [ + (points[0][0] + points[1][0]) / 2, + (points[0][1] + points[1][1]) / 2 + ]; + }; + + effectLineProto.updateData = function(lineData, idx, seriesScope) { + this.childAt(0).updateData(lineData, idx, seriesScope); + this._updateEffectSymbol(lineData, idx); + }; + + effectLineProto.updateSymbolPosition = function(symbol) { + var p1 = symbol.__p1; + var p2 = symbol.__p2; + var cp1 = symbol.__cp1; + var t = symbol.__t; + var pos = symbol.position; + var quadraticAt$$1 = quadraticAt; + var quadraticDerivativeAt$$1 = quadraticDerivativeAt; + pos[0] = quadraticAt$$1(p1[0], cp1[0], p2[0], t); + pos[1] = quadraticAt$$1(p1[1], cp1[1], p2[1], t); + + // Tangent + var tx = quadraticDerivativeAt$$1(p1[0], cp1[0], p2[0], t); + var ty = quadraticDerivativeAt$$1(p1[1], cp1[1], p2[1], t); + + symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; + + symbol.ignore = false; + }; + + + effectLineProto.updateLayout = function(lineData, idx) { + this.childAt(0).updateLayout(lineData, idx); + + var effectModel = lineData.getItemModel(idx).getModel('effect'); + this._updateEffectAnimation(lineData, effectModel, idx); + }; + + inherits(EffectLine, Group); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/chart/helper/Line + */ + + /** + * @constructor + * @extends {module:zrender/graphic/Group} + * @alias {module:echarts/chart/helper/Polyline} + */ + function Polyline$2(lineData, idx, seriesScope) { + Group.call(this); + + this._createPolyline(lineData, idx, seriesScope); + } + + var polylineProto = Polyline$2.prototype; + + polylineProto._createPolyline = function(lineData, idx, seriesScope) { + // var seriesModel = lineData.hostModel; + var points = lineData.getItemLayout(idx); + + var line = new Polyline({ + shape: { + points: points + } + }); + + this.add(line); + + this._updateCommonStl(lineData, idx, seriesScope); + }; + + polylineProto.updateData = function(lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + + var line = this.childAt(0); + var target = { + shape: { + points: lineData.getItemLayout(idx) + } + }; + updateProps(line, target, seriesModel, idx); + + this._updateCommonStl(lineData, idx, seriesScope); + }; + + polylineProto._updateCommonStl = function(lineData, idx, seriesScope) { + var line = this.childAt(0); + var itemModel = lineData.getItemModel(idx); + + var visualColor = lineData.getItemVisual(idx, 'color'); + + var lineStyle = seriesScope && seriesScope.lineStyle; + var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle; + + if (!seriesScope || lineData.hasItemOption) { + lineStyle = itemModel.getModel('lineStyle').getLineStyle(); + hoverLineStyle = itemModel.getModel('emphasis.lineStyle').getLineStyle(); + } + line.useStyle(defaults({ + strokeNoScale: true, + fill: 'none', + stroke: visualColor + }, + lineStyle + )); + line.hoverStyle = hoverLineStyle; + + setHoverStyle(this); + }; + + polylineProto.updateLayout = function(lineData, idx) { + var polyline = this.childAt(0); + polyline.setShape('points', lineData.getItemLayout(idx)); + }; + + inherits(Polyline$2, Group); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Provide effect for line + * @module echarts/chart/helper/EffectLine + */ + + /** + * @constructor + * @extends {module:echarts/chart/helper/EffectLine} + * @alias {module:echarts/chart/helper/Polyline} + */ + function EffectPolyline(lineData, idx, seriesScope) { + EffectLine.call(this, lineData, idx, seriesScope); + this._lastFrame = 0; + this._lastFramePercent = 0; + } + + var effectPolylineProto = EffectPolyline.prototype; + + // Overwrite + effectPolylineProto.createLine = function(lineData, idx, seriesScope) { + return new Polyline$2(lineData, idx, seriesScope); + }; + + // Overwrite + effectPolylineProto.updateAnimationPoints = function(symbol, points) { + this._points = points; + var accLenArr = [0]; + var len$$1 = 0; + for (var i = 1; i < points.length; i++) { + var p1 = points[i - 1]; + var p2 = points[i]; + len$$1 += dist(p1, p2); + accLenArr.push(len$$1); + } + if (len$$1 === 0) { + return; + } + + for (var i = 0; i < accLenArr.length; i++) { + accLenArr[i] /= len$$1; + } + this._offsets = accLenArr; + this._length = len$$1; + }; + + // Overwrite + effectPolylineProto.getLineLength = function(symbol) { + return this._length; + }; + + // Overwrite + effectPolylineProto.updateSymbolPosition = function(symbol) { + var t = symbol.__t; + var points = this._points; + var offsets = this._offsets; + var len$$1 = points.length; + + if (!offsets) { + // Has length 0 + return; + } + + var lastFrame = this._lastFrame; + var frame; + + if (t < this._lastFramePercent) { + // Start from the next frame + // PENDING start from lastFrame ? + var start = Math.min(lastFrame + 1, len$$1 - 1); + for (frame = start; frame >= 0; frame--) { + if (offsets[frame] <= t) { + break; + } + } + // PENDING really need to do this ? + frame = Math.min(frame, len$$1 - 2); + } else { + for (var frame = lastFrame; frame < len$$1; frame++) { + if (offsets[frame] > t) { + break; + } + } + frame = Math.min(frame - 1, len$$1 - 2); + } + + lerp( + symbol.position, points[frame], points[frame + 1], + (t - offsets[frame]) / (offsets[frame + 1] - offsets[frame]) + ); + + var tx = points[frame + 1][0] - points[frame][0]; + var ty = points[frame + 1][1] - points[frame][1]; + symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; + + this._lastFrame = frame; + this._lastFramePercent = t; + + symbol.ignore = false; + }; + + inherits(EffectPolyline, EffectLine); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO Batch by color + + var LargeLineShape = extendShape({ + + shape: { + polyline: false, + curveness: 0, + segs: [] + }, + + buildPath: function(path, shape) { + var segs = shape.segs; + var curveness = shape.curveness; + + if (shape.polyline) { + for (var i = 0; i < segs.length;) { + var count = segs[i++]; + if (count > 0) { + path.moveTo(segs[i++], segs[i++]); + for (var k = 1; k < count; k++) { + path.lineTo(segs[i++], segs[i++]); + } + } + } + } else { + for (var i = 0; i < segs.length;) { + var x0 = segs[i++]; + var y0 = segs[i++]; + var x1 = segs[i++]; + var y1 = segs[i++]; + path.moveTo(x0, y0); + if (curveness > 0) { + var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness; + var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness; + path.quadraticCurveTo(x2, y2, x1, y1); + } else { + path.lineTo(x1, y1); + } + } + } + }, + + findDataIndex: function(x, y) { + + var shape = this.shape; + var segs = shape.segs; + var curveness = shape.curveness; + + if (shape.polyline) { + var dataIndex = 0; + for (var i = 0; i < segs.length;) { + var count = segs[i++]; + if (count > 0) { + var x0 = segs[i++]; + var y0 = segs[i++]; + for (var k = 1; k < count; k++) { + var x1 = segs[i++]; + var y1 = segs[i++]; + if (containStroke$1(x0, y0, x1, y1)) { + return dataIndex; + } + } + } + + dataIndex++; + } + } else { + var dataIndex = 0; + for (var i = 0; i < segs.length;) { + var x0 = segs[i++]; + var y0 = segs[i++]; + var x1 = segs[i++]; + var y1 = segs[i++]; + if (curveness > 0) { + var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness; + var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness; + + if (containStroke$3(x0, y0, x2, y2, x1, y1)) { + return dataIndex; + } + } else { + if (containStroke$1(x0, y0, x1, y1)) { + return dataIndex; + } + } + + dataIndex++; + } + } + + return -1; + } + }); + + function LargeLineDraw() { + this.group = new Group(); + } + + var largeLineProto = LargeLineDraw.prototype; + + largeLineProto.isPersistent = function() { + return !this._incremental; + }; + + /** + * Update symbols draw by new data + * @param {module:echarts/data/List} data + */ + largeLineProto.updateData = function(data) { + this.group.removeAll(); + + var lineEl = new LargeLineShape({ + rectHover: true, + cursor: 'default' + }); + lineEl.setShape({ + segs: data.getLayout('linesPoints') + }); + + this._setCommon(lineEl, data); + + // Add back + this.group.add(lineEl); + + this._incremental = null; + }; + + /** + * @override + */ + largeLineProto.incrementalPrepareUpdate = function(data) { + this.group.removeAll(); + + this._clearIncremental(); + + if (data.count() > 5e5) { + if (!this._incremental) { + this._incremental = new IncrementalDisplayble({ + silent: true + }); + } + this.group.add(this._incremental); + } else { + this._incremental = null; + } + }; + + /** + * @override + */ + largeLineProto.incrementalUpdate = function(taskParams, data) { + var lineEl = new LargeLineShape(); + lineEl.setShape({ + segs: data.getLayout('linesPoints') + }); + + this._setCommon(lineEl, data, !!this._incremental); + + if (!this._incremental) { + lineEl.rectHover = true; + lineEl.cursor = 'default'; + lineEl.__startIndex = taskParams.start; + this.group.add(lineEl); + } else { + this._incremental.addDisplayable(lineEl, true); + } + }; + + /** + * @override + */ + largeLineProto.remove = function() { + this._clearIncremental(); + this._incremental = null; + this.group.removeAll(); + }; + + largeLineProto._setCommon = function(lineEl, data, isIncremental) { + var hostModel = data.hostModel; + + lineEl.setShape({ + polyline: hostModel.get('polyline'), + curveness: hostModel.get('lineStyle.curveness') + }); + + lineEl.useStyle( + hostModel.getModel('lineStyle').getLineStyle() + ); + lineEl.style.strokeNoScale = true; + + var visualColor = data.getVisual('color'); + if (visualColor) { + lineEl.setStyle('stroke', visualColor); + } + lineEl.setStyle('fill'); + + if (!isIncremental) { + // Enable tooltip + // PENDING May have performance issue when path is extremely large + lineEl.seriesIndex = hostModel.seriesIndex; + lineEl.on('mousemove', function(e) { + lineEl.dataIndex = null; + var dataIndex = lineEl.findDataIndex(e.offsetX, e.offsetY); + if (dataIndex > 0) { + // Provide dataIndex for tooltip + lineEl.dataIndex = dataIndex + lineEl.__startIndex; + } + }); + } + }; + + largeLineProto._clearIncremental = function() { + var incremental = this._incremental; + if (incremental) { + incremental.clearDisplaybles(); + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var linesLayout = { + seriesType: 'lines', + + plan: createRenderPlanner(), + + reset: function(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + var isPolyline = seriesModel.get('polyline'); + var isLarge = seriesModel.pipelineContext.large; + + function progress(params, lineData) { + var lineCoords = []; + if (isLarge) { + var points; + var segCount = params.end - params.start; + if (isPolyline) { + var totalCoordsCount = 0; + for (var i = params.start; i < params.end; i++) { + totalCoordsCount += seriesModel.getLineCoordsCount(i); + } + points = new Float32Array(segCount + totalCoordsCount * 2); + } else { + points = new Float32Array(segCount * 4); + } + + var offset = 0; + var pt = []; + for (var i = params.start; i < params.end; i++) { + var len = seriesModel.getLineCoords(i, lineCoords); + if (isPolyline) { + points[offset++] = len; + } + for (var k = 0; k < len; k++) { + pt = coordSys.dataToPoint(lineCoords[k], false, pt); + points[offset++] = pt[0]; + points[offset++] = pt[1]; + } + } + + lineData.setLayout('linesPoints', points); + } else { + for (var i = params.start; i < params.end; i++) { + var itemModel = lineData.getItemModel(i); + var len = seriesModel.getLineCoords(i, lineCoords); + + var pts = []; + if (isPolyline) { + for (var j = 0; j < len; j++) { + pts.push(coordSys.dataToPoint(lineCoords[j])); + } + } else { + pts[0] = coordSys.dataToPoint(lineCoords[0]); + pts[1] = coordSys.dataToPoint(lineCoords[1]); + + var curveness = itemModel.get('lineStyle.curveness'); + if (+curveness) { + pts[2] = [ + (pts[0][0] + pts[1][0]) / 2 - (pts[0][1] - pts[1][1]) * curveness, + (pts[0][1] + pts[1][1]) / 2 - (pts[1][0] - pts[0][0]) * curveness + ]; + } + } + lineData.setItemLayout(i, pts); + } + } + } + + return { + progress: progress + }; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendChartView({ + + type: 'lines', + + init: function() {}, + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + var lineDraw = this._updateLineDraw(data, seriesModel); + + var zlevel = seriesModel.get('zlevel'); + var trailLength = seriesModel.get('effect.trailLength'); + + var zr = api.getZr(); + // Avoid the drag cause ghost shadow + // FIXME Better way ? + // SVG doesn't support + var isSvg = zr.painter.getType() === 'svg'; + if (!isSvg) { + zr.painter.getLayer(zlevel).clear(true); + } + // Config layer with motion blur + if (this._lastZlevel != null && !isSvg) { + zr.configLayer(this._lastZlevel, { + motionBlur: false + }); + } + if (this._showEffect(seriesModel) && trailLength) { + if (__DEV__) { + var notInIndividual = false; + ecModel.eachSeries(function(otherSeriesModel) { + if (otherSeriesModel !== seriesModel && otherSeriesModel.get('zlevel') === zlevel) { + notInIndividual = true; + } + }); + notInIndividual && console.warn('Lines with trail effect should have an individual zlevel'); + } + + if (!isSvg) { + zr.configLayer(zlevel, { + motionBlur: true, + lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0) + }); + } + } + + lineDraw.updateData(data); + + this._lastZlevel = zlevel; + + this._finished = true; + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + var lineDraw = this._updateLineDraw(data, seriesModel); + + lineDraw.incrementalPrepareUpdate(data); + + this._clearLayer(api); + + this._finished = false; + }, + + incrementalRender: function(taskParams, seriesModel, ecModel) { + this._lineDraw.incrementalUpdate(taskParams, seriesModel.getData()); + + this._finished = taskParams.end === seriesModel.getData().count(); + }, + + updateTransform: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var pipelineContext = seriesModel.pipelineContext; + + if (!this._finished || pipelineContext.large || pipelineContext.progressiveRender) { + // TODO Don't have to do update in large mode. Only do it when there are millions of data. + return { + update: true + }; + } else { + // TODO Use same logic with ScatterView. + // Manually update layout + var res = linesLayout.reset(seriesModel); + if (res.progress) { + res.progress({ + start: 0, + end: data.count() + }, data); + } + this._lineDraw.updateLayout(); + this._clearLayer(api); + } + }, + + _updateLineDraw: function(data, seriesModel) { + var lineDraw = this._lineDraw; + var hasEffect = this._showEffect(seriesModel); + var isPolyline = !!seriesModel.get('polyline'); + var pipelineContext = seriesModel.pipelineContext; + var isLargeDraw = pipelineContext.large; + + if (__DEV__) { + if (hasEffect && isLargeDraw) { + console.warn('Large lines not support effect'); + } + } + if (!lineDraw || + hasEffect !== this._hasEffet || + isPolyline !== this._isPolyline || + isLargeDraw !== this._isLargeDraw + ) { + if (lineDraw) { + lineDraw.remove(); + } + lineDraw = this._lineDraw = isLargeDraw ? + new LargeLineDraw() : + new LineDraw( + isPolyline ? + (hasEffect ? EffectPolyline : Polyline$2) : + (hasEffect ? EffectLine : Line$1) + ); + this._hasEffet = hasEffect; + this._isPolyline = isPolyline; + this._isLargeDraw = isLargeDraw; + this.group.removeAll(); + } + + this.group.add(lineDraw.group); + + return lineDraw; + }, + + _showEffect: function(seriesModel) { + return !!seriesModel.get('effect.show'); + }, + + _clearLayer: function(api) { + // Not use motion when dragging or zooming + var zr = api.getZr(); + var isSvg = zr.painter.getType() === 'svg'; + if (!isSvg && this._lastZlevel != null) { + zr.painter.getLayer(this._lastZlevel).clear(true); + } + }, + + remove: function(ecModel, api) { + this._lineDraw && this._lineDraw.remove(); + this._lineDraw = null; + // Clear motion when lineDraw is removed + this._clearLayer(api); + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + function normalize$2(a) { + if (!(a instanceof Array)) { + a = [a, a]; + } + return a; + } + + var opacityQuery = 'lineStyle.opacity'.split('.'); + + var linesVisual = { + seriesType: 'lines', + reset: function(seriesModel, ecModel, api) { + var symbolType = normalize$2(seriesModel.get('symbol')); + var symbolSize = normalize$2(seriesModel.get('symbolSize')); + var data = seriesModel.getData(); + + data.setVisual('fromSymbol', symbolType && symbolType[0]); + data.setVisual('toSymbol', symbolType && symbolType[1]); + data.setVisual('fromSymbolSize', symbolSize && symbolSize[0]); + data.setVisual('toSymbolSize', symbolSize && symbolSize[1]); + data.setVisual('opacity', seriesModel.get(opacityQuery)); + + function dataEach(data, idx) { + var itemModel = data.getItemModel(idx); + var symbolType = normalize$2(itemModel.getShallow('symbol', true)); + var symbolSize = normalize$2(itemModel.getShallow('symbolSize', true)); + var opacity = itemModel.get(opacityQuery); + + symbolType[0] && data.setItemVisual(idx, 'fromSymbol', symbolType[0]); + symbolType[1] && data.setItemVisual(idx, 'toSymbol', symbolType[1]); + symbolSize[0] && data.setItemVisual(idx, 'fromSymbolSize', symbolSize[0]); + symbolSize[1] && data.setItemVisual(idx, 'toSymbolSize', symbolSize[1]); + + data.setItemVisual(idx, 'opacity', opacity); + } + + return { + dataEach: data.hasItemOption ? dataEach : null + }; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerLayout(linesLayout); + registerVisual(linesVisual); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + type: 'series.heatmap', + + getInitialData: function(option, ecModel) { + return createListFromArray(this.getSource(), this, { + generateCoord: 'value' + }); + }, + + preventIncremental: function() { + var coordSysCreator = CoordinateSystemManager.get(this.get('coordinateSystem')); + if (coordSysCreator && coordSysCreator.dimensions) { + return coordSysCreator.dimensions[0] === 'lng' && coordSysCreator.dimensions[1] === 'lat'; + } + }, + + defaultOption: { + + // Cartesian2D or geo + coordinateSystem: 'cartesian2d', + + zlevel: 0, + + z: 2, + + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + + // Geo coordinate system + geoIndex: 0, + + blurSize: 30, + + pointSize: 20, + + maxOpacity: 1, + + minOpacity: 0 + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file defines echarts Heatmap Chart + * @author Ovilia (me@zhangwenli.com) + * Inspired by https://github.com/mourner/simpleheat + * + * @module + */ + + var GRADIENT_LEVELS = 256; + + /** + * Heatmap Chart + * + * @class + */ + function Heatmap() { + var canvas = createCanvas(); + this.canvas = canvas; + + this.blurSize = 30; + this.pointSize = 20; + + this.maxOpacity = 1; + this.minOpacity = 0; + + this._gradientPixels = {}; + } + + Heatmap.prototype = { + /** + * Renders Heatmap and returns the rendered canvas + * @param {Array} data array of data, each has x, y, value + * @param {number} width canvas width + * @param {number} height canvas height + */ + update: function(data, width, height, normalize, colorFunc, isInRange) { + var brush = this._getBrush(); + var gradientInRange = this._getGradient(data, colorFunc, 'inRange'); + var gradientOutOfRange = this._getGradient(data, colorFunc, 'outOfRange'); + var r = this.pointSize + this.blurSize; + + var canvas = this.canvas; + var ctx = canvas.getContext('2d'); + var len = data.length; + canvas.width = width; + canvas.height = height; + for (var i = 0; i < len; ++i) { + var p = data[i]; + var x = p[0]; + var y = p[1]; + var value = p[2]; + + // calculate alpha using value + var alpha = normalize(value); + + // draw with the circle brush with alpha + ctx.globalAlpha = alpha; + ctx.drawImage(brush, x - r, y - r); + } + + if (!canvas.width || !canvas.height) { + // Avoid "Uncaught DOMException: Failed to execute 'getImageData' on + // 'CanvasRenderingContext2D': The source height is 0." + return canvas; + } + + // colorize the canvas using alpha value and set with gradient + var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + + var pixels = imageData.data; + var offset = 0; + var pixelLen = pixels.length; + var minOpacity = this.minOpacity; + var maxOpacity = this.maxOpacity; + var diffOpacity = maxOpacity - minOpacity; + + while (offset < pixelLen) { + var alpha = pixels[offset + 3] / 256; + var gradientOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)) * 4; + // Simple optimize to ignore the empty data + if (alpha > 0) { + var gradient = isInRange(alpha) ? gradientInRange : gradientOutOfRange; + // Any alpha > 0 will be mapped to [minOpacity, maxOpacity] + alpha > 0 && (alpha = alpha * diffOpacity + minOpacity); + pixels[offset++] = gradient[gradientOffset]; + pixels[offset++] = gradient[gradientOffset + 1]; + pixels[offset++] = gradient[gradientOffset + 2]; + pixels[offset++] = gradient[gradientOffset + 3] * alpha * 256; + } else { + offset += 4; + } + } + ctx.putImageData(imageData, 0, 0); + + return canvas; + }, + + /** + * get canvas of a black circle brush used for canvas to draw later + * @private + * @returns {Object} circle brush canvas + */ + _getBrush: function() { + var brushCanvas = this._brushCanvas || (this._brushCanvas = createCanvas()); + // set brush size + var r = this.pointSize + this.blurSize; + var d = r * 2; + brushCanvas.width = d; + brushCanvas.height = d; + + var ctx = brushCanvas.getContext('2d'); + ctx.clearRect(0, 0, d, d); + + // in order to render shadow without the distinct circle, + // draw the distinct circle in an invisible place, + // and use shadowOffset to draw shadow in the center of the canvas + ctx.shadowOffsetX = d; + ctx.shadowBlur = this.blurSize; + // draw the shadow in black, and use alpha and shadow blur to generate + // color in color map + ctx.shadowColor = '#000'; + + // draw circle in the left to the canvas + ctx.beginPath(); + ctx.arc(-r, r, this.pointSize, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + return brushCanvas; + }, + + /** + * get gradient color map + * @private + */ + _getGradient: function(data, colorFunc, state) { + var gradientPixels = this._gradientPixels; + var pixelsSingleState = gradientPixels[state] || (gradientPixels[state] = new Uint8ClampedArray(256 * 4)); + var color = [0, 0, 0, 0]; + var off = 0; + for (var i = 0; i < 256; i++) { + colorFunc[state](i / 255, true, color); + pixelsSingleState[off++] = color[0]; + pixelsSingleState[off++] = color[1]; + pixelsSingleState[off++] = color[2]; + pixelsSingleState[off++] = color[3]; + } + return pixelsSingleState; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function getIsInPiecewiseRange(dataExtent, pieceList, selected) { + var dataSpan = dataExtent[1] - dataExtent[0]; + pieceList = map(pieceList, function(piece) { + return { + interval: [ + (piece.interval[0] - dataExtent[0]) / dataSpan, + (piece.interval[1] - dataExtent[0]) / dataSpan + ] + }; + }); + var len = pieceList.length; + var lastIndex = 0; + + return function(val) { + // Try to find in the location of the last found + for (var i = lastIndex; i < len; i++) { + var interval = pieceList[i].interval; + if (interval[0] <= val && val <= interval[1]) { + lastIndex = i; + break; + } + } + if (i === len) { // Not found, back interation + for (var i = lastIndex - 1; i >= 0; i--) { + var interval = pieceList[i].interval; + if (interval[0] <= val && val <= interval[1]) { + lastIndex = i; + break; + } + } + } + return i >= 0 && i < len && selected[i]; + }; + } + + function getIsInContinuousRange(dataExtent, range) { + var dataSpan = dataExtent[1] - dataExtent[0]; + range = [ + (range[0] - dataExtent[0]) / dataSpan, + (range[1] - dataExtent[0]) / dataSpan + ]; + return function(val) { + return val >= range[0] && val <= range[1]; + }; + } + + function isGeoCoordSys(coordSys) { + var dimensions = coordSys.dimensions; + // Not use coorSys.type === 'geo' because coordSys maybe extended + return dimensions[0] === 'lng' && dimensions[1] === 'lat'; + } + + extendChartView({ + + type: 'heatmap', + + render: function(seriesModel, ecModel, api) { + var visualMapOfThisSeries; + ecModel.eachComponent('visualMap', function(visualMap) { + visualMap.eachTargetSeries(function(targetSeries) { + if (targetSeries === seriesModel) { + visualMapOfThisSeries = visualMap; + } + }); + }); + + if (__DEV__) { + if (!visualMapOfThisSeries) { + throw new Error('Heatmap must use with visualMap'); + } + } + + this.group.removeAll(); + + this._incrementalDisplayable = null; + + var coordSys = seriesModel.coordinateSystem; + if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') { + this._renderOnCartesianAndCalendar(seriesModel, api, 0, seriesModel.getData().count()); + } else if (isGeoCoordSys(coordSys)) { + this._renderOnGeo( + coordSys, seriesModel, visualMapOfThisSeries, api + ); + } + }, + + incrementalPrepareRender: function(seriesModel, ecModel, api) { + this.group.removeAll(); + }, + + incrementalRender: function(params, seriesModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys) { + this._renderOnCartesianAndCalendar(seriesModel, api, params.start, params.end, true); + } + }, + + _renderOnCartesianAndCalendar: function(seriesModel, api, start, end, incremental) { + + var coordSys = seriesModel.coordinateSystem; + var width; + var height; + + if (coordSys.type === 'cartesian2d') { + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + + if (__DEV__) { + if (!(xAxis.type === 'category' && yAxis.type === 'category')) { + throw new Error('Heatmap on cartesian must have two category axes'); + } + if (!(xAxis.onBand && yAxis.onBand)) { + throw new Error('Heatmap on cartesian must have two axes with boundaryGap true'); + } + } + + width = xAxis.getBandWidth(); + height = yAxis.getBandWidth(); + } + + var group = this.group; + var data = seriesModel.getData(); + + var itemStyleQuery = 'itemStyle'; + var hoverItemStyleQuery = 'emphasis.itemStyle'; + var labelQuery = 'label'; + var hoverLabelQuery = 'emphasis.label'; + var style = seriesModel.getModel(itemStyleQuery).getItemStyle(['color']); + var hoverStl = seriesModel.getModel(hoverItemStyleQuery).getItemStyle(); + var labelModel = seriesModel.getModel(labelQuery); + var hoverLabelModel = seriesModel.getModel(hoverLabelQuery); + var coordSysType = coordSys.type; + + + var dataDims = coordSysType === 'cartesian2d' ? + [ + data.mapDimension('x'), + data.mapDimension('y'), + data.mapDimension('value') + ] : + [ + data.mapDimension('time'), + data.mapDimension('value') + ]; + + for (var idx = start; idx < end; idx++) { + var rect; + + if (coordSysType === 'cartesian2d') { + // Ignore empty data + if (isNaN(data.get(dataDims[2], idx))) { + continue; + } + + var point = coordSys.dataToPoint([ + data.get(dataDims[0], idx), + data.get(dataDims[1], idx) + ]); + + rect = new Rect({ + shape: { + x: point[0] - width / 2, + y: point[1] - height / 2, + width: width, + height: height + }, + style: { + fill: data.getItemVisual(idx, 'color'), + opacity: data.getItemVisual(idx, 'opacity') + } + }); + } else { + // Ignore empty data + if (isNaN(data.get(dataDims[1], idx))) { + continue; + } + + rect = new Rect({ + z2: 1, + shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape, + style: { + fill: data.getItemVisual(idx, 'color'), + opacity: data.getItemVisual(idx, 'opacity') + } + }); + } + + var itemModel = data.getItemModel(idx); + + // Optimization for large datset + if (data.hasItemOption) { + style = itemModel.getModel(itemStyleQuery).getItemStyle(['color']); + hoverStl = itemModel.getModel(hoverItemStyleQuery).getItemStyle(); + labelModel = itemModel.getModel(labelQuery); + hoverLabelModel = itemModel.getModel(hoverLabelQuery); + } + + var rawValue = seriesModel.getRawValue(idx); + var defaultText = '-'; + if (rawValue && rawValue[2] != null) { + defaultText = rawValue[2]; + } + + setLabelStyle( + style, hoverStl, labelModel, hoverLabelModel, { + labelFetcher: seriesModel, + labelDataIndex: idx, + defaultText: defaultText, + isRectText: true + } + ); + + rect.setStyle(style); + setHoverStyle(rect, data.hasItemOption ? hoverStl : extend({}, hoverStl)); + + rect.incremental = incremental; + // PENDING + if (incremental) { + // Rect must use hover layer if it's incremental. + rect.useHoverLayer = true; + } + + group.add(rect); + data.setItemGraphicEl(idx, rect); + } + }, + + _renderOnGeo: function(geo, seriesModel, visualMapModel, api) { + var inRangeVisuals = visualMapModel.targetVisuals.inRange; + var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange; + // if (!visualMapping) { + // throw new Error('Data range must have color visuals'); + // } + + var data = seriesModel.getData(); + var hmLayer = this._hmLayer || (this._hmLayer || new Heatmap()); + hmLayer.blurSize = seriesModel.get('blurSize'); + hmLayer.pointSize = seriesModel.get('pointSize'); + hmLayer.minOpacity = seriesModel.get('minOpacity'); + hmLayer.maxOpacity = seriesModel.get('maxOpacity'); + + var rect = geo.getViewRect().clone(); + var roamTransform = geo.getRoamTransform(); + rect.applyTransform(roamTransform); + + // Clamp on viewport + var x = Math.max(rect.x, 0); + var y = Math.max(rect.y, 0); + var x2 = Math.min(rect.width + rect.x, api.getWidth()); + var y2 = Math.min(rect.height + rect.y, api.getHeight()); + var width = x2 - x; + var height = y2 - y; + + var dims = [ + data.mapDimension('lng'), + data.mapDimension('lat'), + data.mapDimension('value') + ]; + + var points = data.mapArray(dims, function(lng, lat, value) { + var pt = geo.dataToPoint([lng, lat]); + pt[0] -= x; + pt[1] -= y; + pt.push(value); + return pt; + }); + + var dataExtent = visualMapModel.getExtent(); + var isInRange = visualMapModel.type === 'visualMap.continuous' ? + getIsInContinuousRange(dataExtent, visualMapModel.option.range) : + getIsInPiecewiseRange( + dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected + ); + + hmLayer.update( + points, width, height, + inRangeVisuals.color.getNormalizer(), { + inRange: inRangeVisuals.color.getColorMapper(), + outOfRange: outOfRangeVisuals.color.getColorMapper() + }, + isInRange + ); + var img = new ZImage({ + style: { + width: width, + height: height, + x: x, + y: y, + image: hmLayer.canvas + }, + silent: true + }); + this.group.add(img); + }, + + dispose: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PictorialBarSeries = BaseBarSeries.extend({ + + type: 'series.pictorialBar', + + dependencies: ['grid'], + + defaultOption: { + symbol: 'circle', // Customized bar shape + symbolSize: null, // Can be ['100%', '100%'], null means auto. + symbolRotate: null, + + symbolPosition: null, // 'start' or 'end' or 'center', null means auto. + symbolOffset: null, + symbolMargin: null, // start margin and end margin. Can be a number or a percent string. + // Auto margin by defualt. + symbolRepeat: false, // false/null/undefined, means no repeat. + // Can be true, means auto calculate repeat times and cut by data. + // Can be a number, specifies repeat times, and do not cut by data. + // Can be 'fixed', means auto calculate repeat times but do not cut by data. + symbolRepeatDirection: 'end', // 'end' means from 'start' to 'end'. + + symbolClip: false, + symbolBoundingData: null, // Can be 60 or -40 or [-40, 60] + symbolPatternSize: 400, // 400 * 400 px + + barGap: '-100%', // In most case, overlap is needed. + + // z can be set in data item, which is z2 actually. + + // Disable progressive + progressive: 0, + hoverAnimation: false // Open only when needed. + }, + + getInitialData: function(option) { + // Disable stack. + option.stack = null; + return PictorialBarSeries.superApply(this, 'getInitialData', arguments); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var BAR_BORDER_WIDTH_QUERY$1 = ['itemStyle', 'borderWidth']; + + // index: +isHorizontal + var LAYOUT_ATTRS = [{ + xy: 'x', + wh: 'width', + index: 0, + posDesc: ['left', 'right'] + }, + { + xy: 'y', + wh: 'height', + index: 1, + posDesc: ['top', 'bottom'] + } + ]; + + var pathForLineWidth = new Circle(); + + var BarView$1 = extendChartView({ + + type: 'pictorialBar', + + render: function(seriesModel, ecModel, api) { + var group = this.group; + var data = seriesModel.getData(); + var oldData = this._data; + + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var isHorizontal = !!baseAxis.isHorizontal(); + var coordSysRect = cartesian.grid.getRect(); + + var opt = { + ecSize: { + width: api.getWidth(), + height: api.getHeight() + }, + seriesModel: seriesModel, + coordSys: cartesian, + coordSysExtent: [ + [coordSysRect.x, coordSysRect.x + coordSysRect.width], + [coordSysRect.y, coordSysRect.y + coordSysRect.height] + ], + isHorizontal: isHorizontal, + valueDim: LAYOUT_ATTRS[+isHorizontal], + categoryDim: LAYOUT_ATTRS[1 - isHorizontal] + }; + + data.diff(oldData) + .add(function(dataIndex) { + if (!data.hasValue(dataIndex)) { + return; + } + + var itemModel = getItemModel(data, dataIndex); + var symbolMeta = getSymbolMeta(data, dataIndex, itemModel, opt); + + var bar = createBar(data, opt, symbolMeta); + + data.setItemGraphicEl(dataIndex, bar); + group.add(bar); + + updateCommon$1(bar, opt, symbolMeta); + }) + .update(function(newIndex, oldIndex) { + var bar = oldData.getItemGraphicEl(oldIndex); + + if (!data.hasValue(newIndex)) { + group.remove(bar); + return; + } + + var itemModel = getItemModel(data, newIndex); + var symbolMeta = getSymbolMeta(data, newIndex, itemModel, opt); + + var pictorialShapeStr = getShapeStr(data, symbolMeta); + if (bar && pictorialShapeStr !== bar.__pictorialShapeStr) { + group.remove(bar); + data.setItemGraphicEl(newIndex, null); + bar = null; + } + + if (bar) { + updateBar(bar, opt, symbolMeta); + } else { + bar = createBar(data, opt, symbolMeta, true); + } + + data.setItemGraphicEl(newIndex, bar); + bar.__pictorialSymbolMeta = symbolMeta; + // Add back + group.add(bar); + + updateCommon$1(bar, opt, symbolMeta); + }) + .remove(function(dataIndex) { + var bar = oldData.getItemGraphicEl(dataIndex); + bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar); + }) + .execute(); + + this._data = data; + + return this.group; + }, + + dispose: noop, + + remove: function(ecModel, api) { + var group = this.group; + var data = this._data; + if (ecModel.get('animation')) { + if (data) { + data.eachItemGraphicEl(function(bar) { + removeBar(data, bar.dataIndex, ecModel, bar); + }); + } + } else { + group.removeAll(); + } + } + }); + + + // Set or calculate default value about symbol, and calculate layout info. + function getSymbolMeta(data, dataIndex, itemModel, opt) { + var layout = data.getItemLayout(dataIndex); + var symbolRepeat = itemModel.get('symbolRepeat'); + var symbolClip = itemModel.get('symbolClip'); + var symbolPosition = itemModel.get('symbolPosition') || 'start'; + var symbolRotate = itemModel.get('symbolRotate'); + var rotation = (symbolRotate || 0) * Math.PI / 180 || 0; + var symbolPatternSize = itemModel.get('symbolPatternSize') || 2; + var isAnimationEnabled = itemModel.isAnimationEnabled(); + + var symbolMeta = { + dataIndex: dataIndex, + layout: layout, + itemModel: itemModel, + symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle', + color: data.getItemVisual(dataIndex, 'color'), + symbolClip: symbolClip, + symbolRepeat: symbolRepeat, + symbolRepeatDirection: itemModel.get('symbolRepeatDirection'), + symbolPatternSize: symbolPatternSize, + rotation: rotation, + animationModel: isAnimationEnabled ? itemModel : null, + hoverAnimation: isAnimationEnabled && itemModel.get('hoverAnimation'), + z2: itemModel.getShallow('z', true) || 0 + }; + + prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta); + + prepareSymbolSize( + data, dataIndex, layout, symbolRepeat, symbolClip, symbolMeta.boundingLength, + symbolMeta.pxSign, symbolPatternSize, opt, symbolMeta + ); + + prepareLineWidth(itemModel, symbolMeta.symbolScale, rotation, opt, symbolMeta); + + var symbolSize = symbolMeta.symbolSize; + var symbolOffset = itemModel.get('symbolOffset'); + if (isArray(symbolOffset)) { + symbolOffset = [ + parsePercent$1(symbolOffset[0], symbolSize[0]), + parsePercent$1(symbolOffset[1], symbolSize[1]) + ]; + } + + prepareLayoutInfo( + itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, + symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength, + opt, symbolMeta + ); + + return symbolMeta; + } + + // bar length can be negative. + function prepareBarLength(itemModel, symbolRepeat, layout, opt, output) { + var valueDim = opt.valueDim; + var symbolBoundingData = itemModel.get('symbolBoundingData'); + var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis()); + var zeroPx = valueAxis.toGlobalCoord(valueAxis.dataToCoord(0)); + var pxSignIdx = 1 - +(layout[valueDim.wh] <= 0); + var boundingLength; + + if (isArray(symbolBoundingData)) { + var symbolBoundingExtent = [ + convertToCoordOnAxis(valueAxis, symbolBoundingData[0]) - zeroPx, + convertToCoordOnAxis(valueAxis, symbolBoundingData[1]) - zeroPx + ]; + symbolBoundingExtent[1] < symbolBoundingExtent[0] && (symbolBoundingExtent.reverse()); + boundingLength = symbolBoundingExtent[pxSignIdx]; + } else if (symbolBoundingData != null) { + boundingLength = convertToCoordOnAxis(valueAxis, symbolBoundingData) - zeroPx; + } else if (symbolRepeat) { + boundingLength = opt.coordSysExtent[valueDim.index][pxSignIdx] - zeroPx; + } else { + boundingLength = layout[valueDim.wh]; + } + + output.boundingLength = boundingLength; + + if (symbolRepeat) { + output.repeatCutLength = layout[valueDim.wh]; + } + + output.pxSign = boundingLength > 0 ? 1 : boundingLength < 0 ? -1 : 0; + } + + function convertToCoordOnAxis(axis, value) { + return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value))); + } + + // Support ['100%', '100%'] + function prepareSymbolSize( + data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength, + pxSign, symbolPatternSize, opt, output + ) { + var valueDim = opt.valueDim; + var categoryDim = opt.categoryDim; + var categorySize = Math.abs(layout[categoryDim.wh]); + + var symbolSize = data.getItemVisual(dataIndex, 'symbolSize'); + if (isArray(symbolSize)) { + symbolSize = symbolSize.slice(); + } else { + if (symbolSize == null) { + symbolSize = '100%'; + } + symbolSize = [symbolSize, symbolSize]; + } + + // Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is + // to complicated to calculate real percent value if considering scaled lineWidth. + // So the actual size will bigger than layout size if lineWidth is bigger than zero, + // which can be tolerated in pictorial chart. + + symbolSize[categoryDim.index] = parsePercent$1( + symbolSize[categoryDim.index], + categorySize + ); + symbolSize[valueDim.index] = parsePercent$1( + symbolSize[valueDim.index], + symbolRepeat ? categorySize : Math.abs(boundingLength) + ); + + output.symbolSize = symbolSize; + + // If x or y is less than zero, show reversed shape. + var symbolScale = output.symbolScale = [ + symbolSize[0] / symbolPatternSize, + symbolSize[1] / symbolPatternSize + ]; + // Follow convention, 'right' and 'top' is the normal scale. + symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign; + } + + function prepareLineWidth(itemModel, symbolScale, rotation, opt, output) { + // In symbols are drawn with scale, so do not need to care about the case that width + // or height are too small. But symbol use strokeNoScale, where acture lineWidth should + // be calculated. + var valueLineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY$1) || 0; + + if (valueLineWidth) { + pathForLineWidth.attr({ + scale: symbolScale.slice(), + rotation: rotation + }); + pathForLineWidth.updateTransform(); + valueLineWidth /= pathForLineWidth.getLineScale(); + valueLineWidth *= symbolScale[opt.valueDim.index]; + } + + output.valueLineWidth = valueLineWidth; + } + + function prepareLayoutInfo( + itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, + symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, output + ) { + var categoryDim = opt.categoryDim; + var valueDim = opt.valueDim; + var pxSign = output.pxSign; + + var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0); + var pathLen = unitLength; + + // Note: rotation will not effect the layout of symbols, because user may + // want symbols to rotate on its center, which should not be translated + // when rotating. + + if (symbolRepeat) { + var absBoundingLength = Math.abs(boundingLength); + + var symbolMargin = retrieve(itemModel.get('symbolMargin'), '15%') + ''; + var hasEndGap = false; + if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) { + hasEndGap = true; + symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1); + } + symbolMargin = parsePercent$1(symbolMargin, symbolSize[valueDim.index]); + + var uLenWithMargin = Math.max(unitLength + symbolMargin * 2, 0); + + // When symbol margin is less than 0, margin at both ends will be subtracted + // to ensure that all of the symbols will not be overflow the given area. + var endFix = hasEndGap ? 0 : symbolMargin * 2; + + // Both final repeatTimes and final symbolMargin area calculated based on + // boundingLength. + var repeatSpecified = isNumeric(symbolRepeat); + var repeatTimes = repeatSpecified ? + symbolRepeat : + toIntTimes((absBoundingLength + endFix) / uLenWithMargin); + + // Adjust calculate margin, to ensure each symbol is displayed + // entirely in the given layout area. + var mDiff = absBoundingLength - repeatTimes * unitLength; + symbolMargin = mDiff / 2 / (hasEndGap ? repeatTimes : repeatTimes - 1); + uLenWithMargin = unitLength + symbolMargin * 2; + endFix = hasEndGap ? 0 : symbolMargin * 2; + + // Update repeatTimes when not all symbol will be shown. + if (!repeatSpecified && symbolRepeat !== 'fixed') { + repeatTimes = repeatCutLength ? + toIntTimes((Math.abs(repeatCutLength) + endFix) / uLenWithMargin) : + 0; + } + + pathLen = repeatTimes * uLenWithMargin - endFix; + output.repeatTimes = repeatTimes; + output.symbolMargin = symbolMargin; + } + + var sizeFix = pxSign * (pathLen / 2); + var pathPosition = output.pathPosition = []; + pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2; + pathPosition[valueDim.index] = symbolPosition === 'start' ? + sizeFix : + symbolPosition === 'end' ? + boundingLength - sizeFix : + boundingLength / 2; // 'center' + if (symbolOffset) { + pathPosition[0] += symbolOffset[0]; + pathPosition[1] += symbolOffset[1]; + } + + var bundlePosition = output.bundlePosition = []; + bundlePosition[categoryDim.index] = layout[categoryDim.xy]; + bundlePosition[valueDim.index] = layout[valueDim.xy]; + + var barRectShape = output.barRectShape = extend({}, layout); + barRectShape[valueDim.wh] = pxSign * Math.max( + Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix) + ); + barRectShape[categoryDim.wh] = layout[categoryDim.wh]; + + var clipShape = output.clipShape = {}; + // Consider that symbol may be overflow layout rect. + clipShape[categoryDim.xy] = -layout[categoryDim.xy]; + clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh]; + clipShape[valueDim.xy] = 0; + clipShape[valueDim.wh] = layout[valueDim.wh]; + } + + function createPath(symbolMeta) { + var symbolPatternSize = symbolMeta.symbolPatternSize; + var path = createSymbol( + // Consider texture img, make a big size. + symbolMeta.symbolType, + -symbolPatternSize / 2, + -symbolPatternSize / 2, + symbolPatternSize, + symbolPatternSize, + symbolMeta.color + ); + path.attr({ + culling: true + }); + path.type !== 'image' && path.setStyle({ + strokeNoScale: true + }); + + return path; + } + + function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) { + var bundle = bar.__pictorialBundle; + var symbolSize = symbolMeta.symbolSize; + var valueLineWidth = symbolMeta.valueLineWidth; + var pathPosition = symbolMeta.pathPosition; + var valueDim = opt.valueDim; + var repeatTimes = symbolMeta.repeatTimes || 0; + + var index = 0; + var unit = symbolSize[opt.valueDim.index] + valueLineWidth + symbolMeta.symbolMargin * 2; + + eachPath(bar, function(path) { + path.__pictorialAnimationIndex = index; + path.__pictorialRepeatTimes = repeatTimes; + if (index < repeatTimes) { + updateAttr(path, null, makeTarget(index), symbolMeta, isUpdate); + } else { + updateAttr(path, null, { + scale: [0, 0] + }, symbolMeta, isUpdate, function() { + bundle.remove(path); + }); + } + + updateHoverAnimation(path, symbolMeta); + + index++; + }); + + for (; index < repeatTimes; index++) { + var path = createPath(symbolMeta); + path.__pictorialAnimationIndex = index; + path.__pictorialRepeatTimes = repeatTimes; + bundle.add(path); + + var target = makeTarget(index); + + updateAttr( + path, { + position: target.position, + scale: [0, 0] + }, { + scale: target.scale, + rotation: target.rotation + }, + symbolMeta, + isUpdate + ); + + // FIXME + // If all emphasis/normal through action. + path + .on('mouseover', onMouseOver) + .on('mouseout', onMouseOut); + + updateHoverAnimation(path, symbolMeta); + } + + function makeTarget(index) { + var position = pathPosition.slice(); + // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index + // Otherwise: i = index; + var pxSign = symbolMeta.pxSign; + var i = index; + if (symbolMeta.symbolRepeatDirection === 'start' ? pxSign > 0 : pxSign < 0) { + i = repeatTimes - 1 - index; + } + position[valueDim.index] = unit * (i - repeatTimes / 2 + 0.5) + pathPosition[valueDim.index]; + + return { + position: position, + scale: symbolMeta.symbolScale.slice(), + rotation: symbolMeta.rotation + }; + } + + function onMouseOver() { + eachPath(bar, function(path) { + path.trigger('emphasis'); + }); + } + + function onMouseOut() { + eachPath(bar, function(path) { + path.trigger('normal'); + }); + } + } + + function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) { + var bundle = bar.__pictorialBundle; + var mainPath = bar.__pictorialMainPath; + + if (!mainPath) { + mainPath = bar.__pictorialMainPath = createPath(symbolMeta); + bundle.add(mainPath); + + updateAttr( + mainPath, { + position: symbolMeta.pathPosition.slice(), + scale: [0, 0], + rotation: symbolMeta.rotation + }, { + scale: symbolMeta.symbolScale.slice() + }, + symbolMeta, + isUpdate + ); + + mainPath + .on('mouseover', onMouseOver) + .on('mouseout', onMouseOut); + } else { + updateAttr( + mainPath, + null, { + position: symbolMeta.pathPosition.slice(), + scale: symbolMeta.symbolScale.slice(), + rotation: symbolMeta.rotation + }, + symbolMeta, + isUpdate + ); + } + + updateHoverAnimation(mainPath, symbolMeta); + + function onMouseOver() { + this.trigger('emphasis'); + } + + function onMouseOut() { + this.trigger('normal'); + } + } + + // bar rect is used for label. + function createOrUpdateBarRect(bar, symbolMeta, isUpdate) { + var rectShape = extend({}, symbolMeta.barRectShape); + + var barRect = bar.__pictorialBarRect; + if (!barRect) { + barRect = bar.__pictorialBarRect = new Rect({ + z2: 2, + shape: rectShape, + silent: true, + style: { + stroke: 'transparent', + fill: 'transparent', + lineWidth: 0 + } + }); + + bar.add(barRect); + } else { + updateAttr(barRect, null, { + shape: rectShape + }, symbolMeta, isUpdate); + } + } + + function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) { + // If not clip, symbol will be remove and rebuilt. + if (symbolMeta.symbolClip) { + var clipPath = bar.__pictorialClipPath; + var clipShape = extend({}, symbolMeta.clipShape); + var valueDim = opt.valueDim; + var animationModel = symbolMeta.animationModel; + var dataIndex = symbolMeta.dataIndex; + + if (clipPath) { + updateProps( + clipPath, { + shape: clipShape + }, animationModel, dataIndex + ); + } else { + clipShape[valueDim.wh] = 0; + clipPath = new Rect({ + shape: clipShape + }); + bar.__pictorialBundle.setClipPath(clipPath); + bar.__pictorialClipPath = clipPath; + + var target = {}; + target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh]; + + graphic[isUpdate ? 'updateProps' : 'initProps']( + clipPath, { + shape: target + }, animationModel, dataIndex + ); + } + } + } + + function getItemModel(data, dataIndex) { + var itemModel = data.getItemModel(dataIndex); + itemModel.getAnimationDelayParams = getAnimationDelayParams; + itemModel.isAnimationEnabled = isAnimationEnabled; + return itemModel; + } + + function getAnimationDelayParams(path) { + // The order is the same as the z-order, see `symbolRepeatDiretion`. + return { + index: path.__pictorialAnimationIndex, + count: path.__pictorialRepeatTimes + }; + } + + function isAnimationEnabled() { + // `animation` prop can be set on itemModel in pictorial bar chart. + return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation'); + } + + function updateHoverAnimation(path, symbolMeta) { + path.off('emphasis').off('normal'); + + var scale = symbolMeta.symbolScale.slice(); + + symbolMeta.hoverAnimation && path + .on('emphasis', function() { + this.animateTo({ + scale: [scale[0] * 1.1, scale[1] * 1.1] + }, 400, 'elasticOut'); + }) + .on('normal', function() { + this.animateTo({ + scale: scale.slice() + }, 400, 'elasticOut'); + }); + } + + function createBar(data, opt, symbolMeta, isUpdate) { + // bar is the main element for each data. + var bar = new Group(); + // bundle is used for location and clip. + var bundle = new Group(); + bar.add(bundle); + bar.__pictorialBundle = bundle; + bundle.attr('position', symbolMeta.bundlePosition.slice()); + + if (symbolMeta.symbolRepeat) { + createOrUpdateRepeatSymbols(bar, opt, symbolMeta); + } else { + createOrUpdateSingleSymbol(bar, opt, symbolMeta); + } + + createOrUpdateBarRect(bar, symbolMeta, isUpdate); + + createOrUpdateClip(bar, opt, symbolMeta, isUpdate); + + bar.__pictorialShapeStr = getShapeStr(data, symbolMeta); + bar.__pictorialSymbolMeta = symbolMeta; + + return bar; + } + + function updateBar(bar, opt, symbolMeta) { + var animationModel = symbolMeta.animationModel; + var dataIndex = symbolMeta.dataIndex; + var bundle = bar.__pictorialBundle; + + updateProps( + bundle, { + position: symbolMeta.bundlePosition.slice() + }, animationModel, dataIndex + ); + + if (symbolMeta.symbolRepeat) { + createOrUpdateRepeatSymbols(bar, opt, symbolMeta, true); + } else { + createOrUpdateSingleSymbol(bar, opt, symbolMeta, true); + } + + createOrUpdateBarRect(bar, symbolMeta, true); + + createOrUpdateClip(bar, opt, symbolMeta, true); + } + + function removeBar(data, dataIndex, animationModel, bar) { + // Not show text when animating + var labelRect = bar.__pictorialBarRect; + labelRect && (labelRect.style.text = null); + + var pathes = []; + eachPath(bar, function(path) { + pathes.push(path); + }); + bar.__pictorialMainPath && pathes.push(bar.__pictorialMainPath); + + // I do not find proper remove animation for clip yet. + bar.__pictorialClipPath && (animationModel = null); + + each$1(pathes, function(path) { + updateProps( + path, { + scale: [0, 0] + }, animationModel, dataIndex, + function() { + bar.parent && bar.parent.remove(bar); + } + ); + }); + + data.setItemGraphicEl(dataIndex, null); + } + + function getShapeStr(data, symbolMeta) { + return [ + data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none', + !!symbolMeta.symbolRepeat, + !!symbolMeta.symbolClip + ].join(':'); + } + + function eachPath(bar, cb, context) { + // Do not use Group#eachChild, because it do not support remove. + each$1(bar.__pictorialBundle.children(), function(el) { + el !== bar.__pictorialBarRect && cb.call(context, el); + }); + } + + function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) { + immediateAttrs && el.attr(immediateAttrs); + // when symbolCip used, only clip path has init animation, otherwise it would be weird effect. + if (symbolMeta.symbolClip && !isUpdate) { + animationAttrs && el.attr(animationAttrs); + } else { + animationAttrs && graphic[isUpdate ? 'updateProps' : 'initProps']( + el, animationAttrs, symbolMeta.animationModel, symbolMeta.dataIndex, cb + ); + } + } + + function updateCommon$1(bar, opt, symbolMeta) { + var color = symbolMeta.color; + var dataIndex = symbolMeta.dataIndex; + var itemModel = symbolMeta.itemModel; + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + var normalStyle = itemModel.getModel('itemStyle').getItemStyle(['color']); + var hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle(); + var cursorStyle = itemModel.getShallow('cursor'); + + eachPath(bar, function(path) { + // PENDING setColor should be before setStyle!!! + path.setColor(color); + path.setStyle(defaults({ + fill: color, + opacity: symbolMeta.opacity + }, + normalStyle + )); + setHoverStyle(path, hoverStyle); + + cursorStyle && (path.cursor = cursorStyle); + path.z2 = symbolMeta.z2; + }); + + var barRectHoverStyle = {}; + var barPositionOutside = opt.valueDim.posDesc[+(symbolMeta.boundingLength > 0)]; + var barRect = bar.__pictorialBarRect; + + setLabel( + barRect.style, barRectHoverStyle, itemModel, + color, opt.seriesModel, dataIndex, barPositionOutside + ); + + setHoverStyle(barRect, barRectHoverStyle); + } + + function toIntTimes(times) { + var roundedTimes = Math.round(times); + // Escapse accurate error + return Math.abs(times - roundedTimes) < 1e-4 ? + roundedTimes : + Math.ceil(times); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // In case developer forget to include grid component + registerLayout(curry( + layout, 'pictorialBar' + )); + registerVisual(visualSymbol('pictorialBar', 'roundRect')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @constructor module:echarts/coord/single/SingleAxis + * @extends {module:echarts/coord/Axis} + * @param {string} dim + * @param {*} scale + * @param {Array.} coordExtent + * @param {string} axisType + * @param {string} position + */ + var SingleAxis = function(dim, scale, coordExtent, axisType, position) { + + Axis.call(this, dim, scale, coordExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = axisType || 'value'; + + /** + * Axis position + * - 'top' + * - 'bottom' + * - 'left' + * - 'right' + * @type {string} + */ + this.position = position || 'bottom'; + + /** + * Axis orient + * - 'horizontal' + * - 'vertical' + * @type {[type]} + */ + this.orient = null; + + }; + + SingleAxis.prototype = { + + constructor: SingleAxis, + + /** + * Axis model + * @type {module:echarts/coord/single/AxisModel} + */ + model: null, + + /** + * Judge the orient of the axis. + * @return {boolean} + */ + isHorizontal: function() { + var position = this.position; + return position === 'top' || position === 'bottom'; + + }, + + /** + * @override + */ + pointToData: function(point, clamp) { + return this.coordinateSystem.pointToData(point, clamp)[0]; + }, + + /** + * Convert the local coord(processed by dataToCoord()) + * to global coord(concrete pixel coord). + * designated by module:echarts/coord/single/Single. + * @type {Function} + */ + toGlobalCoord: null, + + /** + * Convert the global coord to local coord. + * designated by module:echarts/coord/single/Single. + * @type {Function} + */ + toLocalCoord: null + + }; + + inherits(SingleAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Single coordinates system. + */ + + /** + * Create a single coordinates system. + * + * @param {module:echarts/coord/single/AxisModel} axisModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + function Single(axisModel, ecModel, api) { + + /** + * @type {string} + * @readOnly + */ + this.dimension = 'single'; + + /** + * Add it just for draw tooltip. + * + * @type {Array.} + * @readOnly + */ + this.dimensions = ['single']; + + /** + * @private + * @type {module:echarts/coord/single/SingleAxis}. + */ + this._axis = null; + + /** + * @private + * @type {module:zrender/core/BoundingRect} + */ + this._rect; + + this._init(axisModel, ecModel, api); + + /** + * @type {module:echarts/coord/single/AxisModel} + */ + this.model = axisModel; + } + + Single.prototype = { + + type: 'singleAxis', + + axisPointerEnabled: true, + + constructor: Single, + + /** + * Initialize single coordinate system. + * + * @param {module:echarts/coord/single/AxisModel} axisModel + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @private + */ + _init: function(axisModel, ecModel, api) { + + var dim = this.dimension; + + var axis = new SingleAxis( + dim, + createScaleByModel(axisModel), + [0, 0], + axisModel.get('type'), + axisModel.get('position') + ); + + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + axis.orient = axisModel.get('orient'); + + axisModel.axis = axis; + axis.model = axisModel; + axis.coordinateSystem = this; + this._axis = axis; + }, + + /** + * Update axis scale after data processed + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + update: function(ecModel, api) { + ecModel.eachSeries(function(seriesModel) { + if (seriesModel.coordinateSystem === this) { + var data = seriesModel.getData(); + each$1(data.mapDimension(this.dimension, true), function(dim) { + this._axis.scale.unionExtentFromData(data, dim); + }, this); + niceScaleExtent(this._axis.scale, this._axis.model); + } + }, this); + }, + + /** + * Resize the single coordinate system. + * + * @param {module:echarts/coord/single/AxisModel} axisModel + * @param {module:echarts/ExtensionAPI} api + */ + resize: function(axisModel, api) { + this._rect = getLayoutRect({ + left: axisModel.get('left'), + top: axisModel.get('top'), + right: axisModel.get('right'), + bottom: axisModel.get('bottom'), + width: axisModel.get('width'), + height: axisModel.get('height') + }, { + width: api.getWidth(), + height: api.getHeight() + }); + + this._adjustAxis(); + }, + + /** + * @return {module:zrender/core/BoundingRect} + */ + getRect: function() { + return this._rect; + }, + + /** + * @private + */ + _adjustAxis: function() { + + var rect = this._rect; + var axis = this._axis; + + var isHorizontal = axis.isHorizontal(); + var extent = isHorizontal ? [0, rect.width] : [0, rect.height]; + var idx = axis.reverse ? 1 : 0; + + axis.setExtent(extent[idx], extent[1 - idx]); + + this._updateAxisTransform(axis, isHorizontal ? rect.x : rect.y); + + }, + + /** + * @param {module:echarts/coord/single/SingleAxis} axis + * @param {number} coordBase + */ + _updateAxisTransform: function(axis, coordBase) { + + var axisExtent = axis.getExtent(); + var extentSum = axisExtent[0] + axisExtent[1]; + var isHorizontal = axis.isHorizontal(); + + axis.toGlobalCoord = isHorizontal ? + function(coord) { + return coord + coordBase; + } : + function(coord) { + return extentSum - coord + coordBase; + }; + + axis.toLocalCoord = isHorizontal ? + function(coord) { + return coord - coordBase; + } : + function(coord) { + return extentSum - coord + coordBase; + }; + }, + + /** + * Get axis. + * + * @return {module:echarts/coord/single/SingleAxis} + */ + getAxis: function() { + return this._axis; + }, + + /** + * Get axis, add it just for draw tooltip. + * + * @return {[type]} [description] + */ + getBaseAxis: function() { + return this._axis; + }, + + /** + * @return {Array.} + */ + getAxes: function() { + return [this._axis]; + }, + + /** + * @return {Object} {baseAxes: [], otherAxes: []} + */ + getTooltipAxes: function() { + return { + baseAxes: [this.getAxis()] + }; + }, + + /** + * If contain point. + * + * @param {Array.} point + * @return {boolean} + */ + containPoint: function(point) { + var rect = this.getRect(); + var axis = this.getAxis(); + var orient = axis.orient; + if (orient === 'horizontal') { + return axis.contain(axis.toLocalCoord(point[0])) && + (point[1] >= rect.y && point[1] <= (rect.y + rect.height)); + } else { + return axis.contain(axis.toLocalCoord(point[1])) && + (point[0] >= rect.y && point[0] <= (rect.y + rect.height)); + } + }, + + /** + * @param {Array.} point + * @return {Array.} + */ + pointToData: function(point) { + var axis = this.getAxis(); + return [axis.coordToData(axis.toLocalCoord( + point[axis.orient === 'horizontal' ? 0 : 1] + ))]; + }, + + /** + * Convert the series data to concrete point. + * + * @param {number|Array.} val + * @return {Array.} + */ + dataToPoint: function(val) { + var axis = this.getAxis(); + var rect = this.getRect(); + var pt = []; + var idx = axis.orient === 'horizontal' ? 0 : 1; + + if (val instanceof Array) { + val = val[0]; + } + + pt[idx] = axis.toGlobalCoord(axis.dataToCoord(+val)); + pt[1 - idx] = idx === 0 ? (rect.y + rect.height / 2) : (rect.x + rect.width / 2); + return pt; + } + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Single coordinate system creator. + */ + + /** + * Create single coordinate system and inject it into seriesModel. + * + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @return {Array.} + */ + function create$3(ecModel, api) { + var singles = []; + + ecModel.eachComponent('singleAxis', function(axisModel, idx) { + + var single = new Single(axisModel, ecModel, api); + single.name = 'single_' + idx; + single.resize(axisModel, api); + axisModel.coordinateSystem = single; + singles.push(single); + + }); + + ecModel.eachSeries(function(seriesModel) { + if (seriesModel.get('coordinateSystem') === 'singleAxis') { + var singleAxisModel = ecModel.queryComponents({ + mainType: 'singleAxis', + index: seriesModel.get('singleAxisIndex'), + id: seriesModel.get('singleAxisId') + })[0]; + seriesModel.coordinateSystem = singleAxisModel && singleAxisModel.coordinateSystem; + } + }); + + return singles; + } + + CoordinateSystemManager.register('single', { + create: create$3, + dimensions: Single.prototype.dimensions + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {Object} opt {labelInside} + * @return {Object} { + * position, rotation, labelDirection, labelOffset, + * tickDirection, labelRotate, z2 + * } + */ + function layout$2(axisModel, opt) { + opt = opt || {}; + var single = axisModel.coordinateSystem; + var axis = axisModel.axis; + var layout = {}; + + var axisPosition = axis.position; + var orient = axis.orient; + + var rect = single.getRect(); + var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height]; + + var positionMap = { + horizontal: { + top: rectBound[2], + bottom: rectBound[3] + }, + vertical: { + left: rectBound[0], + right: rectBound[1] + } + }; + + layout.position = [ + orient === 'vertical' ? + positionMap.vertical[axisPosition] : + rectBound[0], + orient === 'horizontal' ? + positionMap.horizontal[axisPosition] : + rectBound[3] + ]; + + var r = { + horizontal: 0, + vertical: 1 + }; + layout.rotation = Math.PI / 2 * r[orient]; + + var directionMap = { + top: -1, + bottom: 1, + right: 1, + left: -1 + }; + + layout.labelDirection = layout.tickDirection = layout.nameDirection = directionMap[axisPosition]; + + if (axisModel.get('axisTick.inside')) { + layout.tickDirection = -layout.tickDirection; + } + + if (retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) { + layout.labelDirection = -layout.labelDirection; + } + + var labelRotation = opt.rotate; + labelRotation == null && (labelRotation = axisModel.get('axisLabel.rotate')); + layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation; + + layout.z2 = 1; + + return layout; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var axisBuilderAttrs$2 = [ + 'axisLine', 'axisTickLabel', 'axisName' + ]; + + var selfBuilderAttr = 'splitLine'; + + var SingleAxisView = AxisView.extend({ + + type: 'singleAxis', + + axisPointerClass: 'SingleAxisPointer', + + render: function(axisModel, ecModel, api, payload) { + + var group = this.group; + + group.removeAll(); + + var layout = layout$2(axisModel); + + var axisBuilder = new AxisBuilder(axisModel, layout); + + each$1(axisBuilderAttrs$2, axisBuilder.add, axisBuilder); + + group.add(axisBuilder.getGroup()); + + if (axisModel.get(selfBuilderAttr + '.show')) { + this['_' + selfBuilderAttr](axisModel); + } + + SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload); + }, + + _splitLine: function(axisModel) { + var axis = axisModel.axis; + + if (axis.scale.isBlank()) { + return; + } + + var splitLineModel = axisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineWidth = lineStyleModel.get('width'); + var lineColors = lineStyleModel.get('color'); + + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + + var gridRect = axisModel.coordinateSystem.getRect(); + var isHorizontal = axis.isHorizontal(); + + var splitLines = []; + var lineCount = 0; + + var ticksCoords = axis.getTicksCoords({ + tickModel: splitLineModel + }); + + var p1 = []; + var p2 = []; + + for (var i = 0; i < ticksCoords.length; ++i) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + if (isHorizontal) { + p1[0] = tickCoord; + p1[1] = gridRect.y; + p2[0] = tickCoord; + p2[1] = gridRect.y + gridRect.height; + } else { + p1[0] = gridRect.x; + p1[1] = tickCoord; + p2[0] = gridRect.x + gridRect.width; + p2[1] = tickCoord; + } + var colorIndex = (lineCount++) % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new Line( + subPixelOptimizeLine({ + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + }, + style: { + lineWidth: lineWidth + }, + silent: true + }))); + } + + for (var i = 0; i < splitLines.length; ++i) { + this.group.add(mergePath(splitLines[i], { + style: { + stroke: lineColors[i % lineColors.length], + lineDash: lineStyleModel.getLineDash(lineWidth), + lineWidth: lineWidth + }, + silent: true + })); + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AxisModel$4 = ComponentModel.extend({ + + type: 'singleAxis', + + layoutMode: 'box', + + /** + * @type {module:echarts/coord/single/SingleAxis} + */ + axis: null, + + /** + * @type {module:echarts/coord/single/Single} + */ + coordinateSystem: null, + + /** + * @override + */ + getCoordSysModel: function() { + return this; + } + + }); + + var defaultOption$2 = { + + left: '5%', + top: '5%', + right: '5%', + bottom: '5%', + + type: 'value', + + position: 'bottom', + + orient: 'horizontal', + + axisLine: { + show: true, + lineStyle: { + width: 2, + type: 'solid' + } + }, + + // Single coordinate system and single axis is the, + // which is used as the parent tooltip model. + // same model, so we set default tooltip show as true. + tooltip: { + show: true + }, + + axisTick: { + show: true, + length: 6, + lineStyle: { + width: 2 + } + }, + + axisLabel: { + show: true, + interval: 'auto' + }, + + splitLine: { + show: true, + lineStyle: { + type: 'dashed', + opacity: 0.2 + } + } + }; + + function getAxisType$2(axisName, option) { + return option.type || (option.data ? 'category' : 'value'); + } + + merge(AxisModel$4.prototype, axisModelCommonMixin); + + axisModelCreator('single', AxisModel$4, getAxisType$2, defaultOption$2); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {Object} finder contains {seriesIndex, dataIndex, dataIndexInside} + * @param {module:echarts/model/Global} ecModel + * @return {Object} {point: [x, y], el: ...} point Will not be null. + */ + var findPointFromSeries = function(finder, ecModel) { + var point = []; + var seriesIndex = finder.seriesIndex; + var seriesModel; + if (seriesIndex == null || !( + seriesModel = ecModel.getSeriesByIndex(seriesIndex) + )) { + return { + point: [] + }; + } + + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, finder); + if (dataIndex == null || dataIndex < 0 || isArray(dataIndex)) { + return { + point: [] + }; + } + + var el = data.getItemGraphicEl(dataIndex); + var coordSys = seriesModel.coordinateSystem; + + if (seriesModel.getTooltipPosition) { + point = seriesModel.getTooltipPosition(dataIndex) || []; + } else if (coordSys && coordSys.dataToPoint) { + point = coordSys.dataToPoint( + data.getValues( + map(coordSys.dimensions, function(dim) { + return data.mapDimension(dim); + }), dataIndex, true + ) + ) || []; + } else if (el) { + // Use graphic bounding rect + var rect = el.getBoundingRect().clone(); + rect.applyTransform(el.transform); + point = [ + rect.x + rect.width / 2, + rect.y + rect.height / 2 + ]; + } + + return { + point: point, + el: el + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$14 = each$1; + var curry$3 = curry; + var inner$7 = makeInner(); + + /** + * Basic logic: check all axis, if they do not demand show/highlight, + * then hide/downplay them. + * + * @param {Object} coordSysAxesInfo + * @param {Object} payload + * @param {string} [payload.currTrigger] 'click' | 'mousemove' | 'leave' + * @param {Array.} [payload.x] x and y, which are mandatory, specify a point to + * trigger axisPointer and tooltip. + * @param {Array.} [payload.y] x and y, which are mandatory, specify a point to + * trigger axisPointer and tooltip. + * @param {Object} [payload.seriesIndex] finder, optional, restrict target axes. + * @param {Object} [payload.dataIndex] finder, restrict target axes. + * @param {Object} [payload.axesInfo] finder, restrict target axes. + * [{ + * axisDim: 'x'|'y'|'angle'|..., + * axisIndex: ..., + * value: ... + * }, ...] + * @param {Function} [payload.dispatchAction] + * @param {Object} [payload.tooltipOption] + * @param {Object|Array.|Function} [payload.position] Tooltip position, + * which can be specified in dispatchAction + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @return {Object} content of event obj for echarts.connect. + */ + var axisTrigger = function(payload, ecModel, api) { + var currTrigger = payload.currTrigger; + var point = [payload.x, payload.y]; + var finder = payload; + var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api); + var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; + + // Pending + // See #6121. But we are not able to reproduce it yet. + if (!coordSysAxesInfo) { + return; + } + + if (illegalPoint(point)) { + // Used in the default behavior of `connection`: use the sample seriesIndex + // and dataIndex. And also used in the tooltipView trigger. + point = findPointFromSeries({ + seriesIndex: finder.seriesIndex, + // Do not use dataIndexInside from other ec instance. + // FIXME: auto detect it? + dataIndex: finder.dataIndex + }, ecModel).point; + } + var isIllegalPoint = illegalPoint(point); + + // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}). + // Notice: In this case, it is difficult to get the `point` (which is necessary to show + // tooltip, so if point is not given, we just use the point found by sample seriesIndex + // and dataIndex. + var inputAxesInfo = finder.axesInfo; + + var axesInfo = coordSysAxesInfo.axesInfo; + var shouldHide = currTrigger === 'leave' || illegalPoint(point); + var outputFinder = {}; + + var showValueMap = {}; + var dataByCoordSys = { + list: [], + map: {} + }; + var updaters = { + showPointer: curry$3(showPointer, showValueMap), + showTooltip: curry$3(showTooltip, dataByCoordSys) + }; + + // Process for triggered axes. + each$14(coordSysAxesInfo.coordSysMap, function(coordSys, coordSysKey) { + // If a point given, it must be contained by the coordinate system. + var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point); + + each$14(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function(axisInfo, key) { + var axis = axisInfo.axis; + var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); + // If no inputAxesInfo, no axis is restricted. + if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) { + var val = inputAxisInfo && inputAxisInfo.value; + if (val == null && !isIllegalPoint) { + val = axis.pointToData(point); + } + val != null && processOnAxis(axisInfo, val, updaters, false, outputFinder); + } + }); + }); + + // Process for linked axes. + var linkTriggers = {}; + each$14(axesInfo, function(tarAxisInfo, tarKey) { + var linkGroup = tarAxisInfo.linkGroup; + + // If axis has been triggered in the previous stage, it should not be triggered by link. + if (linkGroup && !showValueMap[tarKey]) { + each$14(linkGroup.axesInfo, function(srcAxisInfo, srcKey) { + var srcValItem = showValueMap[srcKey]; + // If srcValItem exist, source axis is triggered, so link to target axis. + if (srcAxisInfo !== tarAxisInfo && srcValItem) { + var val = srcValItem.value; + linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper( + val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo) + ))); + linkTriggers[tarAxisInfo.key] = val; + } + }); + } + }); + each$14(linkTriggers, function(val, tarKey) { + processOnAxis(axesInfo[tarKey], val, updaters, true, outputFinder); + }); + + updateModelActually(showValueMap, axesInfo, outputFinder); + dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction); + dispatchHighDownActually(axesInfo, dispatchAction, api); + + return outputFinder; + }; + + function processOnAxis(axisInfo, newValue, updaters, dontSnap, outputFinder) { + var axis = axisInfo.axis; + + if (axis.scale.isBlank() || !axis.containData(newValue)) { + return; + } + + if (!axisInfo.involveSeries) { + updaters.showPointer(axisInfo, newValue); + return; + } + + // Heavy calculation. So put it after axis.containData checking. + var payloadInfo = buildPayloadsBySeries(newValue, axisInfo); + var payloadBatch = payloadInfo.payloadBatch; + var snapToValue = payloadInfo.snapToValue; + + // Fill content of event obj for echarts.connect. + // By defualt use the first involved series data as a sample to connect. + if (payloadBatch[0] && outputFinder.seriesIndex == null) { + extend(outputFinder, payloadBatch[0]); + } + + // If no linkSource input, this process is for collecting link + // target, where snap should not be accepted. + if (!dontSnap && axisInfo.snap) { + if (axis.containData(snapToValue) && snapToValue != null) { + newValue = snapToValue; + } + } + + updaters.showPointer(axisInfo, newValue, payloadBatch, outputFinder); + // Tooltip should always be snapToValue, otherwise there will be + // incorrect "axis value ~ series value" mapping displayed in tooltip. + updaters.showTooltip(axisInfo, payloadInfo, snapToValue); + } + + function buildPayloadsBySeries(value, axisInfo) { + var axis = axisInfo.axis; + var dim = axis.dim; + var snapToValue = value; + var payloadBatch = []; + var minDist = Number.MAX_VALUE; + var minDiff = -1; + + each$14(axisInfo.seriesModels, function(series, idx) { + var dataDim = series.getData().mapDimension(dim, true); + var seriesNestestValue; + var dataIndices; + + if (series.getAxisTooltipData) { + var result = series.getAxisTooltipData(dataDim, value, axis); + dataIndices = result.dataIndices; + seriesNestestValue = result.nestestValue; + } else { + dataIndices = series.getData().indicesOfNearest( + dataDim[0], + value, + // Add a threshold to avoid find the wrong dataIndex + // when data length is not same. + // false, + axis.type === 'category' ? 0.5 : null + ); + if (!dataIndices.length) { + return; + } + seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]); + } + + if (seriesNestestValue == null || !isFinite(seriesNestestValue)) { + return; + } + + var diff = value - seriesNestestValue; + var dist = Math.abs(diff); + // Consider category case + if (dist <= minDist) { + if (dist < minDist || (diff >= 0 && minDiff < 0)) { + minDist = dist; + minDiff = diff; + snapToValue = seriesNestestValue; + payloadBatch.length = 0; + } + each$14(dataIndices, function(dataIndex) { + payloadBatch.push({ + seriesIndex: series.seriesIndex, + dataIndexInside: dataIndex, + dataIndex: series.getData().getRawIndex(dataIndex) + }); + }); + } + }); + + return { + payloadBatch: payloadBatch, + snapToValue: snapToValue + }; + } + + function showPointer(showValueMap, axisInfo, value, payloadBatch) { + showValueMap[axisInfo.key] = { + value: value, + payloadBatch: payloadBatch + }; + } + + function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) { + var payloadBatch = payloadInfo.payloadBatch; + var axis = axisInfo.axis; + var axisModel = axis.model; + var axisPointerModel = axisInfo.axisPointerModel; + + // If no data, do not create anything in dataByCoordSys, + // whose length will be used to judge whether dispatch action. + if (!axisInfo.triggerTooltip || !payloadBatch.length) { + return; + } + + var coordSysModel = axisInfo.coordSys.model; + var coordSysKey = makeKey(coordSysModel); + var coordSysItem = dataByCoordSys.map[coordSysKey]; + if (!coordSysItem) { + coordSysItem = dataByCoordSys.map[coordSysKey] = { + coordSysId: coordSysModel.id, + coordSysIndex: coordSysModel.componentIndex, + coordSysType: coordSysModel.type, + coordSysMainType: coordSysModel.mainType, + dataByAxis: [] + }; + dataByCoordSys.list.push(coordSysItem); + } + + coordSysItem.dataByAxis.push({ + axisDim: axis.dim, + axisIndex: axisModel.componentIndex, + axisType: axisModel.type, + axisId: axisModel.id, + value: value, + // Caustion: viewHelper.getValueLabel is actually on "view stage", which + // depends that all models have been updated. So it should not be performed + // here. Considering axisPointerModel used here is volatile, which is hard + // to be retrieve in TooltipView, we prepare parameters here. + valueLabelOpt: { + precision: axisPointerModel.get('label.precision'), + formatter: axisPointerModel.get('label.formatter') + }, + seriesDataIndices: payloadBatch.slice() + }); + } + + function updateModelActually(showValueMap, axesInfo, outputFinder) { + var outputAxesInfo = outputFinder.axesInfo = []; + // Basic logic: If no 'show' required, 'hide' this axisPointer. + each$14(axesInfo, function(axisInfo, key) { + var option = axisInfo.axisPointerModel.option; + var valItem = showValueMap[key]; + + if (valItem) { + !axisInfo.useHandle && (option.status = 'show'); + option.value = valItem.value; + // For label formatter param and highlight. + option.seriesDataIndices = (valItem.payloadBatch || []).slice(); + } + // When always show (e.g., handle used), remain + // original value and status. + else { + // If hide, value still need to be set, consider + // click legend to toggle axis blank. + !axisInfo.useHandle && (option.status = 'hide'); + } + + // If status is 'hide', should be no info in payload. + option.status === 'show' && outputAxesInfo.push({ + axisDim: axisInfo.axis.dim, + axisIndex: axisInfo.axis.model.componentIndex, + value: option.value + }); + }); + } + + function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) { + // Basic logic: If no showTip required, hideTip will be dispatched. + if (illegalPoint(point) || !dataByCoordSys.list.length) { + dispatchAction({ + type: 'hideTip' + }); + return; + } + + // In most case only one axis (or event one series is used). It is + // convinient to fetch payload.seriesIndex and payload.dataIndex + // dirtectly. So put the first seriesIndex and dataIndex of the first + // axis on the payload. + var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {}; + + dispatchAction({ + type: 'showTip', + escapeConnect: true, + x: point[0], + y: point[1], + tooltipOption: payload.tooltipOption, + position: payload.position, + dataIndexInside: sampleItem.dataIndexInside, + dataIndex: sampleItem.dataIndex, + seriesIndex: sampleItem.seriesIndex, + dataByCoordSys: dataByCoordSys.list + }); + } + + function dispatchHighDownActually(axesInfo, dispatchAction, api) { + // FIXME + // highlight status modification shoule be a stage of main process? + // (Consider confilct (e.g., legend and axisPointer) and setOption) + + var zr = api.getZr(); + var highDownKey = 'axisPointerLastHighlights'; + var lastHighlights = inner$7(zr)[highDownKey] || {}; + var newHighlights = inner$7(zr)[highDownKey] = {}; + + // Update highlight/downplay status according to axisPointer model. + // Build hash map and remove duplicate incidentally. + each$14(axesInfo, function(axisInfo, key) { + var option = axisInfo.axisPointerModel.option; + option.status === 'show' && each$14(option.seriesDataIndices, function(batchItem) { + var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex; + newHighlights[key] = batchItem; + }); + }); + + // Diff. + var toHighlight = []; + var toDownplay = []; + each$1(lastHighlights, function(batchItem, key) { + !newHighlights[key] && toDownplay.push(batchItem); + }); + each$1(newHighlights, function(batchItem, key) { + !lastHighlights[key] && toHighlight.push(batchItem); + }); + + toDownplay.length && api.dispatchAction({ + type: 'downplay', + escapeConnect: true, + batch: toDownplay + }); + toHighlight.length && api.dispatchAction({ + type: 'highlight', + escapeConnect: true, + batch: toHighlight + }); + } + + function findInputAxisInfo(inputAxesInfo, axisInfo) { + for (var i = 0; i < (inputAxesInfo || []).length; i++) { + var inputAxisInfo = inputAxesInfo[i]; + if (axisInfo.axis.dim === inputAxisInfo.axisDim && + axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex + ) { + return inputAxisInfo; + } + } + } + + function makeMapperParam(axisInfo) { + var axisModel = axisInfo.axis.model; + var item = {}; + var dim = item.axisDim = axisInfo.axis.dim; + item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex; + item.axisName = item[dim + 'AxisName'] = axisModel.name; + item.axisId = item[dim + 'AxisId'] = axisModel.id; + return item; + } + + function illegalPoint(point) { + return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AxisPointerModel = extendComponentModel({ + + type: 'axisPointer', + + coordSysAxesInfo: null, + + defaultOption: { + // 'auto' means that show when triggered by tooltip or handle. + show: 'auto', + // 'click' | 'mousemove' | 'none' + triggerOn: null, // set default in AxisPonterView.js + + zlevel: 0, + z: 50, + + type: 'line', + // axispointer triggered by tootip determine snap automatically, + // see `modelHelper`. + snap: false, + triggerTooltip: true, + + value: null, + status: null, // Init value depends on whether handle is used. + + // [group0, group1, ...] + // Each group can be: { + // mapper: function () {}, + // singleTooltip: 'multiple', // 'multiple' or 'single' + // xAxisId: ..., + // yAxisName: ..., + // angleAxisIndex: ... + // } + // mapper: can be ignored. + // input: {axisInfo, value} + // output: {axisInfo, value} + link: [], + + // Do not set 'auto' here, otherwise global animation: false + // will not effect at this axispointer. + animation: null, + animationDurationUpdate: 200, + + lineStyle: { + color: '#aaa', + width: 1, + type: 'solid' + }, + + shadowStyle: { + color: 'rgba(150,150,150,0.3)' + }, + + label: { + show: true, + formatter: null, // string | Function + precision: 'auto', // Or a number like 0, 1, 2 ... + margin: 3, + color: '#fff', + padding: [5, 7, 5, 7], + backgroundColor: 'auto', // default: axis line color + borderColor: null, + borderWidth: 0, + shadowBlur: 3, + shadowColor: '#aaa' + // Considering applicability, common style should + // better not have shadowOffset. + // shadowOffsetX: 0, + // shadowOffsetY: 2 + }, + + handle: { + show: false, + icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line + size: 45, + // handle margin is from symbol center to axis, which is stable when circular move. + margin: 50, + // color: '#1b8bbd' + // color: '#2f4554' + color: '#333', + shadowBlur: 3, + shadowColor: '#aaa', + shadowOffsetX: 0, + shadowOffsetY: 2, + + // For mobile performance + throttle: 40 + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$8 = makeInner(); + var each$15 = each$1; + + /** + * @param {string} key + * @param {module:echarts/ExtensionAPI} api + * @param {Function} handler + * param: {string} currTrigger + * param: {Array.} point + */ + function register(key, api, handler) { + if (env$1.node) { + return; + } + + var zr = api.getZr(); + inner$8(zr).records || (inner$8(zr).records = {}); + + initGlobalListeners(zr, api); + + var record = inner$8(zr).records[key] || (inner$8(zr).records[key] = {}); + record.handler = handler; + } + + function initGlobalListeners(zr, api) { + if (inner$8(zr).initialized) { + return; + } + + inner$8(zr).initialized = true; + + useHandler('click', curry(doEnter, 'click')); + useHandler('mousemove', curry(doEnter, 'mousemove')); + // useHandler('mouseout', onLeave); + useHandler('globalout', onLeave); + + function useHandler(eventType, cb) { + zr.on(eventType, function(e) { + var dis = makeDispatchAction(api); + + each$15(inner$8(zr).records, function(record) { + record && cb(record, e, dis.dispatchAction); + }); + + dispatchTooltipFinally(dis.pendings, api); + }); + } + } + + function dispatchTooltipFinally(pendings, api) { + var showLen = pendings.showTip.length; + var hideLen = pendings.hideTip.length; + + var actuallyPayload; + if (showLen) { + actuallyPayload = pendings.showTip[showLen - 1]; + } else if (hideLen) { + actuallyPayload = pendings.hideTip[hideLen - 1]; + } + if (actuallyPayload) { + actuallyPayload.dispatchAction = null; + api.dispatchAction(actuallyPayload); + } + } + + function onLeave(record, e, dispatchAction) { + record.handler('leave', null, dispatchAction); + } + + function doEnter(currTrigger, record, e, dispatchAction) { + record.handler(currTrigger, e, dispatchAction); + } + + function makeDispatchAction(api) { + var pendings = { + showTip: [], + hideTip: [] + }; + // FIXME + // better approach? + // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip, + // which may be conflict, (axisPointer call showTip but tooltip call hideTip); + // So we have to add "final stage" to merge those dispatched actions. + var dispatchAction = function(payload) { + var pendingList = pendings[payload.type]; + if (pendingList) { + pendingList.push(payload); + } else { + payload.dispatchAction = dispatchAction; + api.dispatchAction(payload); + } + }; + + return { + dispatchAction: dispatchAction, + pendings: pendings + }; + } + + /** + * @param {string} key + * @param {module:echarts/ExtensionAPI} api + */ + function unregister(key, api) { + if (env$1.node) { + return; + } + var zr = api.getZr(); + var record = (inner$8(zr).records || {})[key]; + if (record) { + inner$8(zr).records[key] = null; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AxisPointerView = extendComponentView({ + + type: 'axisPointer', + + render: function(globalAxisPointerModel, ecModel, api) { + var globalTooltipModel = ecModel.getComponent('tooltip'); + var triggerOn = globalAxisPointerModel.get('triggerOn') || + (globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click'); + + // Register global listener in AxisPointerView to enable + // AxisPointerView to be independent to Tooltip. + register( + 'axisPointer', + api, + function(currTrigger, e, dispatchAction) { + // If 'none', it is not controlled by mouse totally. + if (triggerOn !== 'none' && + (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0) + ) { + dispatchAction({ + type: 'updateAxisPointer', + currTrigger: currTrigger, + x: e && e.offsetX, + y: e && e.offsetY + }); + } + } + ); + }, + + /** + * @override + */ + remove: function(ecModel, api) { + unregister(api.getZr(), 'axisPointer'); + AxisPointerView.superApply(this._model, 'remove', arguments); + }, + + /** + * @override + */ + dispose: function(ecModel, api) { + unregister('axisPointer', api); + AxisPointerView.superApply(this._model, 'dispose', arguments); + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var inner$9 = makeInner(); + var clone$4 = clone; + var bind$2 = bind; + + /** + * Base axis pointer class in 2D. + * Implemenents {module:echarts/component/axis/IAxisPointer}. + */ + function BaseAxisPointer() {} + + BaseAxisPointer.prototype = { + + /** + * @private + */ + _group: null, + + /** + * @private + */ + _lastGraphicKey: null, + + /** + * @private + */ + _handle: null, + + /** + * @private + */ + _dragging: false, + + /** + * @private + */ + _lastValue: null, + + /** + * @private + */ + _lastStatus: null, + + /** + * @private + */ + _payloadInfo: null, + + /** + * In px, arbitrary value. Do not set too small, + * no animation is ok for most cases. + * @protected + */ + animationThreshold: 15, + + /** + * @implement + */ + render: function(axisModel, axisPointerModel, api, forceRender) { + var value = axisPointerModel.get('value'); + var status = axisPointerModel.get('status'); + + // Bind them to `this`, not in closure, otherwise they will not + // be replaced when user calling setOption in not merge mode. + this._axisModel = axisModel; + this._axisPointerModel = axisPointerModel; + this._api = api; + + // Optimize: `render` will be called repeatly during mouse move. + // So it is power consuming if performing `render` each time, + // especially on mobile device. + if (!forceRender && + this._lastValue === value && + this._lastStatus === status + ) { + return; + } + this._lastValue = value; + this._lastStatus = status; + + var group = this._group; + var handle = this._handle; + + if (!status || status === 'hide') { + // Do not clear here, for animation better. + group && group.hide(); + handle && handle.hide(); + return; + } + group && group.show(); + handle && handle.show(); + + // Otherwise status is 'show' + var elOption = {}; + this.makeElOption(elOption, value, axisModel, axisPointerModel, api); + + // Enable change axis pointer type. + var graphicKey = elOption.graphicKey; + if (graphicKey !== this._lastGraphicKey) { + this.clear(api); + } + this._lastGraphicKey = graphicKey; + + var moveAnimation = this._moveAnimation = + this.determineAnimation(axisModel, axisPointerModel); + + if (!group) { + group = this._group = new Group(); + this.createPointerEl(group, elOption, axisModel, axisPointerModel); + this.createLabelEl(group, elOption, axisModel, axisPointerModel); + api.getZr().add(group); + } else { + var doUpdateProps = curry(updateProps$1, axisPointerModel, moveAnimation); + this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel); + this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel); + } + + updateMandatoryProps(group, axisPointerModel, true); + + this._renderHandle(value); + }, + + /** + * @implement + */ + remove: function(api) { + this.clear(api); + }, + + /** + * @implement + */ + dispose: function(api) { + this.clear(api); + }, + + /** + * @protected + */ + determineAnimation: function(axisModel, axisPointerModel) { + var animation = axisPointerModel.get('animation'); + var axis = axisModel.axis; + var isCategoryAxis = axis.type === 'category'; + var useSnap = axisPointerModel.get('snap'); + + // Value axis without snap always do not snap. + if (!useSnap && !isCategoryAxis) { + return false; + } + + if (animation === 'auto' || animation == null) { + var animationThreshold = this.animationThreshold; + if (isCategoryAxis && axis.getBandWidth() > animationThreshold) { + return true; + } + + // It is important to auto animation when snap used. Consider if there is + // a dataZoom, animation will be disabled when too many points exist, while + // it will be enabled for better visual effect when little points exist. + if (useSnap) { + var seriesDataCount = getAxisInfo(axisModel).seriesDataCount; + var axisExtent = axis.getExtent(); + // Approximate band width + return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold; + } + + return false; + } + + return animation === true; + }, + + /** + * add {pointer, label, graphicKey} to elOption + * @protected + */ + makeElOption: function(elOption, value, axisModel, axisPointerModel, api) { + // Shoule be implemenented by sub-class. + }, + + /** + * @protected + */ + createPointerEl: function(group, elOption, axisModel, axisPointerModel) { + var pointerOption = elOption.pointer; + if (pointerOption) { + var pointerEl = inner$9(group).pointerEl = new graphic[pointerOption.type]( + clone$4(elOption.pointer) + ); + group.add(pointerEl); + } + }, + + /** + * @protected + */ + createLabelEl: function(group, elOption, axisModel, axisPointerModel) { + if (elOption.label) { + var labelEl = inner$9(group).labelEl = new Rect( + clone$4(elOption.label) + ); + + group.add(labelEl); + updateLabelShowHide(labelEl, axisPointerModel); + } + }, + + /** + * @protected + */ + updatePointerEl: function(group, elOption, updateProps$$1) { + var pointerEl = inner$9(group).pointerEl; + if (pointerEl) { + pointerEl.setStyle(elOption.pointer.style); + updateProps$$1(pointerEl, { + shape: elOption.pointer.shape + }); + } + }, + + /** + * @protected + */ + updateLabelEl: function(group, elOption, updateProps$$1, axisPointerModel) { + var labelEl = inner$9(group).labelEl; + if (labelEl) { + labelEl.setStyle(elOption.label.style); + updateProps$$1(labelEl, { + // Consider text length change in vertical axis, animation should + // be used on shape, otherwise the effect will be weird. + shape: elOption.label.shape, + position: elOption.label.position + }); + + updateLabelShowHide(labelEl, axisPointerModel); + } + }, + + /** + * @private + */ + _renderHandle: function(value) { + if (this._dragging || !this.updateHandleTransform) { + return; + } + + var axisPointerModel = this._axisPointerModel; + var zr = this._api.getZr(); + var handle = this._handle; + var handleModel = axisPointerModel.getModel('handle'); + + var status = axisPointerModel.get('status'); + if (!handleModel.get('show') || !status || status === 'hide') { + handle && zr.remove(handle); + this._handle = null; + return; + } + + var isInit; + if (!this._handle) { + isInit = true; + handle = this._handle = createIcon( + handleModel.get('icon'), { + cursor: 'move', + draggable: true, + onmousemove: function(e) { + // Fot mobile devicem, prevent screen slider on the button. + stop(e.event); + }, + onmousedown: bind$2(this._onHandleDragMove, this, 0, 0), + drift: bind$2(this._onHandleDragMove, this), + ondragend: bind$2(this._onHandleDragEnd, this) + } + ); + zr.add(handle); + } + + updateMandatoryProps(handle, axisPointerModel, false); + + // update style + var includeStyles = [ + 'color', 'borderColor', 'borderWidth', 'opacity', + 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY' + ]; + handle.setStyle(handleModel.getItemStyle(null, includeStyles)); + + // update position + var handleSize = handleModel.get('size'); + if (!isArray(handleSize)) { + handleSize = [handleSize, handleSize]; + } + handle.attr('scale', [handleSize[0] / 2, handleSize[1] / 2]); + + createOrUpdate( + this, + '_doDispatchAxisPointer', + handleModel.get('throttle') || 0, + 'fixRate' + ); + + this._moveHandleToValue(value, isInit); + }, + + /** + * @private + */ + _moveHandleToValue: function(value, isInit) { + updateProps$1( + this._axisPointerModel, + !isInit && this._moveAnimation, + this._handle, + getHandleTransProps(this.getHandleTransform( + value, this._axisModel, this._axisPointerModel + )) + ); + }, + + /** + * @private + */ + _onHandleDragMove: function(dx, dy) { + var handle = this._handle; + if (!handle) { + return; + } + + this._dragging = true; + + // Persistent for throttle. + var trans = this.updateHandleTransform( + getHandleTransProps(handle), + [dx, dy], + this._axisModel, + this._axisPointerModel + ); + this._payloadInfo = trans; + + handle.stopAnimation(); + handle.attr(getHandleTransProps(trans)); + inner$9(handle).lastProp = null; + + this._doDispatchAxisPointer(); + }, + + /** + * Throttled method. + * @private + */ + _doDispatchAxisPointer: function() { + var handle = this._handle; + if (!handle) { + return; + } + + var payloadInfo = this._payloadInfo; + var axisModel = this._axisModel; + this._api.dispatchAction({ + type: 'updateAxisPointer', + x: payloadInfo.cursorPoint[0], + y: payloadInfo.cursorPoint[1], + tooltipOption: payloadInfo.tooltipOption, + axesInfo: [{ + axisDim: axisModel.axis.dim, + axisIndex: axisModel.componentIndex + }] + }); + }, + + /** + * @private + */ + _onHandleDragEnd: function(moveAnimation) { + this._dragging = false; + var handle = this._handle; + if (!handle) { + return; + } + + var value = this._axisPointerModel.get('value'); + // Consider snap or categroy axis, handle may be not consistent with + // axisPointer. So move handle to align the exact value position when + // drag ended. + this._moveHandleToValue(value); + + // For the effect: tooltip will be shown when finger holding on handle + // button, and will be hidden after finger left handle button. + this._api.dispatchAction({ + type: 'hideTip' + }); + }, + + /** + * Should be implemenented by sub-class if support `handle`. + * @protected + * @param {number} value + * @param {module:echarts/model/Model} axisModel + * @param {module:echarts/model/Model} axisPointerModel + * @return {Object} {position: [x, y], rotation: 0} + */ + getHandleTransform: null, + + /** + * * Should be implemenented by sub-class if support `handle`. + * @protected + * @param {Object} transform {position, rotation} + * @param {Array.} delta [dx, dy] + * @param {module:echarts/model/Model} axisModel + * @param {module:echarts/model/Model} axisPointerModel + * @return {Object} {position: [x, y], rotation: 0, cursorPoint: [x, y]} + */ + updateHandleTransform: null, + + /** + * @private + */ + clear: function(api) { + this._lastValue = null; + this._lastStatus = null; + + var zr = api.getZr(); + var group = this._group; + var handle = this._handle; + if (zr && group) { + this._lastGraphicKey = null; + group && zr.remove(group); + handle && zr.remove(handle); + this._group = null; + this._handle = null; + this._payloadInfo = null; + } + }, + + /** + * @protected + */ + doClear: function() { + // Implemented by sub-class if necessary. + }, + + /** + * @protected + * @param {Array.} xy + * @param {Array.} wh + * @param {number} [xDimIndex=0] or 1 + */ + buildLabel: function(xy, wh, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x: xy[xDimIndex], + y: xy[1 - xDimIndex], + width: wh[xDimIndex], + height: wh[1 - xDimIndex] + }; + } + }; + + BaseAxisPointer.prototype.constructor = BaseAxisPointer; + + + function updateProps$1(animationModel, moveAnimation, el, props) { + // Animation optimize. + if (!propsEqual(inner$9(el).lastProp, props)) { + inner$9(el).lastProp = props; + moveAnimation + ? + updateProps(el, props, animationModel) : + (el.stopAnimation(), el.attr(props)); + } + } + + function propsEqual(lastProps, newProps) { + if (isObject$1(lastProps) && isObject$1(newProps)) { + var equals = true; + each$1(newProps, function(item, key) { + equals = equals && propsEqual(lastProps[key], item); + }); + return !!equals; + } else { + return lastProps === newProps; + } + } + + function updateLabelShowHide(labelEl, axisPointerModel) { + labelEl[axisPointerModel.get('label.show') ? 'show' : 'hide'](); + } + + function getHandleTransProps(trans) { + return { + position: trans.position.slice(), + rotation: trans.rotation || 0 + }; + } + + function updateMandatoryProps(group, axisPointerModel, silent) { + var z = axisPointerModel.get('z'); + var zlevel = axisPointerModel.get('zlevel'); + + group && group.traverse(function(el) { + if (el.type !== 'group') { + z != null && (el.z = z); + zlevel != null && (el.zlevel = zlevel); + el.silent = silent; + } + }); + } + + enableClassExtend(BaseAxisPointer); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/model/Model} axisPointerModel + */ + function buildElStyle(axisPointerModel) { + var axisPointerType = axisPointerModel.get('type'); + var styleModel = axisPointerModel.getModel(axisPointerType + 'Style'); + var style; + if (axisPointerType === 'line') { + style = styleModel.getLineStyle(); + style.fill = null; + } else if (axisPointerType === 'shadow') { + style = styleModel.getAreaStyle(); + style.stroke = null; + } + return style; + } + + /** + * @param {Function} labelPos {align, verticalAlign, position} + */ + function buildLabelElOption( + elOption, axisModel, axisPointerModel, api, labelPos + ) { + var value = axisPointerModel.get('value'); + var text = getValueLabel( + value, axisModel.axis, axisModel.ecModel, + axisPointerModel.get('seriesDataIndices'), { + precision: axisPointerModel.get('label.precision'), + formatter: axisPointerModel.get('label.formatter') + } + ); + var labelModel = axisPointerModel.getModel('label'); + var paddings = normalizeCssArray$1(labelModel.get('padding') || 0); + + var font = labelModel.getFont(); + var textRect = getBoundingRect(text, font); + + var position = labelPos.position; + var width = textRect.width + paddings[1] + paddings[3]; + var height = textRect.height + paddings[0] + paddings[2]; + + // Adjust by align. + var align = labelPos.align; + align === 'right' && (position[0] -= width); + align === 'center' && (position[0] -= width / 2); + var verticalAlign = labelPos.verticalAlign; + verticalAlign === 'bottom' && (position[1] -= height); + verticalAlign === 'middle' && (position[1] -= height / 2); + + // Not overflow ec container + confineInContainer(position, width, height, api); + + var bgColor = labelModel.get('backgroundColor'); + if (!bgColor || bgColor === 'auto') { + bgColor = axisModel.get('axisLine.lineStyle.color'); + } + + elOption.label = { + shape: { + x: 0, + y: 0, + width: width, + height: height, + r: labelModel.get('borderRadius') + }, + position: position.slice(), + // TODO: rich + style: { + text: text, + textFont: font, + textFill: labelModel.getTextColor(), + textPosition: 'inside', + fill: bgColor, + stroke: labelModel.get('borderColor') || 'transparent', + lineWidth: labelModel.get('borderWidth') || 0, + shadowBlur: labelModel.get('shadowBlur'), + shadowColor: labelModel.get('shadowColor'), + shadowOffsetX: labelModel.get('shadowOffsetX'), + shadowOffsetY: labelModel.get('shadowOffsetY') + }, + // Lable should be over axisPointer. + z2: 10 + }; + } + + // Do not overflow ec container + function confineInContainer(position, width, height, api) { + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + position[0] = Math.min(position[0] + width, viewWidth) - width; + position[1] = Math.min(position[1] + height, viewHeight) - height; + position[0] = Math.max(position[0], 0); + position[1] = Math.max(position[1], 0); + } + + /** + * @param {number} value + * @param {module:echarts/coord/Axis} axis + * @param {module:echarts/model/Global} ecModel + * @param {Object} opt + * @param {Array.} seriesDataIndices + * @param {number|string} opt.precision 'auto' or a number + * @param {string|Function} opt.formatter label formatter + */ + function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) { + value = axis.scale.parse(value); + var text = axis.scale.getLabel( + // If `precision` is set, width can be fixed (like '12.00500'), which + // helps to debounce when when moving label. + value, { + precision: opt.precision + } + ); + var formatter = opt.formatter; + + if (formatter) { + var params = { + value: getAxisRawValue(axis, value), + seriesData: [] + }; + each$1(seriesDataIndices, function(idxItem) { + var series = ecModel.getSeriesByIndex(idxItem.seriesIndex); + var dataIndex = idxItem.dataIndexInside; + var dataParams = series && series.getDataParams(dataIndex); + dataParams && params.seriesData.push(dataParams); + }); + + if (isString(formatter)) { + text = formatter.replace('{value}', text); + } else if (isFunction$1(formatter)) { + text = formatter(params); + } + } + + return text; + } + + /** + * @param {module:echarts/coord/Axis} axis + * @param {number} value + * @param {Object} layoutInfo { + * rotation, position, labelOffset, labelDirection, labelMargin + * } + */ + function getTransformedPosition(axis, value, layoutInfo) { + var transform = create$1(); + rotate(transform, transform, layoutInfo.rotation); + translate(transform, transform, layoutInfo.position); + + return applyTransform$1([ + axis.dataToCoord(value), + (layoutInfo.labelOffset || 0) + + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0) + ], transform); + } + + function buildCartesianSingleLabelElOption( + value, elOption, layoutInfo, axisModel, axisPointerModel, api + ) { + var textLayout = AxisBuilder.innerTextLayout( + layoutInfo.rotation, 0, layoutInfo.labelDirection + ); + layoutInfo.labelMargin = axisPointerModel.get('label.margin'); + buildLabelElOption(elOption, axisModel, axisPointerModel, api, { + position: getTransformedPosition(axisModel.axis, value, layoutInfo), + align: textLayout.textAlign, + verticalAlign: textLayout.textVerticalAlign + }); + } + + /** + * @param {Array.} p1 + * @param {Array.} p2 + * @param {number} [xDimIndex=0] or 1 + */ + function makeLineShape(p1, p2, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x1: p1[xDimIndex], + y1: p1[1 - xDimIndex], + x2: p2[xDimIndex], + y2: p2[1 - xDimIndex] + }; + } + + /** + * @param {Array.} xy + * @param {Array.} wh + * @param {number} [xDimIndex=0] or 1 + */ + function makeRectShape(xy, wh, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x: xy[xDimIndex], + y: xy[1 - xDimIndex], + width: wh[xDimIndex], + height: wh[1 - xDimIndex] + }; + } + + function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) { + return { + cx: cx, + cy: cy, + r0: r0, + r: r, + startAngle: startAngle, + endAngle: endAngle, + clockwise: true + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var CartesianAxisPointer = BaseAxisPointer.extend({ + + /** + * @override + */ + makeElOption: function(elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + var grid = axis.grid; + var axisPointerType = axisPointerModel.get('type'); + var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent(); + var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true)); + + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder[axisPointerType]( + axis, pixelValue, otherExtent, elStyle + ); + pointerOption.style = elStyle; + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + + var layoutInfo = layout$1(grid.model, axisModel); + buildCartesianSingleLabelElOption( + value, elOption, layoutInfo, axisModel, axisPointerModel, api + ); + }, + + /** + * @override + */ + getHandleTransform: function(value, axisModel, axisPointerModel) { + var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, { + labelInside: false + }); + layoutInfo.labelMargin = axisPointerModel.get('handle.margin'); + return { + position: getTransformedPosition(axisModel.axis, value, layoutInfo), + rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0) + }; + }, + + /** + * @override + */ + updateHandleTransform: function(transform, delta, axisModel, axisPointerModel) { + var axis = axisModel.axis; + var grid = axis.grid; + var axisExtent = axis.getGlobalExtent(true); + var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent(); + var dimIndex = axis.dim === 'x' ? 0 : 1; + + var currPosition = transform.position; + currPosition[dimIndex] += delta[dimIndex]; + currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]); + currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]); + + var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2; + var cursorPoint = [cursorOtherValue, cursorOtherValue]; + cursorPoint[dimIndex] = currPosition[dimIndex]; + + // Make tooltip do not overlap axisPointer and in the middle of the grid. + var tooltipOptions = [{ + verticalAlign: 'middle' + }, { + align: 'center' + }]; + + return { + position: currPosition, + rotation: transform.rotation, + cursorPoint: cursorPoint, + tooltipOption: tooltipOptions[dimIndex] + }; + } + + }); + + function getCartesian(grid, axis) { + var opt = {}; + opt[axis.dim + 'AxisIndex'] = axis.index; + return grid.getCartesian(opt); + } + + var pointerShapeBuilder = { + + line: function(axis, pixelValue, otherExtent, elStyle) { + var targetShape = makeLineShape( + [pixelValue, otherExtent[0]], + [pixelValue, otherExtent[1]], + getAxisDimIndex(axis) + ); + subPixelOptimizeLine({ + shape: targetShape, + style: elStyle + }); + return { + type: 'Line', + shape: targetShape + }; + }, + + shadow: function(axis, pixelValue, otherExtent, elStyle) { + var bandWidth = Math.max(1, axis.getBandWidth()); + var span = otherExtent[1] - otherExtent[0]; + return { + type: 'Rect', + shape: makeRectShape( + [pixelValue - bandWidth / 2, otherExtent[0]], + [bandWidth, span], + getAxisDimIndex(axis) + ) + }; + } + }; + + function getAxisDimIndex(axis) { + return axis.dim === 'x' ? 0 : 1; + } + + AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // CartesianAxisPointer is not supposed to be required here. But consider + // echarts.simple.js and online build tooltip, which only require gridSimple, + // CartesianAxisPointer should be able to required somewhere. + registerPreprocessor(function(option) { + // Always has a global axisPointerModel for default setting. + if (option) { + (!option.axisPointer || option.axisPointer.length === 0) && + (option.axisPointer = {}); + + var link = option.axisPointer.link; + // Normalize to array to avoid object mergin. But if link + // is not set, remain null/undefined, otherwise it will + // override existent link setting. + if (link && !isArray(link)) { + option.axisPointer.link = [link]; + } + } + }); + + // This process should proformed after coordinate systems created + // and series data processed. So put it on statistic processing stage. + registerProcessor(PRIORITY.PROCESSOR.STATISTIC, function(ecModel, api) { + // Build axisPointerModel, mergin tooltip.axisPointer model for each axis. + // allAxesInfo should be updated when setOption performed. + ecModel.getComponent('axisPointer').coordSysAxesInfo = collect(ecModel, api); + }); + + // Broadcast to all views. + registerAction({ + type: 'updateAxisPointer', + event: 'updateAxisPointer', + update: ':updateAxisPointer' + }, axisTrigger); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var XY = ['x', 'y']; + var WH = ['width', 'height']; + + var SingleAxisPointer = BaseAxisPointer.extend({ + + /** + * @override + */ + makeElOption: function(elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + var coordSys = axis.coordinateSystem; + var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis)); + var pixelValue = coordSys.dataToPoint(value)[0]; + + var axisPointerType = axisPointerModel.get('type'); + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder$1[axisPointerType]( + axis, pixelValue, otherExtent, elStyle + ); + pointerOption.style = elStyle; + + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + + var layoutInfo = layout$2(axisModel); + buildCartesianSingleLabelElOption( + value, elOption, layoutInfo, axisModel, axisPointerModel, api + ); + }, + + /** + * @override + */ + getHandleTransform: function(value, axisModel, axisPointerModel) { + var layoutInfo = layout$2(axisModel, { + labelInside: false + }); + layoutInfo.labelMargin = axisPointerModel.get('handle.margin'); + return { + position: getTransformedPosition(axisModel.axis, value, layoutInfo), + rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0) + }; + }, + + /** + * @override + */ + updateHandleTransform: function(transform, delta, axisModel, axisPointerModel) { + var axis = axisModel.axis; + var coordSys = axis.coordinateSystem; + var dimIndex = getPointDimIndex(axis); + var axisExtent = getGlobalExtent(coordSys, dimIndex); + var currPosition = transform.position; + currPosition[dimIndex] += delta[dimIndex]; + currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]); + currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]); + var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex); + var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2; + var cursorPoint = [cursorOtherValue, cursorOtherValue]; + cursorPoint[dimIndex] = currPosition[dimIndex]; + + return { + position: currPosition, + rotation: transform.rotation, + cursorPoint: cursorPoint, + tooltipOption: { + verticalAlign: 'middle' + } + }; + } + }); + + var pointerShapeBuilder$1 = { + + line: function(axis, pixelValue, otherExtent, elStyle) { + var targetShape = makeLineShape( + [pixelValue, otherExtent[0]], + [pixelValue, otherExtent[1]], + getPointDimIndex(axis) + ); + subPixelOptimizeLine({ + shape: targetShape, + style: elStyle + }); + return { + type: 'Line', + shape: targetShape + }; + }, + + shadow: function(axis, pixelValue, otherExtent, elStyle) { + var bandWidth = axis.getBandWidth(); + var span = otherExtent[1] - otherExtent[0]; + return { + type: 'Rect', + shape: makeRectShape( + [pixelValue - bandWidth / 2, otherExtent[0]], + [bandWidth, span], + getPointDimIndex(axis) + ) + }; + } + }; + + function getPointDimIndex(axis) { + return axis.isHorizontal() ? 0 : 1; + } + + function getGlobalExtent(coordSys, dimIndex) { + var rect = coordSys.getRect(); + return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]]; + } + + AxisView.registerAxisPointerClass('SingleAxisPointer', SingleAxisPointer); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentView({ + type: 'single' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Define the themeRiver view's series model + * @author Deqing Li(annong035@gmail.com) + */ + + var DATA_NAME_INDEX = 2; + + var ThemeRiverSeries = SeriesModel.extend({ + + type: 'series.themeRiver', + + dependencies: ['singleAxis'], + + /** + * @readOnly + * @type {module:zrender/core/util#HashMap} + */ + nameMap: null, + + /** + * @override + */ + init: function(option) { + ThemeRiverSeries.superApply(this, 'init', arguments); + + // Put this function here is for the sake of consistency of code style. + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendDataProvider = function() { + return this.getRawData(); + }; + }, + + /** + * If there is no value of a certain point in the time for some event,set it value to 0. + * + * @param {Array} data initial data in the option + * @return {Array} + */ + fixData: function(data) { + var rawDataLength = data.length; + + // grouped data by name + var dataByName = nest() + .key(function(dataItem) { + return dataItem[2]; + }) + .entries(data); + + // data group in each layer + var layData = map(dataByName, function(d) { + return { + name: d.key, + dataList: d.values + }; + }); + + var layerNum = layData.length; + var largestLayer = -1; + var index = -1; + for (var i = 0; i < layerNum; ++i) { + var len = layData[i].dataList.length; + if (len > largestLayer) { + largestLayer = len; + index = i; + } + } + + for (var k = 0; k < layerNum; ++k) { + if (k === index) { + continue; + } + var name = layData[k].name; + for (var j = 0; j < largestLayer; ++j) { + var timeValue = layData[index].dataList[j][0]; + var length = layData[k].dataList.length; + var keyIndex = -1; + for (var l = 0; l < length; ++l) { + var value = layData[k].dataList[l][0]; + if (value === timeValue) { + keyIndex = l; + break; + } + } + if (keyIndex === -1) { + data[rawDataLength] = []; + data[rawDataLength][0] = timeValue; + data[rawDataLength][1] = 0; + data[rawDataLength][2] = name; + rawDataLength++; + + } + } + } + return data; + }, + + /** + * @override + * @param {Object} option the initial option that user gived + * @param {module:echarts/model/Model} ecModel the model object for themeRiver option + * @return {module:echarts/data/List} + */ + getInitialData: function(option, ecModel) { + + var singleAxisModel = ecModel.queryComponents({ + mainType: 'singleAxis', + index: this.get('singleAxisIndex'), + id: this.get('singleAxisId') + })[0]; + + var axisType = singleAxisModel.get('type'); + + // filter the data item with the value of label is undefined + var filterData = filter(option.data, function(dataItem) { + return dataItem[2] !== undefined; + }); + + // ??? TODO design a stage to transfer data for themeRiver and lines? + var data = this.fixData(filterData || []); + var nameList = []; + var nameMap = this.nameMap = createHashMap(); + var count = 0; + + for (var i = 0; i < data.length; ++i) { + nameList.push(data[i][DATA_NAME_INDEX]); + if (!nameMap.get(data[i][DATA_NAME_INDEX])) { + nameMap.set(data[i][DATA_NAME_INDEX], count); + count++; + } + } + + var dimensionsInfo = createDimensions(data, { + coordDimensions: ['single'], + dimensionsDefine: [{ + name: 'time', + type: getDimensionTypeByAxis(axisType) + }, + { + name: 'value', + type: 'float' + }, + { + name: 'name', + type: 'ordinal' + } + ], + encodeDefine: { + single: 0, + value: 1, + itemName: 2 + } + }); + + var list = new List(dimensionsInfo, this); + list.initData(data); + + return list; + }, + + /** + * The raw data is divided into multiple layers and each layer + * has same name. + * + * @return {Array.>} + */ + getLayerSeries: function() { + var data = this.getData(); + var lenCount = data.count(); + var indexArr = []; + + for (var i = 0; i < lenCount; ++i) { + indexArr[i] = i; + } + // data group by name + var dataByName = nest() + .key(function(index) { + return data.get('name', index); + }) + .entries(indexArr); + + var layerSeries = map(dataByName, function(d) { + return { + name: d.key, + indices: d.values + }; + }); + + var timeDim = data.mapDimension('single'); + + for (var j = 0; j < layerSeries.length; ++j) { + layerSeries[j].indices.sort(comparer); + } + + function comparer(index1, index2) { + return data.get(timeDim, index1) - data.get(timeDim, index2); + } + + return layerSeries; + }, + + /** + * Get data indices for show tooltip content + * + * @param {Array.|string} dim single coordinate dimension + * @param {number} value axis value + * @param {module:echarts/coord/single/SingleAxis} baseAxis single Axis used + * the themeRiver. + * @return {Object} {dataIndices, nestestValue} + */ + getAxisTooltipData: function(dim, value, baseAxis) { + if (!isArray(dim)) { + dim = dim ? [dim] : []; + } + + var data = this.getData(); + var layerSeries = this.getLayerSeries(); + var indices = []; + var layerNum = layerSeries.length; + var nestestValue; + + for (var i = 0; i < layerNum; ++i) { + var minDist = Number.MAX_VALUE; + var nearestIdx = -1; + var pointNum = layerSeries[i].indices.length; + for (var j = 0; j < pointNum; ++j) { + var theValue = data.get(dim[0], layerSeries[i].indices[j]); + var dist = Math.abs(theValue - value); + if (dist <= minDist) { + nestestValue = theValue; + minDist = dist; + nearestIdx = layerSeries[i].indices[j]; + } + } + indices.push(nearestIdx); + } + + return { + dataIndices: indices, + nestestValue: nestestValue + }; + }, + + /** + * @override + * @param {number} dataIndex index of data + */ + formatTooltip: function(dataIndex) { + var data = this.getData(); + var htmlName = data.getName(dataIndex); + var htmlValue = data.get(data.mapDimension('value'), dataIndex); + if (isNaN(htmlValue) || htmlValue == null) { + htmlValue = '-'; + } + return encodeHTML(htmlName + ' : ' + htmlValue); + }, + + defaultOption: { + zlevel: 0, + z: 2, + + coordinateSystem: 'singleAxis', + + // gap in axis's orthogonal orientation + boundaryGap: ['10%', '10%'], + + // legendHoverLink: true, + + singleAxisIndex: 0, + + animationEasing: 'linear', + + label: { + margin: 4, + show: true, + position: 'left', + color: '#000', + fontSize: 11 + }, + + emphasis: { + label: { + show: true + } + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file The file used to draw themeRiver view + * @author Deqing Li(annong035@gmail.com) + */ + + extendChartView({ + + type: 'themeRiver', + + init: function() { + this._layers = []; + }, + + render: function(seriesModel, ecModel, api) { + var data = seriesModel.getData(); + + var group = this.group; + + var layerSeries = seriesModel.getLayerSeries(); + + var layoutInfo = data.getLayout('layoutInfo'); + var rect = layoutInfo.rect; + var boundaryGap = layoutInfo.boundaryGap; + + group.attr('position', [0, rect.y + boundaryGap[0]]); + + function keyGetter(item) { + return item.name; + } + var dataDiffer = new DataDiffer( + this._layersSeries || [], layerSeries, + keyGetter, keyGetter + ); + + var newLayersGroups = {}; + + dataDiffer + .add(bind(process, this, 'add')) + .update(bind(process, this, 'update')) + .remove(bind(process, this, 'remove')) + .execute(); + + function process(status, idx, oldIdx) { + var oldLayersGroups = this._layers; + if (status === 'remove') { + group.remove(oldLayersGroups[idx]); + return; + } + var points0 = []; + var points1 = []; + var color; + var indices = layerSeries[idx].indices; + for (var j = 0; j < indices.length; j++) { + var layout = data.getItemLayout(indices[j]); + var x = layout.x; + var y0 = layout.y0; + var y = layout.y; + + points0.push([x, y0]); + points1.push([x, y0 + y]); + + color = data.getItemVisual(indices[j], 'color'); + } + + var polygon; + var text; + var textLayout = data.getItemLayout(indices[0]); + var itemModel = data.getItemModel(indices[j - 1]); + var labelModel = itemModel.getModel('label'); + var margin = labelModel.get('margin'); + if (status === 'add') { + var layerGroup = newLayersGroups[idx] = new Group(); + polygon = new Polygon$1({ + shape: { + points: points0, + stackedOnPoints: points1, + smooth: 0.4, + stackedOnSmooth: 0.4, + smoothConstraint: false + }, + z2: 0 + }); + text = new Text({ + style: { + x: textLayout.x - margin, + y: textLayout.y0 + textLayout.y / 2 + } + }); + layerGroup.add(polygon); + layerGroup.add(text); + group.add(layerGroup); + + polygon.setClipPath(createGridClipShape$3(polygon.getBoundingRect(), seriesModel, function() { + polygon.removeClipPath(); + })); + } else { + var layerGroup = oldLayersGroups[oldIdx]; + polygon = layerGroup.childAt(0); + text = layerGroup.childAt(1); + group.add(layerGroup); + + newLayersGroups[idx] = layerGroup; + + updateProps(polygon, { + shape: { + points: points0, + stackedOnPoints: points1 + } + }, seriesModel); + + updateProps(text, { + style: { + x: textLayout.x - margin, + y: textLayout.y0 + textLayout.y / 2 + } + }, seriesModel); + } + + var hoverItemStyleModel = itemModel.getModel('emphasis.itemStyle'); + var itemStyleModel = itemModel.getModel('itemStyle'); + + setTextStyle(text.style, labelModel, { + text: labelModel.get('show') ? + seriesModel.getFormattedLabel(indices[j - 1], 'normal') || + data.getName(indices[j - 1]) : + null, + textVerticalAlign: 'middle' + }); + + polygon.setStyle(extend({ + fill: color + }, itemStyleModel.getItemStyle(['color']))); + + setHoverStyle(polygon, hoverItemStyleModel.getItemStyle()); + } + + this._layersSeries = layerSeries; + this._layers = newLayersGroups; + }, + + dispose: function() {} + }); + + // add animation to the view + function createGridClipShape$3(rect, seriesModel, cb) { + var rectEl = new Rect({ + shape: { + x: rect.x - 10, + y: rect.y - 10, + width: 0, + height: rect.height + 20 + } + }); + initProps(rectEl, { + shape: { + width: rect.width + 20, + height: rect.height + 20 + } + }, seriesModel, cb); + + return rectEl; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Using layout algorithm transform the raw data to layout information. + * @author Deqing Li(annong035@gmail.com) + */ + + var themeRiverLayout = function(ecModel, api) { + + ecModel.eachSeriesByType('themeRiver', function(seriesModel) { + + var data = seriesModel.getData(); + + var single = seriesModel.coordinateSystem; + + var layoutInfo = {}; + + // use the axis boundingRect for view + var rect = single.getRect(); + + layoutInfo.rect = rect; + + var boundaryGap = seriesModel.get('boundaryGap'); + + var axis = single.getAxis(); + + layoutInfo.boundaryGap = boundaryGap; + + if (axis.orient === 'horizontal') { + boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.height); + boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.height); + var height = rect.height - boundaryGap[0] - boundaryGap[1]; + themeRiverLayout$1(data, seriesModel, height); + } else { + boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.width); + boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.width); + var width = rect.width - boundaryGap[0] - boundaryGap[1]; + themeRiverLayout$1(data, seriesModel, width); + } + + data.setLayout('layoutInfo', layoutInfo); + }); + }; + + /** + * The layout information about themeriver + * + * @param {module:echarts/data/List} data data in the series + * @param {module:echarts/model/Series} seriesModel the model object of themeRiver series + * @param {number} height value used to compute every series height + */ + function themeRiverLayout$1(data, seriesModel, height) { + if (!data.count()) { + return; + } + var coordSys = seriesModel.coordinateSystem; + // the data in each layer are organized into a series. + var layerSeries = seriesModel.getLayerSeries(); + + // the points in each layer. + var timeDim = data.mapDimension('single'); + var valueDim = data.mapDimension('value'); + var layerPoints = map(layerSeries, function(singleLayer) { + return map(singleLayer.indices, function(idx) { + var pt = coordSys.dataToPoint(data.get(timeDim, idx)); + pt[1] = data.get(valueDim, idx); + return pt; + }); + }); + + var base = computeBaseline(layerPoints); + var baseLine = base.y0; + var ky = height / base.max; + + // set layout information for each item. + var n = layerSeries.length; + var m = layerSeries[0].indices.length; + var baseY0; + for (var j = 0; j < m; ++j) { + baseY0 = baseLine[j] * ky; + data.setItemLayout(layerSeries[0].indices[j], { + layerIndex: 0, + x: layerPoints[0][j][0], + y0: baseY0, + y: layerPoints[0][j][1] * ky + }); + for (var i = 1; i < n; ++i) { + baseY0 += layerPoints[i - 1][j][1] * ky; + data.setItemLayout(layerSeries[i].indices[j], { + layerIndex: i, + x: layerPoints[i][j][0], + y0: baseY0, + y: layerPoints[i][j][1] * ky + }); + } + } + } + + /** + * Compute the baseLine of the rawdata + * Inspired by Lee Byron's paper Stacked Graphs - Geometry & Aesthetics + * + * @param {Array.} data the points in each layer + * @return {Object} + */ + function computeBaseline(data) { + var layerNum = data.length; + var pointNum = data[0].length; + var sums = []; + var y0 = []; + var max = 0; + var temp; + var base = {}; + + for (var i = 0; i < pointNum; ++i) { + for (var j = 0, temp = 0; j < layerNum; ++j) { + temp += data[j][i][1]; + } + if (temp > max) { + max = temp; + } + sums.push(temp); + } + + for (var k = 0; k < pointNum; ++k) { + y0[k] = (max - sums[k]) / 2; + } + max = 0; + + for (var l = 0; l < pointNum; ++l) { + var sum = sums[l] + y0[l]; + if (sum > max) { + max = sum; + } + } + base.y0 = y0; + base.max = max; + + return base; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Visual encoding for themeRiver view + * @author Deqing Li(annong035@gmail.com) + */ + + var themeRiverVisual = function(ecModel) { + ecModel.eachSeriesByType('themeRiver', function(seriesModel) { + var data = seriesModel.getData(); + var rawData = seriesModel.getRawData(); + var colorList = seriesModel.get('color'); + var idxMap = createHashMap(); + + data.each(function(idx) { + idxMap.set(data.getRawIndex(idx), idx); + }); + + rawData.each(function(rawIndex) { + var name = rawData.getName(rawIndex); + var color = colorList[(seriesModel.nameMap.get(name) - 1) % colorList.length]; + + rawData.setItemVisual(rawIndex, 'color', color); + + var idx = idxMap.get(rawIndex); + + if (idx != null) { + data.setItemVisual(idx, 'color', color); + } + }); + }); + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerLayout(themeRiverLayout); + registerVisual(themeRiverVisual); + registerProcessor(dataFilter('themeRiver')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + SeriesModel.extend({ + + type: 'series.sunburst', + + /** + * @type {module:echarts/data/Tree~Node} + */ + _viewRoot: null, + + getInitialData: function(option, ecModel) { + // Create a virtual root. + var root = { + name: option.name, + children: option.data + }; + + completeTreeValue$1(root); + + var levels = option.levels || []; + + // levels = option.levels = setDefault(levels, ecModel); + + var treeOption = {}; + + treeOption.levels = levels; + + // Make sure always a new tree is created when setOption, + // in TreemapView, we check whether oldTree === newTree + // to choose mappings approach among old shapes and new shapes. + return Tree.createTree(root, this, treeOption).data; + }, + + optionUpdated: function() { + this.resetViewRoot(); + }, + + /* + * @override + */ + getDataParams: function(dataIndex) { + var params = SeriesModel.prototype.getDataParams.apply(this, arguments); + + var node = this.getData().tree.getNodeByDataIndex(dataIndex); + params.treePathInfo = wrapTreePathInfo(node, this); + + return params; + }, + + defaultOption: { + zlevel: 0, + z: 2, + + // 默认全局居中 + center: ['50%', '50%'], + radius: [0, '75%'], + // 默认顺时针 + clockwise: true, + startAngle: 90, + // 最小角度改为0 + minAngle: 0, + + percentPrecision: 2, + + // If still show when all data zero. + stillShowZeroSum: true, + + // Policy of highlighting pieces when hover on one + // Valid values: 'none' (for not downplay others), 'descendant', + // 'ancestor', 'self' + highlightPolicy: 'descendant', + + // 'rootToNode', 'link', or false + nodeClick: 'rootToNode', + + renderLabelForZeroData: false, + + label: { + // could be: 'radial', 'tangential', or 'none' + rotate: 'radial', + show: true, + opacity: 1, + // 'left' is for inner side of inside, and 'right' is for outter + // side for inside + align: 'center', + position: 'inside', + distance: 5, + silent: true, + emphasis: {} + }, + itemStyle: { + borderWidth: 1, + borderColor: 'white', + opacity: 1, + emphasis: {}, + highlight: { + opacity: 1 + }, + downplay: { + opacity: 0.9 + } + }, + + // Animation type canbe expansion, scale + animationType: 'expansion', + animationDuration: 1000, + animationDurationUpdate: 500, + animationEasing: 'cubicOut', + + data: [], + + levels: [], + + /** + * Sort order. + * + * Valid values: 'desc', 'asc', null, or callback function. + * 'desc' and 'asc' for descend and ascendant order; + * null for not sorting; + * example of callback function: + * function(nodeA, nodeB) { + * return nodeA.getValue() - nodeB.getValue(); + * } + */ + sort: 'desc' + }, + + getViewRoot: function() { + return this._viewRoot; + }, + + /** + * @param {module:echarts/data/Tree~Node} [viewRoot] + */ + resetViewRoot: function(viewRoot) { + viewRoot + ? + (this._viewRoot = viewRoot) : + (viewRoot = this._viewRoot); + + var root = this.getRawData().tree.root; + + if (!viewRoot || + (viewRoot !== root && !root.contains(viewRoot)) + ) { + this._viewRoot = root; + } + } + }); + + + + /** + * @param {Object} dataNode + */ + function completeTreeValue$1(dataNode) { + // Postorder travel tree. + // If value of none-leaf node is not set, + // calculate it by suming up the value of all children. + var sum = 0; + + each$1(dataNode.children, function(child) { + + completeTreeValue$1(child); + + var childValue = child.value; + isArray(childValue) && (childValue = childValue[0]); + + sum += childValue; + }); + + var thisValue = dataNode.value; + if (isArray(thisValue)) { + thisValue = thisValue[0]; + } + + if (thisValue == null || isNaN(thisValue)) { + thisValue = sum; + } + // Value should not less than 0. + if (thisValue < 0) { + thisValue = 0; + } + + isArray(dataNode.value) ? + (dataNode.value[0] = thisValue) : + (dataNode.value = thisValue); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var NodeHighlightPolicy = { + NONE: 'none', // not downplay others + DESCENDANT: 'descendant', + ANCESTOR: 'ancestor', + SELF: 'self' + }; + + var DEFAULT_SECTOR_Z = 2; + var DEFAULT_TEXT_Z = 4; + + /** + * Sunburstce of Sunburst including Sector, Label, LabelLine + * @constructor + * @extends {module:zrender/graphic/Group} + */ + function SunburstPiece(node, seriesModel, ecModel) { + + Group.call(this); + + var sector = new Sector({ + z2: DEFAULT_SECTOR_Z + }); + sector.seriesIndex = seriesModel.seriesIndex; + + var text = new Text({ + z2: DEFAULT_TEXT_Z, + silent: node.getModel('label').get('silent') + }); + this.add(sector); + this.add(text); + + this.updateData(true, node, 'normal', seriesModel, ecModel); + + // Hover to change label and labelLine + function onEmphasis() { + text.ignore = text.hoverIgnore; + } + + function onNormal() { + text.ignore = text.normalIgnore; + } + this.on('emphasis', onEmphasis) + .on('normal', onNormal) + .on('mouseover', onEmphasis) + .on('mouseout', onNormal); + } + + var SunburstPieceProto = SunburstPiece.prototype; + + SunburstPieceProto.updateData = function( + firstCreate, + node, + state, + seriesModel, + ecModel + ) { + this.node = node; + node.piece = this; + + seriesModel = seriesModel || this._seriesModel; + ecModel = ecModel || this._ecModel; + + var sector = this.childAt(0); + sector.dataIndex = node.dataIndex; + + var itemModel = node.getModel(); + var layout = node.getLayout(); + if (!layout) { + console.log(node.getLayout()); + } + var sectorShape = extend({}, layout); + sectorShape.label = null; + + var visualColor = getNodeColor(node, seriesModel, ecModel); + + var normalStyle = itemModel.getModel('itemStyle').getItemStyle(); + var style; + if (state === 'normal') { + style = normalStyle; + } else { + var stateStyle = itemModel.getModel(state + '.itemStyle') + .getItemStyle(); + style = merge(stateStyle, normalStyle); + } + style = defaults({ + lineJoin: 'bevel', + fill: style.fill || visualColor + }, + style + ); + + if (firstCreate) { + sector.setShape(sectorShape); + sector.shape.r = layout.r0; + updateProps( + sector, { + shape: { + r: layout.r + } + }, + seriesModel, + node.dataIndex + ); + sector.useStyle(style); + } else if (typeof style.fill === 'object' && style.fill.type || + typeof sector.style.fill === 'object' && sector.style.fill.type + ) { + // Disable animation for gradient since no interpolation method + // is supported for gradient + updateProps(sector, { + shape: sectorShape + }, seriesModel); + sector.useStyle(style); + } else { + updateProps(sector, { + shape: sectorShape, + style: style + }, seriesModel); + } + + this._updateLabel(seriesModel, visualColor, state); + + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && sector.attr('cursor', cursorStyle); + + if (firstCreate) { + var highlightPolicy = seriesModel.getShallow('highlightPolicy'); + this._initEvents(sector, node, seriesModel, highlightPolicy); + } + + this._seriesModel = seriesModel || this._seriesModel; + this._ecModel = ecModel || this._ecModel; + }; + + SunburstPieceProto.onEmphasis = function(highlightPolicy) { + var that = this; + this.node.hostTree.root.eachNode(function(n) { + if (n.piece) { + if (that.node === n) { + n.piece.updateData(false, n, 'emphasis'); + } else if (isNodeHighlighted(n, that.node, highlightPolicy)) { + n.piece.childAt(0).trigger('highlight'); + } else if (highlightPolicy !== NodeHighlightPolicy.NONE) { + n.piece.childAt(0).trigger('downplay'); + } + } + }); + }; + + SunburstPieceProto.onNormal = function() { + this.node.hostTree.root.eachNode(function(n) { + if (n.piece) { + n.piece.updateData(false, n, 'normal'); + } + }); + }; + + SunburstPieceProto.onHighlight = function() { + this.updateData(false, this.node, 'highlight'); + }; + + SunburstPieceProto.onDownplay = function() { + this.updateData(false, this.node, 'downplay'); + }; + + SunburstPieceProto._updateLabel = function(seriesModel, visualColor, state) { + var itemModel = this.node.getModel(); + var normalModel = itemModel.getModel('label'); + var labelModel = state === 'normal' || state === 'emphasis' ? + normalModel : + itemModel.getModel(state + '.label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + + var text = retrieve( + seriesModel.getFormattedLabel( + this.node.dataIndex, 'normal', null, null, 'label' + ), + this.node.name + ); + if (getLabelAttr('show') === false) { + text = ''; + } + + var layout = this.node.getLayout(); + var labelMinAngle = labelModel.get('minAngle'); + if (labelMinAngle == null) { + labelMinAngle = normalModel.get('minAngle'); + } + labelMinAngle = labelMinAngle / 180 * Math.PI; + var angle = layout.endAngle - layout.startAngle; + if (labelMinAngle != null && Math.abs(angle) < labelMinAngle) { + // Not displaying text when angle is too small + text = ''; + } + + var label = this.childAt(1); + + setLabelStyle( + label.style, label.hoverStyle || {}, normalModel, labelHoverModel, { + defaultText: labelModel.getShallow('show') ? text : null, + autoColor: visualColor, + useInsideStyle: true + } + ); + + var midAngle = (layout.startAngle + layout.endAngle) / 2; + var dx = Math.cos(midAngle); + var dy = Math.sin(midAngle); + + var r; + var labelPosition = getLabelAttr('position'); + var labelPadding = getLabelAttr('distance') || 0; + var textAlign = getLabelAttr('align'); + if (labelPosition === 'outside') { + r = layout.r + labelPadding; + textAlign = midAngle > Math.PI / 2 ? 'right' : 'left'; + } else { + if (!textAlign || textAlign === 'center') { + r = (layout.r + layout.r0) / 2; + textAlign = 'center'; + } else if (textAlign === 'left') { + r = layout.r0 + labelPadding; + if (midAngle > Math.PI / 2) { + textAlign = 'right'; + } + } else if (textAlign === 'right') { + r = layout.r - labelPadding; + if (midAngle > Math.PI / 2) { + textAlign = 'left'; + } + } + } + + label.attr('style', { + text: text, + textAlign: textAlign, + textVerticalAlign: getLabelAttr('verticalAlign') || 'middle', + opacity: getLabelAttr('opacity') + }); + + var textX = r * dx + layout.cx; + var textY = r * dy + layout.cy; + label.attr('position', [textX, textY]); + + var rotateType = getLabelAttr('rotate'); + var rotate = 0; + if (rotateType === 'radial') { + rotate = -midAngle; + if (rotate < -Math.PI / 2) { + rotate += Math.PI; + } + } else if (rotateType === 'tangential') { + rotate = Math.PI / 2 - midAngle; + if (rotate > Math.PI / 2) { + rotate -= Math.PI; + } else if (rotate < -Math.PI / 2) { + rotate += Math.PI; + } + } else if (typeof rotateType === 'number') { + rotate = rotateType * Math.PI / 180; + } + label.attr('rotation', rotate); + + function getLabelAttr(name) { + var stateAttr = labelModel.get(name); + if (stateAttr == null) { + return normalModel.get(name); + } else { + return stateAttr; + } + } + }; + + SunburstPieceProto._initEvents = function( + sector, + node, + seriesModel, + highlightPolicy + ) { + sector.off('mouseover').off('mouseout').off('emphasis').off('normal'); + + var that = this; + var onEmphasis = function() { + that.onEmphasis(highlightPolicy); + }; + var onNormal = function() { + that.onNormal(); + }; + var onDownplay = function() { + that.onDownplay(); + }; + var onHighlight = function() { + that.onHighlight(); + }; + + if (seriesModel.isAnimationEnabled()) { + sector + .on('mouseover', onEmphasis) + .on('mouseout', onNormal) + .on('emphasis', onEmphasis) + .on('normal', onNormal) + .on('downplay', onDownplay) + .on('highlight', onHighlight); + } + }; + + inherits(SunburstPiece, Group); + + /** + * Get node color + * + * @param {TreeNode} node the node to get color + * @param {module:echarts/model/Series} seriesModel series + * @param {module:echarts/model/Global} ecModel echarts defaults + */ + function getNodeColor(node, seriesModel, ecModel) { + // Color from visualMap + var visualColor = node.getVisual('color'); + var visualMetaList = node.getVisual('visualMeta'); + if (!visualMetaList || visualMetaList.length === 0) { + // Use first-generation color if has no visualMap + visualColor = null; + } + + // Self color or level color + var color = node.getModel('itemStyle').get('color'); + if (color) { + return color; + } else if (visualColor) { + // Color mapping + return visualColor; + } else if (node.depth === 0) { + // Virtual root node + return ecModel.option.color[0]; + } else { + // First-generation color + var length = ecModel.option.color.length; + color = ecModel.option.color[getRootId(node) % length]; + } + return color; + } + + /** + * Get index of root in sorted order + * + * @param {TreeNode} node current node + * @return {number} index in root + */ + function getRootId(node) { + var ancestor = node; + while (ancestor.depth > 1) { + ancestor = ancestor.parentNode; + } + + var virtualRoot = node.getAncestors()[0]; + return indexOf(virtualRoot.children, ancestor); + } + + function isNodeHighlighted(node, activeNode, policy) { + if (policy === NodeHighlightPolicy.NONE) { + return false; + } else if (policy === NodeHighlightPolicy.SELF) { + return node === activeNode; + } else if (policy === NodeHighlightPolicy.ANCESTOR) { + return node === activeNode || node.isAncestorOf(activeNode); + } else { + return node === activeNode || node.isDescendantOf(activeNode); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var ROOT_TO_NODE_ACTION = 'sunburstRootToNode'; + + var SunburstView = Chart.extend({ + + type: 'sunburst', + + init: function() {}, + + render: function(seriesModel, ecModel, api, payload) { + var that = this; + + this.seriesModel = seriesModel; + this.api = api; + this.ecModel = ecModel; + + var data = seriesModel.getData(); + var virtualRoot = data.tree.root; + + var newRoot = seriesModel.getViewRoot(); + + var group = this.group; + + var renderLabelForZeroData = seriesModel.get('renderLabelForZeroData'); + + var newChildren = []; + newRoot.eachNode(function(node) { + newChildren.push(node); + }); + var oldChildren = this._oldChildren || []; + + dualTravel(newChildren, oldChildren); + + renderRollUp(virtualRoot, newRoot); + + if (payload && payload.highlight && payload.highlight.piece) { + var highlightPolicy = seriesModel.getShallow('highlightPolicy'); + payload.highlight.piece.onEmphasis(highlightPolicy); + } else if (payload && payload.unhighlight) { + var piece = this.virtualPiece; + if (!piece && virtualRoot.children.length) { + piece = virtualRoot.children[0].piece; + } + if (piece) { + piece.onNormal(); + } + } + + this._initEvents(); + + this._oldChildren = newChildren; + + function dualTravel(newChildren, oldChildren) { + if (newChildren.length === 0 && oldChildren.length === 0) { + return; + } + + new DataDiffer(oldChildren, newChildren, getKey, getKey) + .add(processNode) + .update(processNode) + .remove(curry(processNode, null)) + .execute(); + + function getKey(node) { + return node.getId(); + } + + function processNode(newId, oldId) { + var newNode = newId == null ? null : newChildren[newId]; + var oldNode = oldId == null ? null : oldChildren[oldId]; + + doRenderNode(newNode, oldNode); + } + } + + function doRenderNode(newNode, oldNode) { + if (!renderLabelForZeroData && newNode && !newNode.getValue()) { + // Not render data with value 0 + newNode = null; + } + + if (newNode !== virtualRoot && oldNode !== virtualRoot) { + if (oldNode && oldNode.piece) { + if (newNode) { + // Update + oldNode.piece.updateData( + false, newNode, 'normal', seriesModel, ecModel); + + // For tooltip + data.setItemGraphicEl(newNode.dataIndex, oldNode.piece); + } else { + // Remove + removeNode(oldNode); + } + } else if (newNode) { + // Add + var piece = new SunburstPiece( + newNode, + seriesModel, + ecModel + ); + group.add(piece); + + // For tooltip + data.setItemGraphicEl(newNode.dataIndex, piece); + } + } + } + + function removeNode(node) { + if (!node) { + return; + } + + if (node.piece) { + group.remove(node.piece); + node.piece = null; + } + } + + function renderRollUp(virtualRoot, viewRoot) { + if (viewRoot.depth > 0) { + // Render + if (that.virtualPiece) { + // Update + that.virtualPiece.updateData( + false, virtualRoot, 'normal', seriesModel, ecModel); + } else { + // Add + that.virtualPiece = new SunburstPiece( + virtualRoot, + seriesModel, + ecModel + ); + group.add(that.virtualPiece); + } + + if (viewRoot.piece._onclickEvent) { + viewRoot.piece.off('click', viewRoot.piece._onclickEvent); + } + var event = function(e) { + that._rootToNode(viewRoot.parentNode); + }; + viewRoot.piece._onclickEvent = event; + that.virtualPiece.on('click', event); + } else if (that.virtualPiece) { + // Remove + group.remove(that.virtualPiece); + that.virtualPiece = null; + } + } + }, + + dispose: function() {}, + + /** + * @private + */ + _initEvents: function() { + var that = this; + + var event = function(e) { + var targetFound = false; + var viewRoot = that.seriesModel.getViewRoot(); + viewRoot.eachNode(function(node) { + if (!targetFound && + node.piece && node.piece.childAt(0) === e.target + ) { + var nodeClick = node.getModel().get('nodeClick'); + if (nodeClick === 'rootToNode') { + that._rootToNode(node); + } else if (nodeClick === 'link') { + var itemModel = node.getModel(); + var link = itemModel.get('link'); + if (link) { + var linkTarget = itemModel.get('target', true) || + '_blank'; + window.open(link, linkTarget); + } + } + targetFound = true; + } + }); + }; + + if (this.group._onclickEvent) { + this.group.off('click', this.group._onclickEvent); + } + this.group.on('click', event); + this.group._onclickEvent = event; + }, + + /** + * @private + */ + _rootToNode: function(node) { + if (node !== this.seriesModel.getViewRoot()) { + this.api.dispatchAction({ + type: ROOT_TO_NODE_ACTION, + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: node + }); + } + }, + + /** + * @implement + */ + containPoint: function(point, seriesModel) { + var treeRoot = seriesModel.getData(); + var itemLayout = treeRoot.getItemLayout(0); + if (itemLayout) { + var dx = point[0] - itemLayout.cx; + var dy = point[1] - itemLayout.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + return radius <= itemLayout.r && radius >= itemLayout.r0; + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Sunburst action + */ + + var ROOT_TO_NODE_ACTION$1 = 'sunburstRootToNode'; + + registerAction({ + type: ROOT_TO_NODE_ACTION$1, + update: 'updateView' + }, + function(payload, ecModel) { + + ecModel.eachComponent({ + mainType: 'series', + subType: 'sunburst', + query: payload + }, + handleRootToNode + ); + + function handleRootToNode(model, index) { + var targetInfo = retrieveTargetInfo(payload, [ROOT_TO_NODE_ACTION$1], model); + + if (targetInfo) { + var originViewRoot = model.getViewRoot(); + if (originViewRoot) { + payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? + 'rollUp' : 'drillDown'; + } + model.resetViewRoot(targetInfo.node); + } + } + } + ); + + + var HIGHLIGHT_ACTION = 'sunburstHighlight'; + + registerAction({ + type: HIGHLIGHT_ACTION, + update: 'updateView' + }, + function(payload, ecModel) { + + ecModel.eachComponent({ + mainType: 'series', + subType: 'sunburst', + query: payload + }, + handleHighlight + ); + + function handleHighlight(model, index) { + var targetInfo = retrieveTargetInfo(payload, [HIGHLIGHT_ACTION], model); + + if (targetInfo) { + payload.highlight = targetInfo.node; + } + } + } + ); + + + var UNHIGHLIGHT_ACTION = 'sunburstUnhighlight'; + + registerAction({ + type: UNHIGHLIGHT_ACTION, + update: 'updateView' + }, + function(payload, ecModel) { + + ecModel.eachComponent({ + mainType: 'series', + subType: 'sunburst', + query: payload + }, + handleUnhighlight + ); + + function handleUnhighlight(model, index) { + payload.unhighlight = true; + } + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var RADIAN$1 = Math.PI / 180; + + var sunburstLayout = function(seriesType, ecModel, api, payload) { + ecModel.eachSeriesByType(seriesType, function(seriesModel) { + var center = seriesModel.get('center'); + var radius = seriesModel.get('radius'); + + if (!isArray(radius)) { + radius = [0, radius]; + } + if (!isArray(center)) { + center = [center, center]; + } + + var width = api.getWidth(); + var height = api.getHeight(); + var size = Math.min(width, height); + var cx = parsePercent$1(center[0], width); + var cy = parsePercent$1(center[1], height); + var r0 = parsePercent$1(radius[0], size / 2); + var r = parsePercent$1(radius[1], size / 2); + + var startAngle = -seriesModel.get('startAngle') * RADIAN$1; + var minAngle = seriesModel.get('minAngle') * RADIAN$1; + + var virtualRoot = seriesModel.getData().tree.root; + var treeRoot = seriesModel.getViewRoot(); + var rootDepth = treeRoot.depth; + + var sort = seriesModel.get('sort'); + if (sort != null) { + initChildren$1(treeRoot, sort); + } + + var validDataCount = 0; + each$1(treeRoot.children, function(child) { + !isNaN(child.getValue()) && validDataCount++; + }); + + var sum = treeRoot.getValue(); + // Sum may be 0 + var unitRadian = Math.PI / (sum || validDataCount) * 2; + + var renderRollupNode = treeRoot.depth > 0; + var levels = treeRoot.height - (renderRollupNode ? -1 : 1); + var rPerLevel = (r - r0) / (levels || 1); + + var clockwise = seriesModel.get('clockwise'); + + var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); + + // In the case some sector angle is smaller than minAngle + var dir = clockwise ? 1 : -1; + + /** + * Render a tree + * @return increased angle + */ + var renderNode = function(node, startAngle) { + if (!node) { + return; + } + + var endAngle = startAngle; + + // Render self + if (node !== virtualRoot) { + // Tree node is virtual, so it doesn't need to be drawn + var value = node.getValue(); + + var angle = (sum === 0 && stillShowZeroSum) ? + unitRadian : (value * unitRadian); + if (angle < minAngle) { + angle = minAngle; + + } else { + + } + + endAngle = startAngle + dir * angle; + + var depth = node.depth - rootDepth - + (renderRollupNode ? -1 : 1); + var rStart = r0 + rPerLevel * depth; + var rEnd = r0 + rPerLevel * (depth + 1); + + var itemModel = node.getModel(); + if (itemModel.get('r0') != null) { + rStart = parsePercent$1(itemModel.get('r0'), size / 2); + } + if (itemModel.get('r') != null) { + rEnd = parsePercent$1(itemModel.get('r'), size / 2); + } + + node.setLayout({ + angle: angle, + startAngle: startAngle, + endAngle: endAngle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: rStart, + r: rEnd + }); + } + + // Render children + if (node.children && node.children.length) { + // currentAngle = startAngle; + var siblingAngle = 0; + each$1(node.children, function(node) { + siblingAngle += renderNode(node, startAngle + siblingAngle); + }); + } + + return endAngle - startAngle; + }; + + // Virtual root node for roll up + if (renderRollupNode) { + var rStart = r0; + var rEnd = r0 + rPerLevel; + + var angle = Math.PI * 2; + virtualRoot.setLayout({ + angle: angle, + startAngle: startAngle, + endAngle: startAngle + angle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: rStart, + r: rEnd + }); + } + + renderNode(treeRoot, startAngle); + }); + }; + + /** + * Init node children by order and update visual + * + * @param {TreeNode} node root node + * @param {boolean} isAsc if is in ascendant order + */ + function initChildren$1(node, isAsc) { + var children = node.children || []; + + node.children = sort$2(children, isAsc); + + // Init children recursively + if (children.length) { + each$1(node.children, function(child) { + initChildren$1(child, isAsc); + }); + } + } + + /** + * Sort children nodes + * + * @param {TreeNode[]} children children of node to be sorted + * @param {string | function | null} sort sort method + * See SunburstSeries.js for details. + */ + function sort$2(children, sortOrder) { + if (typeof sortOrder === 'function') { + return children.sort(sortOrder); + } else { + var isAsc = sortOrder === 'asc'; + return children.sort(function(a, b) { + var diff = (a.getValue() - b.getValue()) * (isAsc ? 1 : -1); + return diff === 0 ? + (a.dataIndex - b.dataIndex) * (isAsc ? -1 : 1) : + diff; + }); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerVisual(curry(dataColor, 'sunburst')); + registerLayout(curry(sunburstLayout, 'sunburst')); + registerProcessor(curry(dataFilter, 'sunburst')); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function dataToCoordSize(dataSize, dataItem) { + // dataItem is necessary in log axis. + dataItem = dataItem || [0, 0]; + return map(['x', 'y'], function(dim, dimIdx) { + var axis = this.getAxis(dim); + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + return axis.type === 'category' ? + axis.getBandWidth() : + Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize)); + }, this); + } + + var prepareCartesian2d = function(coordSys) { + var rect = coordSys.grid.getRect(); + return { + coordSys: { + // The name exposed to user is always 'cartesian2d' but not 'grid'. + type: 'cartesian2d', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + api: { + coord: function(data) { + // do not provide "out" param + return coordSys.dataToPoint(data); + }, + size: bind(dataToCoordSize, coordSys) + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function dataToCoordSize$1(dataSize, dataItem) { + dataItem = dataItem || [0, 0]; + return map([0, 1], function(dimIdx) { + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + var p1 = []; + var p2 = []; + p1[dimIdx] = val - halfSize; + p2[dimIdx] = val + halfSize; + p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx]; + return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]); + }, this); + } + + var prepareGeo = function(coordSys) { + var rect = coordSys.getBoundingRect(); + return { + coordSys: { + type: 'geo', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + api: { + coord: function(data) { + // do not provide "out" and noRoam param, + // Compatible with this usage: + // echarts.util.map(item.points, api.coord) + return coordSys.dataToPoint(data); + }, + size: bind(dataToCoordSize$1, coordSys) + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function dataToCoordSize$2(dataSize, dataItem) { + // dataItem is necessary in log axis. + var axis = this.getAxis(); + var val = dataItem instanceof Array ? dataItem[0] : dataItem; + var halfSize = (dataSize instanceof Array ? dataSize[0] : dataSize) / 2; + return axis.type === 'category' ? + axis.getBandWidth() : + Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize)); + } + + var prepareSingleAxis = function(coordSys) { + var rect = coordSys.getRect(); + + return { + coordSys: { + type: 'singleAxis', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + api: { + coord: function(val) { + // do not provide "out" param + return coordSys.dataToPoint(val); + }, + size: bind(dataToCoordSize$2, coordSys) + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function dataToCoordSize$3(dataSize, dataItem) { + // dataItem is necessary in log axis. + return map(['Radius', 'Angle'], function(dim, dimIdx) { + var axis = this['get' + dim + 'Axis'](); + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + var method = 'dataTo' + dim; + + var result = axis.type === 'category' ? + axis.getBandWidth() : + Math.abs(axis[method](val - halfSize) - axis[method](val + halfSize)); + + if (dim === 'Angle') { + result = result * Math.PI / 180; + } + + return result; + + }, this); + } + + var preparePolar = function(coordSys) { + var radiusAxis = coordSys.getRadiusAxis(); + var angleAxis = coordSys.getAngleAxis(); + var radius = radiusAxis.getExtent(); + radius[0] > radius[1] && radius.reverse(); + + return { + coordSys: { + type: 'polar', + cx: coordSys.cx, + cy: coordSys.cy, + r: radius[1], + r0: radius[0] + }, + api: { + coord: bind(function(data) { + var radius = radiusAxis.dataToRadius(data[0]); + var angle = angleAxis.dataToAngle(data[1]); + var coord = coordSys.coordToPoint([radius, angle]); + coord.push(radius, angle * Math.PI / 180); + return coord; + }), + size: bind(dataToCoordSize$3, coordSys) + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var prepareCalendar = function(coordSys) { + var rect = coordSys.getRect(); + var rangeInfo = coordSys.getRangeInfo(); + + return { + coordSys: { + type: 'calendar', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + cellWidth: coordSys.getCellWidth(), + cellHeight: coordSys.getCellHeight(), + rangeInfo: { + start: rangeInfo.start, + end: rangeInfo.end, + weeks: rangeInfo.weeks, + dayCount: rangeInfo.allDay + } + }, + api: { + coord: function(data, clamp) { + return coordSys.dataToPoint(data, clamp); + } + } + }; + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var ITEM_STYLE_NORMAL_PATH = ['itemStyle']; + var ITEM_STYLE_EMPHASIS_PATH = ['emphasis', 'itemStyle']; + var LABEL_NORMAL = ['label']; + var LABEL_EMPHASIS = ['emphasis', 'label']; + // Use prefix to avoid index to be the same as el.name, + // which will cause weird udpate animation. + var GROUP_DIFF_PREFIX = 'e\0\0'; + + /** + * To reduce total package size of each coordinate systems, the modules `prepareCustom` + * of each coordinate systems are not required by each coordinate systems directly, but + * required by the module `custom`. + * + * prepareInfoForCustomSeries {Function}: optional + * @return {Object} {coordSys: {...}, api: { + * coord: function (data, clamp) {}, // return point in global. + * size: function (dataSize, dataItem) {} // return size of each axis in coordSys. + * }} + */ + var prepareCustoms = { + cartesian2d: prepareCartesian2d, + geo: prepareGeo, + singleAxis: prepareSingleAxis, + polar: preparePolar, + calendar: prepareCalendar + }; + + // ------ + // Model + // ------ + + extendSeriesModel({ + + type: 'series.custom', + + dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'], + + defaultOption: { + coordinateSystem: 'cartesian2d', // Can be set as 'none' + zlevel: 0, + z: 2, + legendHoverLink: true + + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + + // Polar coordinate system + // polarIndex: 0, + + // Geo coordinate system + // geoIndex: 0, + + // label: {} + // itemStyle: {} + }, + + getInitialData: function(option, ecModel) { + return createListFromArray(this.getSource(), this); + } + }); + + // ----- + // View + // ----- + + extendChartView({ + + type: 'custom', + + /** + * @private + * @type {module:echarts/data/List} + */ + _data: null, + + /** + * @override + */ + render: function(customSeries, ecModel, api) { + var oldData = this._data; + var data = customSeries.getData(); + var group = this.group; + var renderItem = makeRenderItem(customSeries, data, ecModel, api); + + this.group.removeAll(); + + data.diff(oldData) + .add(function(newIdx) { + createOrUpdate$1( + null, newIdx, renderItem(newIdx), customSeries, group, data + ); + }) + .update(function(newIdx, oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + createOrUpdate$1( + el, newIdx, renderItem(newIdx), customSeries, group, data + ); + }) + .remove(function(oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && group.remove(el); + }) + .execute(); + + this._data = data; + }, + + incrementalPrepareRender: function(customSeries, ecModel, api) { + this.group.removeAll(); + this._data = null; + }, + + incrementalRender: function(params, customSeries, ecModel, api) { + var data = customSeries.getData(); + var renderItem = makeRenderItem(customSeries, data, ecModel, api); + + function setIncrementalAndHoverLayer(el) { + if (!el.isGroup) { + el.incremental = true; + el.useHoverLayer = true; + } + } + for (var idx = params.start; idx < params.end; idx++) { + var el = createOrUpdate$1(null, idx, renderItem(idx), customSeries, this.group, data); + el.traverse(setIncrementalAndHoverLayer); + } + }, + + /** + * @override + */ + dispose: noop + }); + + + function createEl(elOption) { + var graphicType = elOption.type; + var el; + + if (graphicType === 'path') { + var shape = elOption.shape; + el = makePath( + shape.pathData, + null, { + x: shape.x || 0, + y: shape.y || 0, + width: shape.width || 0, + height: shape.height || 0 + }, + 'center' + ); + el.__customPathData = elOption.pathData; + } else if (graphicType === 'image') { + el = new ZImage({}); + el.__customImagePath = elOption.style.image; + } else if (graphicType === 'text') { + el = new Text({}); + el.__customText = elOption.style.text; + } else { + var Clz = graphic[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)]; + + if (__DEV__) { + assert$1(Clz, 'graphic type "' + graphicType + '" can not be found.'); + } + + el = new Clz(); + } + + el.__customGraphicType = graphicType; + el.name = elOption.name; + + return el; + } + + function updateEl(el, dataIndex, elOption, animatableModel, data, isInit) { + var targetProps = {}; + var elOptionStyle = elOption.style || {}; + + elOption.shape && (targetProps.shape = clone(elOption.shape)); + elOption.position && (targetProps.position = elOption.position.slice()); + elOption.scale && (targetProps.scale = elOption.scale.slice()); + elOption.origin && (targetProps.origin = elOption.origin.slice()); + elOption.rotation && (targetProps.rotation = elOption.rotation); + + if (el.type === 'image' && elOption.style) { + var targetStyle = targetProps.style = {}; + each$1(['x', 'y', 'width', 'height'], function(prop) { + prepareStyleTransition(prop, targetStyle, elOptionStyle, el.style, isInit); + }); + } + + if (el.type === 'text' && elOption.style) { + var targetStyle = targetProps.style = {}; + each$1(['x', 'y'], function(prop) { + prepareStyleTransition(prop, targetStyle, elOptionStyle, el.style, isInit); + }); + // Compatible with previous: both support + // textFill and fill, textStroke and stroke in 'text' element. + !elOptionStyle.hasOwnProperty('textFill') && elOptionStyle.fill && ( + elOptionStyle.textFill = elOptionStyle.fill + ); + !elOptionStyle.hasOwnProperty('textStroke') && elOptionStyle.stroke && ( + elOptionStyle.textStroke = elOptionStyle.stroke + ); + } + + if (el.type !== 'group') { + el.useStyle(elOptionStyle); + + // Init animation. + if (isInit) { + el.style.opacity = 0; + var targetOpacity = elOptionStyle.opacity; + targetOpacity == null && (targetOpacity = 1); + initProps(el, { + style: { + opacity: targetOpacity + } + }, animatableModel, dataIndex); + } + } + + if (isInit) { + el.attr(targetProps); + } else { + updateProps(el, targetProps, animatableModel, dataIndex); + } + + // z2 must not be null/undefined, otherwise sort error may occur. + el.attr({ + z2: elOption.z2 || 0, + silent: elOption.silent + }); + + elOption.styleEmphasis !== false && setHoverStyle(el, elOption.styleEmphasis); + } + + function prepareStyleTransition(prop, targetStyle, elOptionStyle, oldElStyle, isInit) { + if (elOptionStyle[prop] != null && !isInit) { + targetStyle[prop] = elOptionStyle[prop]; + elOptionStyle[prop] = oldElStyle[prop]; + } + } + + function makeRenderItem(customSeries, data, ecModel, api) { + var renderItem = customSeries.get('renderItem'); + var coordSys = customSeries.coordinateSystem; + var prepareResult = {}; + + if (coordSys) { + if (__DEV__) { + assert$1(renderItem, 'series.render is required.'); + assert$1( + coordSys.prepareCustoms || prepareCustoms[coordSys.type], + 'This coordSys does not support custom series.' + ); + } + + prepareResult = coordSys.prepareCustoms ? + coordSys.prepareCustoms() : + prepareCustoms[coordSys.type](coordSys); + } + + var userAPI = defaults({ + getWidth: api.getWidth, + getHeight: api.getHeight, + getZr: api.getZr, + getDevicePixelRatio: api.getDevicePixelRatio, + value: value, + style: style, + styleEmphasis: styleEmphasis, + visual: visual, + barLayout: barLayout, + currentSeriesIndices: currentSeriesIndices, + font: font + }, prepareResult.api || {}); + + var userParams = { + context: {}, + seriesId: customSeries.id, + seriesName: customSeries.name, + seriesIndex: customSeries.seriesIndex, + coordSys: prepareResult.coordSys, + dataInsideLength: data.count(), + encode: wrapEncodeDef(customSeries.getData()) + }; + + // Do not support call `api` asynchronously without dataIndexInside input. + var currDataIndexInside; + var currDirty = true; + var currItemModel; + var currLabelNormalModel; + var currLabelEmphasisModel; + var currVisualColor; + + return function(dataIndexInside) { + currDataIndexInside = dataIndexInside; + currDirty = true; + return renderItem && renderItem( + defaults({ + dataIndexInside: dataIndexInside, + dataIndex: data.getRawIndex(dataIndexInside) + }, userParams), + userAPI + ) || {}; + }; + + // Do not update cache until api called. + function updateCache(dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + if (currDirty) { + currItemModel = data.getItemModel(dataIndexInside); + currLabelNormalModel = currItemModel.getModel(LABEL_NORMAL); + currLabelEmphasisModel = currItemModel.getModel(LABEL_EMPHASIS); + currVisualColor = data.getItemVisual(dataIndexInside, 'color'); + + currDirty = false; + } + } + + /** + * @public + * @param {number|string} dim + * @param {number} [dataIndexInside=currDataIndexInside] + * @return {number|string} value + */ + function value(dim, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + return data.get(data.getDimension(dim || 0), dataIndexInside); + } + + /** + * By default, `visual` is applied to style (to support visualMap). + * `visual.color` is applied at `fill`. If user want apply visual.color on `stroke`, + * it can be implemented as: + * `api.style({stroke: api.visual('color'), fill: null})`; + * @public + * @param {Object} [extra] + * @param {number} [dataIndexInside=currDataIndexInside] + */ + function style(extra, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + updateCache(dataIndexInside); + + var itemStyle = currItemModel.getModel(ITEM_STYLE_NORMAL_PATH).getItemStyle(); + + currVisualColor != null && (itemStyle.fill = currVisualColor); + var opacity = data.getItemVisual(dataIndexInside, 'opacity'); + opacity != null && (itemStyle.opacity = opacity); + + setTextStyle(itemStyle, currLabelNormalModel, null, { + autoColor: currVisualColor, + isRectText: true + }); + + itemStyle.text = currLabelNormalModel.getShallow('show') ? + retrieve2( + customSeries.getFormattedLabel(dataIndexInside, 'normal'), + getDefaultLabel(data, dataIndexInside) + ) : + null; + + extra && extend(itemStyle, extra); + return itemStyle; + } + + /** + * @public + * @param {Object} [extra] + * @param {number} [dataIndexInside=currDataIndexInside] + */ + function styleEmphasis(extra, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + updateCache(dataIndexInside); + + var itemStyle = currItemModel.getModel(ITEM_STYLE_EMPHASIS_PATH).getItemStyle(); + + setTextStyle(itemStyle, currLabelEmphasisModel, null, { + isRectText: true + }, true); + + itemStyle.text = currLabelEmphasisModel.getShallow('show') ? + retrieve3( + customSeries.getFormattedLabel(dataIndexInside, 'emphasis'), + customSeries.getFormattedLabel(dataIndexInside, 'normal'), + getDefaultLabel(data, dataIndexInside) + ) : + null; + + extra && extend(itemStyle, extra); + return itemStyle; + } + + /** + * @public + * @param {string} visualType + * @param {number} [dataIndexInside=currDataIndexInside] + */ + function visual(visualType, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + return data.getItemVisual(dataIndexInside, visualType); + } + + /** + * @public + * @param {number} opt.count Positive interger. + * @param {number} [opt.barWidth] + * @param {number} [opt.barMaxWidth] + * @param {number} [opt.barGap] + * @param {number} [opt.barCategoryGap] + * @return {Object} {width, offset, offsetCenter} is not support, return undefined. + */ + function barLayout(opt) { + if (coordSys.getBaseAxis) { + var baseAxis = coordSys.getBaseAxis(); + return getLayoutOnAxis(defaults({ + axis: baseAxis + }, opt), api); + } + } + + /** + * @public + * @return {Array.} + */ + function currentSeriesIndices() { + return ecModel.getCurrentSeriesIndices(); + } + + /** + * @public + * @param {Object} opt + * @param {string} [opt.fontStyle] + * @param {number} [opt.fontWeight] + * @param {number} [opt.fontSize] + * @param {string} [opt.fontFamily] + * @return {string} font string + */ + function font(opt) { + return getFont(opt, ecModel); + } + } + + function wrapEncodeDef(data) { + var encodeDef = {}; + each$1(data.dimensions, function(dimName, dataDimIndex) { + var dimInfo = data.getDimensionInfo(dimName); + if (!dimInfo.isExtraCoord) { + var coordDim = dimInfo.coordDim; + var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || []; + dataDims[dimInfo.coordDimIndex] = dataDimIndex; + } + }); + return encodeDef; + } + + function createOrUpdate$1(el, dataIndex, elOption, animatableModel, group, data) { + el = doCreateOrUpdate(el, dataIndex, elOption, animatableModel, group, data); + el && data.setItemGraphicEl(dataIndex, el); + + return el; + } + + function doCreateOrUpdate(el, dataIndex, elOption, animatableModel, group, data) { + var elOptionType = elOption.type; + if (el && + elOptionType !== el.__customGraphicType && + (elOptionType !== 'path' || elOption.pathData !== el.__customPathData) && + (elOptionType !== 'image' || elOption.style.image !== el.__customImagePath) && + (elOptionType !== 'text' || elOption.style.text !== el.__customText) + ) { + group.remove(el); + el = null; + } + + // `elOption.type` is undefined when `renderItem` returns nothing. + if (elOptionType == null) { + return; + } + + var isInit = !el; + !el && (el = createEl(elOption)); + updateEl(el, dataIndex, elOption, animatableModel, data, isInit); + + if (elOptionType === 'group') { + var oldChildren = el.children() || []; + var newChildren = elOption.children || []; + + if (elOption.diffChildrenByName) { + // lower performance. + diffGroupChildren({ + oldChildren: oldChildren, + newChildren: newChildren, + dataIndex: dataIndex, + animatableModel: animatableModel, + group: el, + data: data + }); + } else { + // better performance. + var index = 0; + for (; index < newChildren.length; index++) { + doCreateOrUpdate( + el.childAt(index), + dataIndex, + newChildren[index], + animatableModel, + el, + data + ); + } + for (; index < oldChildren.length; index++) { + oldChildren[index] && el.remove(oldChildren[index]); + } + } + } + + group.add(el); + + return el; + } + + function diffGroupChildren(context) { + (new DataDiffer( + context.oldChildren, + context.newChildren, + getKey, + getKey, + context + )) + .add(processAddUpdate) + .update(processAddUpdate) + .remove(processRemove) + .execute(); + } + + function getKey(item, idx) { + var name = item && item.name; + return name != null ? name : GROUP_DIFF_PREFIX + idx; + } + + function processAddUpdate(newIndex, oldIndex) { + var context = this.context; + var childOption = newIndex != null ? context.newChildren[newIndex] : null; + var child = oldIndex != null ? context.oldChildren[oldIndex] : null; + + doCreateOrUpdate( + child, + context.dataIndex, + childOption, + context.animatableModel, + context.group, + context.data + ); + } + + function processRemove(oldIndex) { + var context = this.context; + var child = context.oldChildren[oldIndex]; + child && context.group.remove(child); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // ------------- + // Preprocessor + // ------------- + + registerPreprocessor(function(option) { + var graphicOption = option.graphic; + + // Convert + // {graphic: [{left: 10, type: 'circle'}, ...]} + // or + // {graphic: {left: 10, type: 'circle'}} + // to + // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]} + if (isArray(graphicOption)) { + if (!graphicOption[0] || !graphicOption[0].elements) { + option.graphic = [{ + elements: graphicOption + }]; + } else { + // Only one graphic instance can be instantiated. (We dont + // want that too many views are created in echarts._viewMap) + option.graphic = [option.graphic[0]]; + } + } else if (graphicOption && !graphicOption.elements) { + option.graphic = [{ + elements: [graphicOption] + }]; + } + }); + + // ------ + // Model + // ------ + + var GraphicModel = extendComponentModel({ + + type: 'graphic', + + defaultOption: { + + // Extra properties for each elements: + // + // left/right/top/bottom: (like 12, '22%', 'center', default undefined) + // If left/rigth is set, shape.x/shape.cx/position will not be used. + // If top/bottom is set, shape.y/shape.cy/position will not be used. + // This mechanism is useful when you want to position a group/element + // against the right side or the center of this container. + // + // width/height: (can only be pixel value, default 0) + // Only be used to specify contianer(group) size, if needed. And + // can not be percentage value (like '33%'). See the reason in the + // layout algorithm below. + // + // bounding: (enum: 'all' (default) | 'raw') + // Specify how to calculate boundingRect when locating. + // 'all': Get uioned and transformed boundingRect + // from both itself and its descendants. + // This mode simplies confining a group of elements in the bounding + // of their ancester container (e.g., using 'right: 0'). + // 'raw': Only use the boundingRect of itself and before transformed. + // This mode is similar to css behavior, which is useful when you + // want an element to be able to overflow its container. (Consider + // a rotated circle needs to be located in a corner.) + + // Note: elements is always behind its ancestors in this elements array. + elements: [], + parentId: null + }, + + /** + * Save el options for the sake of the performance (only update modified graphics). + * The order is the same as those in option. (ancesters -> descendants) + * + * @private + * @type {Array.} + */ + _elOptionsToUpdate: null, + + /** + * @override + */ + mergeOption: function(option) { + // Prevent default merge to elements + var elements = this.option.elements; + this.option.elements = null; + + GraphicModel.superApply(this, 'mergeOption', arguments); + + this.option.elements = elements; + }, + + /** + * @override + */ + optionUpdated: function(newOption, isInit) { + var thisOption = this.option; + var newList = (isInit ? thisOption : newOption).elements; + var existList = thisOption.elements = isInit ? [] : thisOption.elements; + + var flattenedList = []; + this._flatten(newList, flattenedList); + + var mappingResult = mappingToExists(existList, flattenedList); + makeIdAndName(mappingResult); + + // Clear elOptionsToUpdate + var elOptionsToUpdate = this._elOptionsToUpdate = []; + + each$1(mappingResult, function(resultItem, index) { + var newElOption = resultItem.option; + + if (__DEV__) { + assert$1( + isObject$1(newElOption) || resultItem.exist, + 'Empty graphic option definition' + ); + } + + if (!newElOption) { + return; + } + + elOptionsToUpdate.push(newElOption); + + setKeyInfoToNewElOption(resultItem, newElOption); + + mergeNewElOptionToExist(existList, index, newElOption); + + setLayoutInfoToExist(existList[index], newElOption); + + }, this); + + // Clean + for (var i = existList.length - 1; i >= 0; i--) { + if (existList[i] == null) { + existList.splice(i, 1); + } else { + // $action should be volatile, otherwise option gotten from + // `getOption` will contain unexpected $action. + delete existList[i].$action; + } + } + }, + + /** + * Convert + * [{ + * type: 'group', + * id: 'xx', + * children: [{type: 'circle'}, {type: 'polygon'}] + * }] + * to + * [ + * {type: 'group', id: 'xx'}, + * {type: 'circle', parentId: 'xx'}, + * {type: 'polygon', parentId: 'xx'} + * ] + * + * @private + * @param {Array.} optionList option list + * @param {Array.} result result of flatten + * @param {Object} parentOption parent option + */ + _flatten: function(optionList, result, parentOption) { + each$1(optionList, function(option) { + if (!option) { + return; + } + + if (parentOption) { + option.parentOption = parentOption; + } + + result.push(option); + + var children = option.children; + if (option.type === 'group' && children) { + this._flatten(children, result, option); + } + // Deleting for JSON output, and for not affecting group creation. + delete option.children; + }, this); + }, + + // FIXME + // Pass to view using payload? setOption has a payload? + useElOptionsToUpdate: function() { + var els = this._elOptionsToUpdate; + // Clear to avoid render duplicately when zooming. + this._elOptionsToUpdate = null; + return els; + } + }); + + // ----- + // View + // ----- + + extendComponentView({ + + type: 'graphic', + + /** + * @override + */ + init: function(ecModel, api) { + + /** + * @private + * @type {module:zrender/core/util.HashMap} + */ + this._elMap = createHashMap(); + + /** + * @private + * @type {module:echarts/graphic/GraphicModel} + */ + this._lastGraphicModel; + }, + + /** + * @override + */ + render: function(graphicModel, ecModel, api) { + + // Having leveraged between use cases and algorithm complexity, a very + // simple layout mechanism is used: + // The size(width/height) can be determined by itself or its parent (not + // implemented yet), but can not by its children. (Top-down travel) + // The location(x/y) can be determined by the bounding rect of itself + // (can including its descendants or not) and the size of its parent. + // (Bottom-up travel) + + // When `chart.clear()` or `chart.setOption({...}, true)` with the same id, + // view will be reused. + if (graphicModel !== this._lastGraphicModel) { + this._clear(); + } + this._lastGraphicModel = graphicModel; + + this._updateElements(graphicModel, api); + this._relocate(graphicModel, api); + }, + + /** + * Update graphic elements. + * + * @private + * @param {Object} graphicModel graphic model + * @param {module:echarts/ExtensionAPI} api extension API + */ + _updateElements: function(graphicModel, api) { + var elOptionsToUpdate = graphicModel.useElOptionsToUpdate(); + + if (!elOptionsToUpdate) { + return; + } + + var elMap = this._elMap; + var rootGroup = this.group; + + // Top-down tranverse to assign graphic settings to each elements. + each$1(elOptionsToUpdate, function(elOption) { + var $action = elOption.$action; + var id = elOption.id; + var existEl = elMap.get(id); + var parentId = elOption.parentId; + var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup; + + if (elOption.type === 'text') { + var elOptionStyle = elOption.style; + + // In top/bottom mode, textVerticalAlign should not be used, which cause + // inaccurately locating. + if (elOption.hv && elOption.hv[1]) { + elOptionStyle.textVerticalAlign = elOptionStyle.textBaseline = null; + } + + // Compatible with previous setting: both support fill and textFill, + // stroke and textStroke. + !elOptionStyle.hasOwnProperty('textFill') && elOptionStyle.fill && ( + elOptionStyle.textFill = elOptionStyle.fill + ); + !elOptionStyle.hasOwnProperty('textStroke') && elOptionStyle.stroke && ( + elOptionStyle.textStroke = elOptionStyle.stroke + ); + } + + // Remove unnecessary props to avoid potential problems. + var elOptionCleaned = getCleanedElOption(elOption); + + // For simple, do not support parent change, otherwise reorder is needed. + if (__DEV__) { + existEl && assert$1( + targetElParent === existEl.parent, + 'Changing parent is not supported.' + ); + } + + if (!$action || $action === 'merge') { + existEl + ? + existEl.attr(elOptionCleaned) : + createEl$1(id, targetElParent, elOptionCleaned, elMap); + } else if ($action === 'replace') { + removeEl(existEl, elMap); + createEl$1(id, targetElParent, elOptionCleaned, elMap); + } else if ($action === 'remove') { + removeEl(existEl, elMap); + } + + var el = elMap.get(id); + if (el) { + el.__ecGraphicWidth = elOption.width; + el.__ecGraphicHeight = elOption.height; + } + }); + }, + + /** + * Locate graphic elements. + * + * @private + * @param {Object} graphicModel graphic model + * @param {module:echarts/ExtensionAPI} api extension API + */ + _relocate: function(graphicModel, api) { + var elOptions = graphicModel.option.elements; + var rootGroup = this.group; + var elMap = this._elMap; + + // Bottom-up tranvese all elements (consider ec resize) to locate elements. + for (var i = elOptions.length - 1; i >= 0; i--) { + var elOption = elOptions[i]; + var el = elMap.get(elOption.id); + + if (!el) { + continue; + } + + var parentEl = el.parent; + var containerInfo = parentEl === rootGroup ? + { + width: api.getWidth(), + height: api.getHeight() + } : + { // Like 'position:absolut' in css, default 0. + width: parentEl.__ecGraphicWidth || 0, + height: parentEl.__ecGraphicHeight || 0 + }; + + positionElement( + el, elOption, containerInfo, null, { + hv: elOption.hv, + boundingMode: elOption.bounding + } + ); + } + }, + + /** + * Clear all elements. + * + * @private + */ + _clear: function() { + var elMap = this._elMap; + elMap.each(function(el) { + removeEl(el, elMap); + }); + this._elMap = createHashMap(); + }, + + /** + * @override + */ + dispose: function() { + this._clear(); + } + }); + + function createEl$1(id, targetElParent, elOption, elMap) { + var graphicType = elOption.type; + + if (__DEV__) { + assert$1(graphicType, 'graphic type MUST be set'); + } + + var Clz = graphic[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)]; + + if (__DEV__) { + assert$1(Clz, 'graphic type can not be found'); + } + + var el = new Clz(elOption); + targetElParent.add(el); + elMap.set(id, el); + el.__ecGraphicId = id; + } + + function removeEl(existEl, elMap) { + var existElParent = existEl && existEl.parent; + if (existElParent) { + existEl.type === 'group' && existEl.traverse(function(el) { + removeEl(el, elMap); + }); + elMap.removeKey(existEl.__ecGraphicId); + existElParent.remove(existEl); + } + } + + // Remove unnecessary props to avoid potential problems. + function getCleanedElOption(elOption) { + elOption = extend({}, elOption); + each$1( + ['id', 'parentId', '$action', 'hv', 'bounding'].concat(LOCATION_PARAMS), + function(name) { + delete elOption[name]; + } + ); + return elOption; + } + + function isSetLoc(obj, props) { + var isSet; + each$1(props, function(prop) { + obj[prop] != null && obj[prop] !== 'auto' && (isSet = true); + }); + return isSet; + } + + function setKeyInfoToNewElOption(resultItem, newElOption) { + var existElOption = resultItem.exist; + + // Set id and type after id assigned. + newElOption.id = resultItem.keyInfo.id; + !newElOption.type && existElOption && (newElOption.type = existElOption.type); + + // Set parent id if not specified + if (newElOption.parentId == null) { + var newElParentOption = newElOption.parentOption; + if (newElParentOption) { + newElOption.parentId = newElParentOption.id; + } else if (existElOption) { + newElOption.parentId = existElOption.parentId; + } + } + + // Clear + newElOption.parentOption = null; + } + + function mergeNewElOptionToExist(existList, index, newElOption) { + // Update existing options, for `getOption` feature. + var newElOptCopy = extend({}, newElOption); + var existElOption = existList[index]; + + var $action = newElOption.$action || 'merge'; + if ($action === 'merge') { + if (existElOption) { + + if (__DEV__) { + var newType = newElOption.type; + assert$1( + !newType || existElOption.type === newType, + 'Please set $action: "replace" to change `type`' + ); + } + + // We can ensure that newElOptCopy and existElOption are not + // the same object, so `merge` will not change newElOptCopy. + merge(existElOption, newElOptCopy, true); + // Rigid body, use ignoreSize. + mergeLayoutParam(existElOption, newElOptCopy, { + ignoreSize: true + }); + // Will be used in render. + copyLayoutParams(newElOption, existElOption); + } else { + existList[index] = newElOptCopy; + } + } else if ($action === 'replace') { + existList[index] = newElOptCopy; + } else if ($action === 'remove') { + // null will be cleaned later. + existElOption && (existList[index] = null); + } + } + + function setLayoutInfoToExist(existItem, newElOption) { + if (!existItem) { + return; + } + existItem.hv = newElOption.hv = [ + // Rigid body, dont care `width`. + isSetLoc(newElOption, ['left', 'right']), + // Rigid body, dont care `height`. + isSetLoc(newElOption, ['top', 'bottom']) + ]; + // Give default group size. Otherwise layout error may occur. + if (existItem.type === 'group') { + existItem.width == null && (existItem.width = newElOption.width = 0); + existItem.height == null && (existItem.height = newElOption.height = 0); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var LegendModel = extendComponentModel({ + + type: 'legend.plain', + + dependencies: ['series'], + + layoutMode: { + type: 'box', + // legend.width/height are maxWidth/maxHeight actually, + // whereas realy width/height is calculated by its content. + // (Setting {left: 10, right: 10} does not make sense). + // So consider the case: + // `setOption({legend: {left: 10});` + // then `setOption({legend: {right: 10});` + // The previous `left` should be cleared by setting `ignoreSize`. + ignoreSize: true + }, + + init: function(option, parentModel, ecModel) { + this.mergeDefaultAndTheme(option, ecModel); + + option.selected = option.selected || {}; + }, + + mergeOption: function(option) { + LegendModel.superCall(this, 'mergeOption', option); + }, + + optionUpdated: function() { + this._updateData(this.ecModel); + + var legendData = this._data; + + // If selectedMode is single, try to select one + if (legendData[0] && this.get('selectedMode') === 'single') { + var hasSelected = false; + // If has any selected in option.selected + for (var i = 0; i < legendData.length; i++) { + var name = legendData[i].get('name'); + if (this.isSelected(name)) { + // Force to unselect others + this.select(name); + hasSelected = true; + break; + } + } + // Try select the first if selectedMode is single + !hasSelected && this.select(legendData[0].get('name')); + } + }, + + _updateData: function(ecModel) { + var potentialData = []; + var availableNames = []; + + ecModel.eachRawSeries(function(seriesModel) { + var seriesName = seriesModel.name; + availableNames.push(seriesName); + var isPotential; + + if (seriesModel.legendDataProvider) { + var data = seriesModel.legendDataProvider(); + var names = data.mapArray(data.getName); + + if (!ecModel.isSeriesFiltered(seriesModel)) { + availableNames = availableNames.concat(names); + } + + if (names.length) { + potentialData = potentialData.concat(names); + } else { + isPotential = true; + } + } else { + isPotential = true; + } + + if (isPotential && isNameSpecified(seriesModel)) { + potentialData.push(seriesModel.name); + } + }); + + /** + * @type {Array.} + * @private + */ + this._availableNames = availableNames; + + // If legend.data not specified in option, use availableNames as data, + // which is convinient for user preparing option. + var rawData = this.get('data') || potentialData; + + var legendData = map(rawData, function(dataItem) { + // Can be string or number + if (typeof dataItem === 'string' || typeof dataItem === 'number') { + dataItem = { + name: dataItem + }; + } + return new Model(dataItem, this, this.ecModel); + }, this); + + /** + * @type {Array.} + * @private + */ + this._data = legendData; + }, + + /** + * @return {Array.} + */ + getData: function() { + return this._data; + }, + + /** + * @param {string} name + */ + select: function(name) { + var selected = this.option.selected; + var selectedMode = this.get('selectedMode'); + if (selectedMode === 'single') { + var data = this._data; + each$1(data, function(dataItem) { + selected[dataItem.get('name')] = false; + }); + } + selected[name] = true; + }, + + /** + * @param {string} name + */ + unSelect: function(name) { + if (this.get('selectedMode') !== 'single') { + this.option.selected[name] = false; + } + }, + + /** + * @param {string} name + */ + toggleSelected: function(name) { + var selected = this.option.selected; + // Default is true + if (!selected.hasOwnProperty(name)) { + selected[name] = true; + } + this[selected[name] ? 'unSelect' : 'select'](name); + }, + + /** + * @param {string} name + */ + isSelected: function(name) { + var selected = this.option.selected; + return !(selected.hasOwnProperty(name) && !selected[name]) && + indexOf(this._availableNames, name) >= 0; + }, + + defaultOption: { + // 一级层叠 + zlevel: 0, + // 二级层叠 + z: 4, + show: true, + + // 布局方式,默认为水平布局,可选为: + // 'horizontal' | 'vertical' + orient: 'horizontal', + + left: 'center', + // right: 'center', + + top: 0, + // bottom: null, + + // 水平对齐 + // 'auto' | 'left' | 'right' + // 默认为 'auto', 根据 x 的位置判断是左对齐还是右对齐 + align: 'auto', + + backgroundColor: 'rgba(0,0,0,0)', + // 图例边框颜色 + borderColor: '#ccc', + borderRadius: 0, + // 图例边框线宽,单位px,默认为0(无边框) + borderWidth: 0, + // 图例内边距,单位px,默认各方向内边距为5, + // 接受数组分别设定上右下左边距,同css + padding: 5, + // 各个item之间的间隔,单位px,默认为10, + // 横向布局时为水平间隔,纵向布局时为纵向间隔 + itemGap: 10, + // 图例图形宽度 + itemWidth: 25, + // 图例图形高度 + itemHeight: 14, + + // 图例关闭时候的颜色 + inactiveColor: '#ccc', + + textStyle: { + // 图例文字颜色 + color: '#333' + }, + // formatter: '', + // 选择模式,默认开启图例开关 + selectedMode: true, + // 配置默认选中状态,可配合LEGEND.SELECTED事件做动态数据载入 + // selected: null, + // 图例内容(详见legend.data,数组中每一项代表一个item + // data: [], + + // Tooltip 相关配置 + tooltip: { + show: false + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function legendSelectActionHandler(methodName, payload, ecModel) { + var selectedMap = {}; + var isToggleSelect = methodName === 'toggleSelected'; + var isSelected; + // Update all legend components + ecModel.eachComponent('legend', function(legendModel) { + if (isToggleSelect && isSelected != null) { + // Force other legend has same selected status + // Or the first is toggled to true and other are toggled to false + // In the case one legend has some item unSelected in option. And if other legend + // doesn't has the item, they will assume it is selected. + legendModel[isSelected ? 'select' : 'unSelect'](payload.name); + } else { + legendModel[methodName](payload.name); + isSelected = legendModel.isSelected(payload.name); + } + var legendData = legendModel.getData(); + each$1(legendData, function(model) { + var name = model.get('name'); + // Wrap element + if (name === '\n' || name === '') { + return; + } + var isItemSelected = legendModel.isSelected(name); + if (selectedMap.hasOwnProperty(name)) { + // Unselected if any legend is unselected + selectedMap[name] = selectedMap[name] && isItemSelected; + } else { + selectedMap[name] = isItemSelected; + } + }); + }); + // Return the event explicitly + return { + name: payload.name, + selected: selectedMap + }; + } + /** + * @event legendToggleSelect + * @type {Object} + * @property {string} type 'legendToggleSelect' + * @property {string} [from] + * @property {string} name Series name or data item name + */ + registerAction( + 'legendToggleSelect', 'legendselectchanged', + curry(legendSelectActionHandler, 'toggleSelected') + ); + + /** + * @event legendSelect + * @type {Object} + * @property {string} type 'legendSelect' + * @property {string} name Series name or data item name + */ + registerAction( + 'legendSelect', 'legendselected', + curry(legendSelectActionHandler, 'select') + ); + + /** + * @event legendUnSelect + * @type {Object} + * @property {string} type 'legendUnSelect' + * @property {string} name Series name or data item name + */ + registerAction( + 'legendUnSelect', 'legendunselected', + curry(legendSelectActionHandler, 'unSelect') + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Layout list like component. + * It will box layout each items in group of component and then position the whole group in the viewport + * @param {module:zrender/group/Group} group + * @param {module:echarts/model/Component} componentModel + * @param {module:echarts/ExtensionAPI} + */ + function layout$3(group, componentModel, api) { + var boxLayoutParams = componentModel.getBoxLayoutParams(); + var padding = componentModel.get('padding'); + var viewportSize = { + width: api.getWidth(), + height: api.getHeight() + }; + + var rect = getLayoutRect( + boxLayoutParams, + viewportSize, + padding + ); + + box( + componentModel.get('orient'), + group, + componentModel.get('itemGap'), + rect.width, + rect.height + ); + + positionElement( + group, + boxLayoutParams, + viewportSize, + padding + ); + } + + function makeBackground(rect, componentModel) { + var padding = normalizeCssArray$1( + componentModel.get('padding') + ); + var style = componentModel.getItemStyle(['color', 'opacity']); + style.fill = componentModel.get('backgroundColor'); + var rect = new Rect({ + shape: { + x: rect.x - padding[3], + y: rect.y - padding[0], + width: rect.width + padding[1] + padding[3], + height: rect.height + padding[0] + padding[2], + r: componentModel.get('borderRadius') + }, + style: style, + silent: true, + z2: -1 + }); + // FIXME + // `subPixelOptimizeRect` may bring some gap between edge of viewpart + // and background rect when setting like `left: 0`, `top: 0`. + // graphic.subPixelOptimizeRect(rect); + + return rect; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var curry$4 = curry; + var each$16 = each$1; + var Group$3 = Group; + + var LegendView = extendComponentView({ + + type: 'legend.plain', + + newlineDisabled: false, + + /** + * @override + */ + init: function() { + + /** + * @private + * @type {module:zrender/container/Group} + */ + this.group.add(this._contentGroup = new Group$3()); + + /** + * @private + * @type {module:zrender/Element} + */ + this._backgroundEl; + }, + + /** + * @protected + */ + getContentGroup: function() { + return this._contentGroup; + }, + + /** + * @override + */ + render: function(legendModel, ecModel, api) { + + this.resetInner(); + + if (!legendModel.get('show', true)) { + return; + } + + var itemAlign = legendModel.get('align'); + if (!itemAlign || itemAlign === 'auto') { + itemAlign = ( + legendModel.get('left') === 'right' && + legendModel.get('orient') === 'vertical' + ) ? 'right' : 'left'; + } + + this.renderInner(itemAlign, legendModel, ecModel, api); + + // Perform layout. + var positionInfo = legendModel.getBoxLayoutParams(); + var viewportSize = { + width: api.getWidth(), + height: api.getHeight() + }; + var padding = legendModel.get('padding'); + + var maxSize = getLayoutRect(positionInfo, viewportSize, padding); + var mainRect = this.layoutInner(legendModel, itemAlign, maxSize); + + // Place mainGroup, based on the calculated `mainRect`. + var layoutRect = getLayoutRect( + defaults({ + width: mainRect.width, + height: mainRect.height + }, positionInfo), + viewportSize, + padding + ); + this.group.attr('position', [layoutRect.x - mainRect.x, layoutRect.y - mainRect.y]); + + // Render background after group is layout. + this.group.add( + this._backgroundEl = makeBackground(mainRect, legendModel) + ); + }, + + /** + * @protected + */ + resetInner: function() { + this.getContentGroup().removeAll(); + this._backgroundEl && this.group.remove(this._backgroundEl); + }, + + /** + * @protected + */ + renderInner: function(itemAlign, legendModel, ecModel, api) { + var contentGroup = this.getContentGroup(); + var legendDrawnMap = createHashMap(); + var selectMode = legendModel.get('selectedMode'); + + var excludeSeriesId = []; + ecModel.eachRawSeries(function(seriesModel) { + !seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id); + }); + + each$16(legendModel.getData(), function(itemModel, dataIndex) { + var name = itemModel.get('name'); + + // Use empty string or \n as a newline string + if (!this.newlineDisabled && (name === '' || name === '\n')) { + contentGroup.add(new Group$3({ + newline: true + })); + return; + } + + // Representitive series. + var seriesModel = ecModel.getSeriesByName(name)[0]; + + if (legendDrawnMap.get(name)) { + // Have been drawed + return; + } + + // Series legend + if (seriesModel) { + var data = seriesModel.getData(); + var color = data.getVisual('color'); + + // If color is a callback function + if (typeof color === 'function') { + // Use the first data + color = color(seriesModel.getDataParams(0)); + } + + // Using rect symbol defaultly + var legendSymbolType = data.getVisual('legendSymbol') || 'roundRect'; + var symbolType = data.getVisual('symbol'); + + var itemGroup = this._createItem( + name, dataIndex, itemModel, legendModel, + legendSymbolType, symbolType, + itemAlign, color, + selectMode + ); + + itemGroup.on('click', curry$4(dispatchSelectAction, name, api)) + .on('mouseover', curry$4(dispatchHighlightAction, seriesModel, null, api, excludeSeriesId)) + .on('mouseout', curry$4(dispatchDownplayAction, seriesModel, null, api, excludeSeriesId)); + + legendDrawnMap.set(name, true); + } else { + // Data legend of pie, funnel + ecModel.eachRawSeries(function(seriesModel) { + // In case multiple series has same data name + if (legendDrawnMap.get(name)) { + return; + } + + if (seriesModel.legendDataProvider) { + var data = seriesModel.legendDataProvider(); + var idx = data.indexOfName(name); + if (idx < 0) { + return; + } + + var color = data.getItemVisual(idx, 'color'); + + var legendSymbolType = 'roundRect'; + + var itemGroup = this._createItem( + name, dataIndex, itemModel, legendModel, + legendSymbolType, null, + itemAlign, color, + selectMode + ); + + // FIXME: consider different series has items with the same name. + itemGroup.on('click', curry$4(dispatchSelectAction, name, api)) + // FIXME Should not specify the series name + .on('mouseover', curry$4(dispatchHighlightAction, seriesModel, name, api, excludeSeriesId)) + .on('mouseout', curry$4(dispatchDownplayAction, seriesModel, name, api, excludeSeriesId)); + + legendDrawnMap.set(name, true); + } + + }, this); + } + + if (__DEV__) { + if (!legendDrawnMap.get(name)) { + console.warn(name + ' series not exists. Legend data should be same with series name or data name.'); + } + } + }, this); + }, + + _createItem: function( + name, dataIndex, itemModel, legendModel, + legendSymbolType, symbolType, + itemAlign, color, selectMode + ) { + var itemWidth = legendModel.get('itemWidth'); + var itemHeight = legendModel.get('itemHeight'); + var inactiveColor = legendModel.get('inactiveColor'); + var symbolKeepAspect = legendModel.get('symbolKeepAspect'); + + var isSelected = legendModel.isSelected(name); + var itemGroup = new Group$3(); + + var textStyleModel = itemModel.getModel('textStyle'); + + var itemIcon = itemModel.get('icon'); + + var tooltipModel = itemModel.getModel('tooltip'); + var legendGlobalTooltipModel = tooltipModel.parentModel; + + // Use user given icon first + legendSymbolType = itemIcon || legendSymbolType; + itemGroup.add(createSymbol( + legendSymbolType, + 0, + 0, + itemWidth, + itemHeight, + isSelected ? color : inactiveColor, + // symbolKeepAspect default true for legend + symbolKeepAspect == null ? true : symbolKeepAspect + )); + + // Compose symbols + // PENDING + if (!itemIcon && symbolType + // At least show one symbol, can't be all none + && + ((symbolType !== legendSymbolType) || symbolType == 'none') + ) { + var size = itemHeight * 0.8; + if (symbolType === 'none') { + symbolType = 'circle'; + } + // Put symbol in the center + itemGroup.add(createSymbol( + symbolType, + (itemWidth - size) / 2, + (itemHeight - size) / 2, + size, + size, + isSelected ? color : inactiveColor, + // symbolKeepAspect default true for legend + symbolKeepAspect == null ? true : symbolKeepAspect + )); + } + + var textX = itemAlign === 'left' ? itemWidth + 5 : -5; + var textAlign = itemAlign; + + var formatter = legendModel.get('formatter'); + var content = name; + if (typeof formatter === 'string' && formatter) { + content = formatter.replace('{name}', name != null ? name : ''); + } else if (typeof formatter === 'function') { + content = formatter(name); + } + + itemGroup.add(new Text({ + style: setTextStyle({}, textStyleModel, { + text: content, + x: textX, + y: itemHeight / 2, + textFill: isSelected ? textStyleModel.getTextColor() : inactiveColor, + textAlign: textAlign, + textVerticalAlign: 'middle' + }) + })); + + // Add a invisible rect to increase the area of mouse hover + var hitRect = new Rect({ + shape: itemGroup.getBoundingRect(), + invisible: true, + tooltip: tooltipModel.get('show') ? extend({ + content: name, + // Defaul formatter + formatter: legendGlobalTooltipModel.get('formatter', true) || function() { + return name; + }, + formatterParams: { + componentType: 'legend', + legendIndex: legendModel.componentIndex, + name: name, + $vars: ['name'] + } + }, tooltipModel.option) : null + }); + itemGroup.add(hitRect); + + itemGroup.eachChild(function(child) { + child.silent = true; + }); + + hitRect.silent = !selectMode; + + this.getContentGroup().add(itemGroup); + + setHoverStyle(itemGroup); + + itemGroup.__legendDataIndex = dataIndex; + + return itemGroup; + }, + + /** + * @protected + */ + layoutInner: function(legendModel, itemAlign, maxSize) { + var contentGroup = this.getContentGroup(); + + // Place items in contentGroup. + box( + legendModel.get('orient'), + contentGroup, + legendModel.get('itemGap'), + maxSize.width, + maxSize.height + ); + + var contentRect = contentGroup.getBoundingRect(); + contentGroup.attr('position', [-contentRect.x, -contentRect.y]); + + return this.group.getBoundingRect(); + } + + }); + + function dispatchSelectAction(name, api) { + api.dispatchAction({ + type: 'legendToggleSelect', + name: name + }); + } + + function dispatchHighlightAction(seriesModel, dataName, api, excludeSeriesId) { + // If element hover will move to a hoverLayer. + var el = api.getZr().storage.getDisplayList()[0]; + if (!(el && el.useHoverLayer)) { + api.dispatchAction({ + type: 'highlight', + seriesName: seriesModel.name, + name: dataName, + excludeSeriesId: excludeSeriesId + }); + } + } + + function dispatchDownplayAction(seriesModel, dataName, api, excludeSeriesId) { + // If element hover will move to a hoverLayer. + var el = api.getZr().storage.getDisplayList()[0]; + if (!(el && el.useHoverLayer)) { + api.dispatchAction({ + type: 'downplay', + seriesName: seriesModel.name, + name: dataName, + excludeSeriesId: excludeSeriesId + }); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var legendFilter = function(ecModel) { + + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (legendModels && legendModels.length) { + ecModel.filterSeries(function(series) { + // If in any legend component the status is not selected. + // Because in legend series is assumed selected when it is not in the legend data. + for (var i = 0; i < legendModels.length; i++) { + if (!legendModels[i].isSelected(series.name)) { + return false; + } + } + return true; + }); + } + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + // Do not contain scrollable legend, for sake of file size. + + // Series Filter + registerProcessor(legendFilter); + + ComponentModel.registerSubTypeDefaulter('legend', function() { + // Default 'plain' when no type specified. + return 'plain'; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var ScrollableLegendModel = LegendModel.extend({ + + type: 'legend.scroll', + + /** + * @param {number} scrollDataIndex + */ + setScrollDataIndex: function(scrollDataIndex) { + this.option.scrollDataIndex = scrollDataIndex; + }, + + defaultOption: { + scrollDataIndex: 0, + pageButtonItemGap: 5, + pageButtonGap: null, + pageButtonPosition: 'end', // 'start' or 'end' + pageFormatter: '{current}/{total}', // If null/undefined, do not show page. + pageIcons: { + horizontal: ['M0,0L12,-10L12,10z', 'M0,0L-12,-10L-12,10z'], + vertical: ['M0,0L20,0L10,-20z', 'M0,0L20,0L10,20z'] + }, + pageIconColor: '#2f4554', + pageIconInactiveColor: '#aaa', + pageIconSize: 15, // Can be [10, 3], which represents [width, height] + pageTextStyle: { + color: '#333' + }, + + animationDurationUpdate: 800 + }, + + /** + * @override + */ + init: function(option, parentModel, ecModel, extraOpt) { + var inputPositionParams = getLayoutParams(option); + + ScrollableLegendModel.superCall(this, 'init', option, parentModel, ecModel, extraOpt); + + mergeAndNormalizeLayoutParams(this, option, inputPositionParams); + }, + + /** + * @override + */ + mergeOption: function(option, extraOpt) { + ScrollableLegendModel.superCall(this, 'mergeOption', option, extraOpt); + + mergeAndNormalizeLayoutParams(this, this.option, option); + }, + + getOrient: function() { + return this.get('orient') === 'vertical' ? + { + index: 1, + name: 'vertical' + } : + { + index: 0, + name: 'horizontal' + }; + } + + }); + + // Do not `ignoreSize` to enable setting {left: 10, right: 10}. + function mergeAndNormalizeLayoutParams(legendModel, target, raw) { + var orient = legendModel.getOrient(); + var ignoreSize = [1, 1]; + ignoreSize[orient.index] = 0; + mergeLayoutParam(target, raw, { + type: 'box', + ignoreSize: ignoreSize + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Separate legend and scrollable legend to reduce package size. + */ + + var Group$4 = Group; + + var WH$1 = ['width', 'height']; + var XY$1 = ['x', 'y']; + + var ScrollableLegendView = LegendView.extend({ + + type: 'legend.scroll', + + newlineDisabled: true, + + init: function() { + + ScrollableLegendView.superCall(this, 'init'); + + /** + * @private + * @type {number} For `scroll`. + */ + this._currentIndex = 0; + + /** + * @private + * @type {module:zrender/container/Group} + */ + this.group.add(this._containerGroup = new Group$4()); + this._containerGroup.add(this.getContentGroup()); + + /** + * @private + * @type {module:zrender/container/Group} + */ + this.group.add(this._controllerGroup = new Group$4()); + + /** + * + * @private + */ + this._showController; + }, + + /** + * @override + */ + resetInner: function() { + ScrollableLegendView.superCall(this, 'resetInner'); + + this._controllerGroup.removeAll(); + this._containerGroup.removeClipPath(); + this._containerGroup.__rectSize = null; + }, + + /** + * @override + */ + renderInner: function(itemAlign, legendModel, ecModel, api) { + var me = this; + + // Render content items. + ScrollableLegendView.superCall(this, 'renderInner', itemAlign, legendModel, ecModel, api); + + var controllerGroup = this._controllerGroup; + + var pageIconSize = legendModel.get('pageIconSize', true); + if (!isArray(pageIconSize)) { + pageIconSize = [pageIconSize, pageIconSize]; + } + + createPageButton('pagePrev', 0); + + var pageTextStyleModel = legendModel.getModel('pageTextStyle'); + controllerGroup.add(new Text({ + name: 'pageText', + style: { + textFill: pageTextStyleModel.getTextColor(), + font: pageTextStyleModel.getFont(), + textVerticalAlign: 'middle', + textAlign: 'center' + }, + silent: true + })); + + createPageButton('pageNext', 1); + + function createPageButton(name, iconIdx) { + var pageDataIndexName = name + 'DataIndex'; + var icon = createIcon( + legendModel.get('pageIcons', true)[legendModel.getOrient().name][iconIdx], { + // Buttons will be created in each render, so we do not need + // to worry about avoiding using legendModel kept in scope. + onclick: bind( + me._pageGo, me, pageDataIndexName, legendModel, api + ) + }, { + x: -pageIconSize[0] / 2, + y: -pageIconSize[1] / 2, + width: pageIconSize[0], + height: pageIconSize[1] + } + ); + icon.name = name; + controllerGroup.add(icon); + } + }, + + /** + * @override + */ + layoutInner: function(legendModel, itemAlign, maxSize) { + var contentGroup = this.getContentGroup(); + var containerGroup = this._containerGroup; + var controllerGroup = this._controllerGroup; + + var orientIdx = legendModel.getOrient().index; + var wh = WH$1[orientIdx]; + var hw = WH$1[1 - orientIdx]; + var yx = XY$1[1 - orientIdx]; + + // Place items in contentGroup. + box( + legendModel.get('orient'), + contentGroup, + legendModel.get('itemGap'), + !orientIdx ? null : maxSize.width, + orientIdx ? null : maxSize.height + ); + + box( + // Buttons in controller are layout always horizontally. + 'horizontal', + controllerGroup, + legendModel.get('pageButtonItemGap', true) + ); + + var contentRect = contentGroup.getBoundingRect(); + var controllerRect = controllerGroup.getBoundingRect(); + var showController = this._showController = contentRect[wh] > maxSize[wh]; + + var contentPos = [-contentRect.x, -contentRect.y]; + // Remain contentPos when scroll animation perfroming. + contentPos[orientIdx] = contentGroup.position[orientIdx]; + + // Layout container group based on 0. + var containerPos = [0, 0]; + var controllerPos = [-controllerRect.x, -controllerRect.y]; + var pageButtonGap = retrieve2( + legendModel.get('pageButtonGap', true), legendModel.get('itemGap', true) + ); + + // Place containerGroup and controllerGroup and contentGroup. + if (showController) { + var pageButtonPosition = legendModel.get('pageButtonPosition', true); + // controller is on the right / bottom. + if (pageButtonPosition === 'end') { + controllerPos[orientIdx] += maxSize[wh] - controllerRect[wh]; + } + // controller is on the left / top. + else { + containerPos[orientIdx] += controllerRect[wh] + pageButtonGap; + } + } + + // Always align controller to content as 'middle'. + controllerPos[1 - orientIdx] += contentRect[hw] / 2 - controllerRect[hw] / 2; + + contentGroup.attr('position', contentPos); + containerGroup.attr('position', containerPos); + controllerGroup.attr('position', controllerPos); + + // Calculate `mainRect` and set `clipPath`. + // mainRect should not be calculated by `this.group.getBoundingRect()` + // for sake of the overflow. + var mainRect = this.group.getBoundingRect(); + var mainRect = { + x: 0, + y: 0 + }; + // Consider content may be overflow (should be clipped). + mainRect[wh] = showController ? maxSize[wh] : contentRect[wh]; + mainRect[hw] = Math.max(contentRect[hw], controllerRect[hw]); + // `containerRect[yx] + containerPos[1 - orientIdx]` is 0. + mainRect[yx] = Math.min(0, controllerRect[yx] + controllerPos[1 - orientIdx]); + + containerGroup.__rectSize = maxSize[wh]; + if (showController) { + var clipShape = { + x: 0, + y: 0 + }; + clipShape[wh] = Math.max(maxSize[wh] - controllerRect[wh] - pageButtonGap, 0); + clipShape[hw] = mainRect[hw]; + containerGroup.setClipPath(new Rect({ + shape: clipShape + })); + // Consider content may be larger than container, container rect + // can not be obtained from `containerGroup.getBoundingRect()`. + containerGroup.__rectSize = clipShape[wh]; + } else { + // Do not remove or ignore controller. Keep them set as place holders. + controllerGroup.eachChild(function(child) { + child.attr({ + invisible: true, + silent: true + }); + }); + } + + // Content translate animation. + var pageInfo = this._getPageInfo(legendModel); + pageInfo.pageIndex != null && updateProps( + contentGroup, { + position: pageInfo.contentPosition + }, + // When switch from "show controller" to "not show controller", view should be + // updated immediately without animation, otherwise causes weird efffect. + showController ? legendModel : false + ); + + this._updatePageInfoView(legendModel, pageInfo); + + return mainRect; + }, + + _pageGo: function(to, legendModel, api) { + var scrollDataIndex = this._getPageInfo(legendModel)[to]; + + scrollDataIndex != null && api.dispatchAction({ + type: 'legendScroll', + scrollDataIndex: scrollDataIndex, + legendId: legendModel.id + }); + }, + + _updatePageInfoView: function(legendModel, pageInfo) { + var controllerGroup = this._controllerGroup; + + each$1(['pagePrev', 'pageNext'], function(name) { + var canJump = pageInfo[name + 'DataIndex'] != null; + var icon = controllerGroup.childOfName(name); + if (icon) { + icon.setStyle( + 'fill', + canJump ? + legendModel.get('pageIconColor', true) : + legendModel.get('pageIconInactiveColor', true) + ); + icon.cursor = canJump ? 'pointer' : 'default'; + } + }); + + var pageText = controllerGroup.childOfName('pageText'); + var pageFormatter = legendModel.get('pageFormatter'); + var pageIndex = pageInfo.pageIndex; + var current = pageIndex != null ? pageIndex + 1 : 0; + var total = pageInfo.pageCount; + + pageText && pageFormatter && pageText.setStyle( + 'text', + isString(pageFormatter) ? + pageFormatter.replace('{current}', current).replace('{total}', total) : + pageFormatter({ + current: current, + total: total + }) + ); + }, + + /** + * @param {module:echarts/model/Model} legendModel + * @return {Object} { + * contentPosition: Array., null when data item not found. + * pageIndex: number, null when data item not found. + * pageCount: number, always be a number, can be 0. + * pagePrevDataIndex: number, null when no next page. + * pageNextDataIndex: number, null when no previous page. + * } + */ + _getPageInfo: function(legendModel) { + // Align left or top by the current dataIndex. + var currDataIndex = legendModel.get('scrollDataIndex', true); + var contentGroup = this.getContentGroup(); + var contentRect = contentGroup.getBoundingRect(); + var containerRectSize = this._containerGroup.__rectSize; + + var orientIdx = legendModel.getOrient().index; + var wh = WH$1[orientIdx]; + var hw = WH$1[1 - orientIdx]; + var xy = XY$1[orientIdx]; + var contentPos = contentGroup.position.slice(); + + var pageIndex; + var pagePrevDataIndex; + var pageNextDataIndex; + + var targetItemGroup; + if (this._showController) { + contentGroup.eachChild(function(child) { + if (child.__legendDataIndex === currDataIndex) { + targetItemGroup = child; + } + }); + } else { + targetItemGroup = contentGroup.childAt(0); + } + + var pageCount = containerRectSize ? Math.ceil(contentRect[wh] / containerRectSize) : 0; + + if (targetItemGroup) { + var itemRect = targetItemGroup.getBoundingRect(); + var itemLoc = targetItemGroup.position[orientIdx] + itemRect[xy]; + contentPos[orientIdx] = -itemLoc - contentRect[xy]; + pageIndex = Math.floor( + pageCount * (itemLoc + itemRect[xy] + containerRectSize / 2) / contentRect[wh] + ); + pageIndex = (contentRect[wh] && pageCount) ? + Math.max(0, Math.min(pageCount - 1, pageIndex)) : + -1; + + var winRect = { + x: 0, + y: 0 + }; + winRect[wh] = containerRectSize; + winRect[hw] = contentRect[hw]; + winRect[xy] = -contentPos[orientIdx] - contentRect[xy]; + + var startIdx; + var children = contentGroup.children(); + + contentGroup.eachChild(function(child, index) { + var itemRect = getItemRect(child); + + if (itemRect.intersect(winRect)) { + startIdx == null && (startIdx = index); + // It is user-friendly that the last item shown in the + // current window is shown at the begining of next window. + pageNextDataIndex = child.__legendDataIndex; + } + + // If the last item is shown entirely, no next page. + if (index === children.length - 1 && + itemRect[xy] + itemRect[wh] <= winRect[xy] + winRect[wh] + ) { + pageNextDataIndex = null; + } + }); + + // Always align based on the left/top most item, so the left/top most + // item in the previous window is needed to be found here. + if (startIdx != null) { + var startItem = children[startIdx]; + var startRect = getItemRect(startItem); + winRect[xy] = startRect[xy] + startRect[wh] - winRect[wh]; + + // If the first item is shown entirely, no previous page. + if (startIdx <= 0 && startRect[xy] >= winRect[xy]) { + pagePrevDataIndex = null; + } else { + while (startIdx > 0 && getItemRect(children[startIdx - 1]).intersect(winRect)) { + startIdx--; + } + pagePrevDataIndex = children[startIdx].__legendDataIndex; + } + } + } + + return { + contentPosition: contentPos, + pageIndex: pageIndex, + pageCount: pageCount, + pagePrevDataIndex: pagePrevDataIndex, + pageNextDataIndex: pageNextDataIndex + }; + + function getItemRect(el) { + var itemRect = el.getBoundingRect().clone(); + itemRect[xy] += el.position[orientIdx]; + return itemRect; + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @event legendScroll + * @type {Object} + * @property {string} type 'legendScroll' + * @property {string} scrollDataIndex + */ + registerAction( + 'legendScroll', 'legendscroll', + function(payload, ecModel) { + var scrollDataIndex = payload.scrollDataIndex; + + scrollDataIndex != null && ecModel.eachComponent({ + mainType: 'legend', + subType: 'scroll', + query: payload + }, + function(legendModel) { + legendModel.setScrollDataIndex(scrollDataIndex); + } + ); + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Legend component entry file8 + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentModel({ + + type: 'tooltip', + + dependencies: ['axisPointer'], + + defaultOption: { + zlevel: 0, + + z: 8, + + show: true, + + // tooltip主体内容 + showContent: true, + + // 'trigger' only works on coordinate system. + // 'item' | 'axis' | 'none' + trigger: 'item', + + // 'click' | 'mousemove' | 'none' + triggerOn: 'mousemove|click', + + alwaysShowContent: false, + + displayMode: 'single', // 'single' | 'multipleByCoordSys' + + // 位置 {Array} | {Function} + // position: null + // Consider triggered from axisPointer handle, verticalAlign should be 'middle' + // align: null, + // verticalAlign: null, + + // 是否约束 content 在 viewRect 中。默认 false 是为了兼容以前版本。 + confine: false, + + // 内容格式器:{string}(Template) ¦ {Function} + // formatter: null + + showDelay: 0, + + // 隐藏延迟,单位ms + hideDelay: 100, + + // 动画变换时间,单位s + transitionDuration: 0.4, + + enterable: false, + + // 提示背景颜色,默认为透明度为0.7的黑色 + backgroundColor: 'rgba(50,50,50,0.7)', + + // 提示边框颜色 + borderColor: '#333', + + // 提示边框圆角,单位px,默认为4 + borderRadius: 4, + + // 提示边框线宽,单位px,默认为0(无边框) + borderWidth: 0, + + // 提示内边距,单位px,默认各方向内边距为5, + // 接受数组分别设定上右下左边距,同css + padding: 5, + + // Extra css text + extraCssText: '', + + // 坐标轴指示器,坐标轴触发有效 + axisPointer: { + // 默认为直线 + // 可选为:'line' | 'shadow' | 'cross' + type: 'line', + + // type 为 line 的时候有效,指定 tooltip line 所在的轴,可选 + // 可选 'x' | 'y' | 'angle' | 'radius' | 'auto' + // 默认 'auto',会选择类型为 category 的轴,对于双数值轴,笛卡尔坐标系会默认选择 x 轴 + // 极坐标系会默认选择 angle 轴 + axis: 'auto', + + animation: 'auto', + animationDurationUpdate: 200, + animationEasingUpdate: 'exponentialOut', + + crossStyle: { + color: '#999', + width: 1, + type: 'dashed', + + // TODO formatter + textStyle: {} + } + + // lineStyle and shadowStyle should not be specified here, + // otherwise it will always override those styles on option.axisPointer. + }, + textStyle: { + color: '#fff', + fontSize: 14 + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$18 = each$1; + var toCamelCase$1 = toCamelCase; + + var vendors = ['', '-webkit-', '-moz-', '-o-']; + + var gCssText = 'position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;'; + + /** + * @param {number} duration + * @return {string} + * @inner + */ + function assembleTransition(duration) { + var transitionCurve = 'cubic-bezier(0.23, 1, 0.32, 1)'; + var transitionText = 'left ' + duration + 's ' + transitionCurve + ',' + + 'top ' + duration + 's ' + transitionCurve; + return map(vendors, function(vendorPrefix) { + return vendorPrefix + 'transition:' + transitionText; + }).join(';'); + } + + /** + * @param {Object} textStyle + * @return {string} + * @inner + */ + function assembleFont(textStyleModel) { + var cssText = []; + + var fontSize = textStyleModel.get('fontSize'); + var color = textStyleModel.getTextColor(); + + color && cssText.push('color:' + color); + + cssText.push('font:' + textStyleModel.getFont()); + + fontSize && + cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px'); + + each$18(['decoration', 'align'], function(name) { + var val = textStyleModel.get(name); + val && cssText.push('text-' + name + ':' + val); + }); + + return cssText.join(';'); + } + + /** + * @param {Object} tooltipModel + * @return {string} + * @inner + */ + function assembleCssText(tooltipModel) { + + var cssText = []; + + var transitionDuration = tooltipModel.get('transitionDuration'); + var backgroundColor = tooltipModel.get('backgroundColor'); + var textStyleModel = tooltipModel.getModel('textStyle'); + var padding = tooltipModel.get('padding'); + + // Animation transition. Do not animate when transitionDuration is 0. + transitionDuration && + cssText.push(assembleTransition(transitionDuration)); + + if (backgroundColor) { + if (env$1.canvasSupported) { + cssText.push('background-Color:' + backgroundColor); + } else { + // for ie + cssText.push( + 'background-Color:#' + toHex(backgroundColor) + ); + cssText.push('filter:alpha(opacity=70)'); + } + } + + // Border style + each$18(['width', 'color', 'radius'], function(name) { + var borderName = 'border-' + name; + var camelCase = toCamelCase$1(borderName); + var val = tooltipModel.get(camelCase); + val != null && + cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px')); + }); + + // Text style + cssText.push(assembleFont(textStyleModel)); + + // Padding + if (padding != null) { + cssText.push('padding:' + normalizeCssArray$1(padding).join('px ') + 'px'); + } + + return cssText.join(';') + ';'; + } + + /** + * @alias module:echarts/component/tooltip/TooltipContent + * @constructor + */ + function TooltipContent(container, api) { + if (env$1.wxa) { + return null; + } + + var el = document.createElement('div'); + var zr = this._zr = api.getZr(); + + this.el = el; + + this._x = api.getWidth() / 2; + this._y = api.getHeight() / 2; + + container.appendChild(el); + + this._container = container; + + this._show = false; + + /** + * @private + */ + this._hideTimeout; + + var self = this; + el.onmouseenter = function() { + // clear the timeout in hideLater and keep showing tooltip + if (self._enterable) { + clearTimeout(self._hideTimeout); + self._show = true; + } + self._inContent = true; + }; + el.onmousemove = function(e) { + e = e || window.event; + if (!self._enterable) { + // Try trigger zrender event to avoid mouse + // in and out shape too frequently + var handler = zr.handler; + normalizeEvent(container, e, true); + handler.dispatch('mousemove', e); + } + }; + el.onmouseleave = function() { + if (self._enterable) { + if (self._show) { + self.hideLater(self._hideDelay); + } + } + self._inContent = false; + }; + } + + TooltipContent.prototype = { + + constructor: TooltipContent, + + /** + * @private + * @type {boolean} + */ + _enterable: true, + + /** + * Update when tooltip is rendered + */ + update: function() { + // FIXME + // Move this logic to ec main? + var container = this._container; + var stl = container.currentStyle || + document.defaultView.getComputedStyle(container); + var domStyle = container.style; + if (domStyle.position !== 'absolute' && stl.position !== 'absolute') { + domStyle.position = 'relative'; + } + // Hide the tooltip + // PENDING + // this.hide(); + }, + + show: function(tooltipModel) { + clearTimeout(this._hideTimeout); + var el = this.el; + + el.style.cssText = gCssText + assembleCssText(tooltipModel) + // http://stackoverflow.com/questions/21125587/css3-transition-not-working-in-chrome-anymore + + + ';left:' + this._x + 'px;top:' + this._y + 'px;' + + (tooltipModel.get('extraCssText') || ''); + + el.style.display = el.innerHTML ? 'block' : 'none'; + + this._show = true; + }, + + setContent: function(content) { + this.el.innerHTML = content == null ? '' : content; + }, + + setEnterable: function(enterable) { + this._enterable = enterable; + }, + + getSize: function() { + var el = this.el; + return [el.clientWidth, el.clientHeight]; + }, + + moveTo: function(x, y) { + // xy should be based on canvas root. But tooltipContent is + // the sibling of canvas root. So padding of ec container + // should be considered here. + var zr = this._zr; + var viewportRootOffset; + if (zr && zr.painter && (viewportRootOffset = zr.painter.getViewportRootOffset())) { + x += viewportRootOffset.offsetLeft; + y += viewportRootOffset.offsetTop; + } + + var style = this.el.style; + style.left = x + 'px'; + style.top = y + 'px'; + + this._x = x; + this._y = y; + }, + + hide: function() { + this.el.style.display = 'none'; + this._show = false; + }, + + hideLater: function(time) { + if (this._show && !(this._inContent && this._enterable)) { + if (time) { + this._hideDelay = time; + // Set show false to avoid invoke hideLater mutiple times + this._show = false; + this._hideTimeout = setTimeout(bind(this.hide, this), time); + } else { + this.hide(); + } + } + }, + + isShow: function() { + return this._show; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var bind$3 = bind; + var each$17 = each$1; + var parsePercent$2 = parsePercent$1; + + var proxyRect = new Rect({ + shape: { + x: -1, + y: -1, + width: 2, + height: 2 + } + }); + + extendComponentView({ + + type: 'tooltip', + + init: function(ecModel, api) { + if (env$1.node) { + return; + } + var tooltipContent = new TooltipContent(api.getDom(), api); + this._tooltipContent = tooltipContent; + }, + + render: function(tooltipModel, ecModel, api) { + if (env$1.node || env$1.wxa) { + return; + } + + // Reset + this.group.removeAll(); + + /** + * @private + * @type {module:echarts/component/tooltip/TooltipModel} + */ + this._tooltipModel = tooltipModel; + + /** + * @private + * @type {module:echarts/model/Global} + */ + this._ecModel = ecModel; + + /** + * @private + * @type {module:echarts/ExtensionAPI} + */ + this._api = api; + + /** + * Should be cleaned when render. + * @private + * @type {Array.>} + */ + this._lastDataByCoordSys = null; + + /** + * @private + * @type {boolean} + */ + this._alwaysShowContent = tooltipModel.get('alwaysShowContent'); + + var tooltipContent = this._tooltipContent; + tooltipContent.update(); + tooltipContent.setEnterable(tooltipModel.get('enterable')); + + this._initGlobalListener(); + + this._keepShow(); + }, + + _initGlobalListener: function() { + var tooltipModel = this._tooltipModel; + var triggerOn = tooltipModel.get('triggerOn'); + + register( + 'itemTooltip', + this._api, + bind$3(function(currTrigger, e, dispatchAction) { + // If 'none', it is not controlled by mouse totally. + if (triggerOn !== 'none') { + if (triggerOn.indexOf(currTrigger) >= 0) { + this._tryShow(e, dispatchAction); + } else if (currTrigger === 'leave') { + this._hide(dispatchAction); + } + } + }, this) + ); + }, + + _keepShow: function() { + var tooltipModel = this._tooltipModel; + var ecModel = this._ecModel; + var api = this._api; + + // Try to keep the tooltip show when refreshing + if (this._lastX != null && + this._lastY != null + // When user is willing to control tooltip totally using API, + // self.manuallyShowTip({x, y}) might cause tooltip hide, + // which is not expected. + && + tooltipModel.get('triggerOn') !== 'none' + ) { + var self = this; + clearTimeout(this._refreshUpdateTimeout); + this._refreshUpdateTimeout = setTimeout(function() { + // Show tip next tick after other charts are rendered + // In case highlight action has wrong result + // FIXME + self.manuallyShowTip(tooltipModel, ecModel, api, { + x: self._lastX, + y: self._lastY + }); + }); + } + }, + + /** + * Show tip manually by + * dispatchAction({ + * type: 'showTip', + * x: 10, + * y: 10 + * }); + * Or + * dispatchAction({ + * type: 'showTip', + * seriesIndex: 0, + * dataIndex or dataIndexInside or name + * }); + * + * TODO Batch + */ + manuallyShowTip: function(tooltipModel, ecModel, api, payload) { + if (payload.from === this.uid || env$1.node) { + return; + } + + var dispatchAction = makeDispatchAction$1(payload, api); + + // Reset ticket + this._ticket = ''; + + // When triggered from axisPointer. + var dataByCoordSys = payload.dataByCoordSys; + + if (payload.tooltip && payload.x != null && payload.y != null) { + var el = proxyRect; + el.position = [payload.x, payload.y]; + el.update(); + el.tooltip = payload.tooltip; + // Manually show tooltip while view is not using zrender elements. + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + target: el + }, dispatchAction); + } else if (dataByCoordSys) { + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + position: payload.position, + event: {}, + dataByCoordSys: payload.dataByCoordSys, + tooltipOption: payload.tooltipOption + }, dispatchAction); + } else if (payload.seriesIndex != null) { + + if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) { + return; + } + + var pointInfo = findPointFromSeries(payload, ecModel); + var cx = pointInfo.point[0]; + var cy = pointInfo.point[1]; + if (cx != null && cy != null) { + this._tryShow({ + offsetX: cx, + offsetY: cy, + position: payload.position, + target: pointInfo.el, + event: {} + }, dispatchAction); + } + } else if (payload.x != null && payload.y != null) { + // FIXME + // should wrap dispatchAction like `axisPointer/globalListener` ? + api.dispatchAction({ + type: 'updateAxisPointer', + x: payload.x, + y: payload.y + }); + + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + position: payload.position, + target: api.getZr().findHover(payload.x, payload.y).target, + event: {} + }, dispatchAction); + } + }, + + manuallyHideTip: function(tooltipModel, ecModel, api, payload) { + var tooltipContent = this._tooltipContent; + + if (!this._alwaysShowContent && this._tooltipModel) { + tooltipContent.hideLater(this._tooltipModel.get('hideDelay')); + } + + this._lastX = this._lastY = null; + + if (payload.from !== this.uid) { + this._hide(makeDispatchAction$1(payload, api)); + } + }, + + // Be compatible with previous design, that is, when tooltip.type is 'axis' and + // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer + // and tooltip. + _manuallyAxisShowTip: function(tooltipModel, ecModel, api, payload) { + var seriesIndex = payload.seriesIndex; + var dataIndex = payload.dataIndex; + var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; + + if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) { + return; + } + + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + if (!seriesModel) { + return; + } + + var data = seriesModel.getData(); + var tooltipModel = buildTooltipModel([ + data.getItemModel(dataIndex), + seriesModel, + (seriesModel.coordinateSystem || {}).model, + tooltipModel + ]); + + if (tooltipModel.get('trigger') !== 'axis') { + return; + } + + api.dispatchAction({ + type: 'updateAxisPointer', + seriesIndex: seriesIndex, + dataIndex: dataIndex, + position: payload.position + }); + + return true; + }, + + _tryShow: function(e, dispatchAction) { + var el = e.target; + var tooltipModel = this._tooltipModel; + + if (!tooltipModel) { + return; + } + + // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed + this._lastX = e.offsetX; + this._lastY = e.offsetY; + + var dataByCoordSys = e.dataByCoordSys; + if (dataByCoordSys && dataByCoordSys.length) { + this._showAxisTooltip(dataByCoordSys, e); + } + // Always show item tooltip if mouse is on the element with dataIndex + else if (el && el.dataIndex != null) { + this._lastDataByCoordSys = null; + this._showSeriesItemTooltip(e, el, dispatchAction); + } + // Tooltip provided directly. Like legend. + else if (el && el.tooltip) { + this._lastDataByCoordSys = null; + this._showComponentItemTooltip(e, el, dispatchAction); + } else { + this._lastDataByCoordSys = null; + this._hide(dispatchAction); + } + }, + + _showOrMove: function(tooltipModel, cb) { + // showDelay is used in this case: tooltip.enterable is set + // as true. User intent to move mouse into tooltip and click + // something. `showDelay` makes it easyer to enter the content + // but tooltip do not move immediately. + var delay = tooltipModel.get('showDelay'); + cb = bind(cb, this); + clearTimeout(this._showTimout); + delay > 0 ? + (this._showTimout = setTimeout(cb, delay)) : + cb(); + }, + + _showAxisTooltip: function(dataByCoordSys, e) { + var ecModel = this._ecModel; + var globalTooltipModel = this._tooltipModel; + var point = [e.offsetX, e.offsetY]; + var singleDefaultHTML = []; + var singleParamsList = []; + var singleTooltipModel = buildTooltipModel([ + e.tooltipOption, + globalTooltipModel + ]); + + each$17(dataByCoordSys, function(itemCoordSys) { + // var coordParamList = []; + // var coordDefaultHTML = []; + // var coordTooltipModel = buildTooltipModel([ + // e.tooltipOption, + // itemCoordSys.tooltipOption, + // ecModel.getComponent(itemCoordSys.coordSysMainType, itemCoordSys.coordSysIndex), + // globalTooltipModel + // ]); + // var displayMode = coordTooltipModel.get('displayMode'); + // var paramsList = displayMode === 'single' ? singleParamsList : []; + + each$17(itemCoordSys.dataByAxis, function(item) { + var axisModel = ecModel.getComponent(item.axisDim + 'Axis', item.axisIndex); + var axisValue = item.value; + var seriesDefaultHTML = []; + + if (!axisModel || axisValue == null) { + return; + } + + var valueLabel = getValueLabel( + axisValue, axisModel.axis, ecModel, + item.seriesDataIndices, + item.valueLabelOpt + ); + + each$1(item.seriesDataIndices, function(idxItem) { + var series = ecModel.getSeriesByIndex(idxItem.seriesIndex); + var dataIndex = idxItem.dataIndexInside; + var dataParams = series && series.getDataParams(dataIndex); + dataParams.axisDim = item.axisDim; + dataParams.axisIndex = item.axisIndex; + dataParams.axisType = item.axisType; + dataParams.axisId = item.axisId; + dataParams.axisValue = getAxisRawValue(axisModel.axis, axisValue); + dataParams.axisValueLabel = valueLabel; + + if (dataParams) { + singleParamsList.push(dataParams); + seriesDefaultHTML.push(series.formatTooltip(dataIndex, true)); + } + }); + + // Default tooltip content + // FIXME + // (1) shold be the first data which has name? + // (2) themeRiver, firstDataIndex is array, and first line is unnecessary. + var firstLine = valueLabel; + singleDefaultHTML.push( + (firstLine ? encodeHTML(firstLine) + '
' : '') + + seriesDefaultHTML.join('
') + ); + }); + }, this); + + // In most case, the second axis is shown upper than the first one. + singleDefaultHTML.reverse(); + singleDefaultHTML = singleDefaultHTML.join('

'); + + var positionExpr = e.position; + this._showOrMove(singleTooltipModel, function() { + if (this._updateContentNotChangedOnAxis(dataByCoordSys)) { + this._updatePosition( + singleTooltipModel, + positionExpr, + point[0], point[1], + this._tooltipContent, + singleParamsList + ); + } else { + this._showTooltipContent( + singleTooltipModel, singleDefaultHTML, singleParamsList, Math.random(), + point[0], point[1], positionExpr + ); + } + }); + + // Do not trigger events here, because this branch only be entered + // from dispatchAction. + }, + + _showSeriesItemTooltip: function(e, el, dispatchAction) { + var ecModel = this._ecModel; + // Use dataModel in element if possible + // Used when mouseover on a element like markPoint or edge + // In which case, the data is not main data in series. + var seriesIndex = el.seriesIndex; + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + + // For example, graph link. + var dataModel = el.dataModel || seriesModel; + var dataIndex = el.dataIndex; + var dataType = el.dataType; + var data = dataModel.getData(); + + var tooltipModel = buildTooltipModel([ + data.getItemModel(dataIndex), + dataModel, + seriesModel && (seriesModel.coordinateSystem || {}).model, + this._tooltipModel + ]); + + var tooltipTrigger = tooltipModel.get('trigger'); + if (tooltipTrigger != null && tooltipTrigger !== 'item') { + return; + } + + var params = dataModel.getDataParams(dataIndex, dataType); + var defaultHtml = dataModel.formatTooltip(dataIndex, false, dataType); + var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex; + + this._showOrMove(tooltipModel, function() { + this._showTooltipContent( + tooltipModel, defaultHtml, params, asyncTicket, + e.offsetX, e.offsetY, e.position, e.target + ); + }); + + // FIXME + // duplicated showtip if manuallyShowTip is called from dispatchAction. + dispatchAction({ + type: 'showTip', + dataIndexInside: dataIndex, + dataIndex: data.getRawIndex(dataIndex), + seriesIndex: seriesIndex, + from: this.uid + }); + }, + + _showComponentItemTooltip: function(e, el, dispatchAction) { + var tooltipOpt = el.tooltip; + if (typeof tooltipOpt === 'string') { + var content = tooltipOpt; + tooltipOpt = { + content: content, + // Fixed formatter + formatter: content + }; + } + var subTooltipModel = new Model(tooltipOpt, this._tooltipModel, this._ecModel); + var defaultHtml = subTooltipModel.get('content'); + var asyncTicket = Math.random(); + + // Do not check whether `trigger` is 'none' here, because `trigger` + // only works on cooridinate system. In fact, we have not found case + // that requires setting `trigger` nothing on component yet. + + this._showOrMove(subTooltipModel, function() { + this._showTooltipContent( + subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {}, + asyncTicket, e.offsetX, e.offsetY, e.position, el + ); + }); + + // If not dispatch showTip, tip may be hide triggered by axis. + dispatchAction({ + type: 'showTip', + from: this.uid + }); + }, + + _showTooltipContent: function( + tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el + ) { + // Reset ticket + this._ticket = ''; + + if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) { + return; + } + + var tooltipContent = this._tooltipContent; + + var formatter = tooltipModel.get('formatter'); + positionExpr = positionExpr || tooltipModel.get('position'); + var html = defaultHtml; + + if (formatter && typeof formatter === 'string') { + html = formatTpl(formatter, params, true); + } else if (typeof formatter === 'function') { + var callback = bind$3(function(cbTicket, html) { + if (cbTicket === this._ticket) { + tooltipContent.setContent(html); + this._updatePosition( + tooltipModel, positionExpr, x, y, tooltipContent, params, el + ); + } + }, this); + this._ticket = asyncTicket; + html = formatter(params, asyncTicket, callback); + } + + tooltipContent.setContent(html); + tooltipContent.show(tooltipModel); + + this._updatePosition( + tooltipModel, positionExpr, x, y, tooltipContent, params, el + ); + }, + + /** + * @param {string|Function|Array.|Object} positionExpr + * @param {number} x Mouse x + * @param {number} y Mouse y + * @param {boolean} confine Whether confine tooltip content in view rect. + * @param {Object|} params + * @param {module:zrender/Element} el target element + * @param {module:echarts/ExtensionAPI} api + * @return {Array.} + */ + _updatePosition: function(tooltipModel, positionExpr, x, y, content, params, el) { + var viewWidth = this._api.getWidth(); + var viewHeight = this._api.getHeight(); + positionExpr = positionExpr || tooltipModel.get('position'); + + var contentSize = content.getSize(); + var align = tooltipModel.get('align'); + var vAlign = tooltipModel.get('verticalAlign'); + var rect = el && el.getBoundingRect().clone(); + el && rect.applyTransform(el.transform); + + if (typeof positionExpr === 'function') { + // Callback of position can be an array or a string specify the position + positionExpr = positionExpr([x, y], params, content.el, rect, { + viewSize: [viewWidth, viewHeight], + contentSize: contentSize.slice() + }); + } + + if (isArray(positionExpr)) { + x = parsePercent$2(positionExpr[0], viewWidth); + y = parsePercent$2(positionExpr[1], viewHeight); + } else if (isObject$1(positionExpr)) { + positionExpr.width = contentSize[0]; + positionExpr.height = contentSize[1]; + var layoutRect = getLayoutRect( + positionExpr, { + width: viewWidth, + height: viewHeight + } + ); + x = layoutRect.x; + y = layoutRect.y; + align = null; + // When positionExpr is left/top/right/bottom, + // align and verticalAlign will not work. + vAlign = null; + } + // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element + else if (typeof positionExpr === 'string' && el) { + var pos = calcTooltipPosition( + positionExpr, rect, contentSize + ); + x = pos[0]; + y = pos[1]; + } else { + var pos = refixTooltipPosition( + x, y, content.el, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20 + ); + x = pos[0]; + y = pos[1]; + } + + align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0); + vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0); + + if (tooltipModel.get('confine')) { + var pos = confineTooltipPosition( + x, y, content.el, viewWidth, viewHeight + ); + x = pos[0]; + y = pos[1]; + } + + content.moveTo(x, y); + }, + + // FIXME + // Should we remove this but leave this to user? + _updateContentNotChangedOnAxis: function(dataByCoordSys) { + var lastCoordSys = this._lastDataByCoordSys; + var contentNotChanged = !!lastCoordSys && + lastCoordSys.length === dataByCoordSys.length; + + contentNotChanged && each$17(lastCoordSys, function(lastItemCoordSys, indexCoordSys) { + var lastDataByAxis = lastItemCoordSys.dataByAxis || {}; + var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {}; + var thisDataByAxis = thisItemCoordSys.dataByAxis || []; + contentNotChanged &= lastDataByAxis.length === thisDataByAxis.length; + + contentNotChanged && each$17(lastDataByAxis, function(lastItem, indexAxis) { + var thisItem = thisDataByAxis[indexAxis] || {}; + var lastIndices = lastItem.seriesDataIndices || []; + var newIndices = thisItem.seriesDataIndices || []; + + contentNotChanged &= + lastItem.value === thisItem.value && + lastItem.axisType === thisItem.axisType && + lastItem.axisId === thisItem.axisId && + lastIndices.length === newIndices.length; + + contentNotChanged && each$17(lastIndices, function(lastIdxItem, j) { + var newIdxItem = newIndices[j]; + contentNotChanged &= + lastIdxItem.seriesIndex === newIdxItem.seriesIndex && + lastIdxItem.dataIndex === newIdxItem.dataIndex; + }); + }); + }); + + this._lastDataByCoordSys = dataByCoordSys; + + return !!contentNotChanged; + }, + + _hide: function(dispatchAction) { + // Do not directly hideLater here, because this behavior may be prevented + // in dispatchAction when showTip is dispatched. + + // FIXME + // duplicated hideTip if manuallyHideTip is called from dispatchAction. + this._lastDataByCoordSys = null; + dispatchAction({ + type: 'hideTip', + from: this.uid + }); + }, + + dispose: function(ecModel, api) { + if (env$1.node || env$1.wxa) { + return; + } + this._tooltipContent.hide(); + unregister('itemTooltip', api); + } + }); + + + /** + * @param {Array.} modelCascade + * From top to bottom. (the last one should be globalTooltipModel); + */ + function buildTooltipModel(modelCascade) { + var resultModel = modelCascade.pop(); + while (modelCascade.length) { + var tooltipOpt = modelCascade.pop(); + if (tooltipOpt) { + if (Model.isInstance(tooltipOpt)) { + tooltipOpt = tooltipOpt.get('tooltip', true); + } + // In each data item tooltip can be simply write: + // { + // value: 10, + // tooltip: 'Something you need to know' + // } + if (typeof tooltipOpt === 'string') { + tooltipOpt = { + formatter: tooltipOpt + }; + } + resultModel = new Model(tooltipOpt, resultModel, resultModel.ecModel); + } + } + return resultModel; + } + + function makeDispatchAction$1(payload, api) { + return payload.dispatchAction || bind(api.dispatchAction, api); + } + + function refixTooltipPosition(x, y, el, viewWidth, viewHeight, gapH, gapV) { + var size = getOuterSize(el); + var width = size.width; + var height = size.height; + + if (gapH != null) { + if (x + width + gapH > viewWidth) { + x -= width + gapH; + } else { + x += gapH; + } + } + if (gapV != null) { + if (y + height + gapV > viewHeight) { + y -= height + gapV; + } else { + y += gapV; + } + } + return [x, y]; + } + + function confineTooltipPosition(x, y, el, viewWidth, viewHeight) { + var size = getOuterSize(el); + var width = size.width; + var height = size.height; + + x = Math.min(x + width, viewWidth) - width; + y = Math.min(y + height, viewHeight) - height; + x = Math.max(x, 0); + y = Math.max(y, 0); + + return [x, y]; + } + + function getOuterSize(el) { + var width = el.clientWidth; + var height = el.clientHeight; + + // Consider browser compatibility. + // IE8 does not support getComputedStyle. + if (document.defaultView && document.defaultView.getComputedStyle) { + var stl = document.defaultView.getComputedStyle(el); + if (stl) { + width += parseInt(stl.paddingLeft, 10) + parseInt(stl.paddingRight, 10) + + parseInt(stl.borderLeftWidth, 10) + parseInt(stl.borderRightWidth, 10); + height += parseInt(stl.paddingTop, 10) + parseInt(stl.paddingBottom, 10) + + parseInt(stl.borderTopWidth, 10) + parseInt(stl.borderBottomWidth, 10); + } + } + + return { + width: width, + height: height + }; + } + + function calcTooltipPosition(position, rect, contentSize) { + var domWidth = contentSize[0]; + var domHeight = contentSize[1]; + var gap = 5; + var x = 0; + var y = 0; + var rectWidth = rect.width; + var rectHeight = rect.height; + switch (position) { + case 'inside': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y + rectHeight / 2 - domHeight / 2; + break; + case 'top': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y - domHeight - gap; + break; + case 'bottom': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y + rectHeight + gap; + break; + case 'left': + x = rect.x - domWidth - gap; + y = rect.y + rectHeight / 2 - domHeight / 2; + break; + case 'right': + x = rect.x + rectWidth + gap; + y = rect.y + rectHeight / 2 - domHeight / 2; + } + return [x, y]; + } + + function isCenterAlign(align) { + return align === 'center' || align === 'middle'; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // FIXME Better way to pack data in graphic element + + /** + * @action + * @property {string} type + * @property {number} seriesIndex + * @property {number} dataIndex + * @property {number} [x] + * @property {number} [y] + */ + registerAction({ + type: 'showTip', + event: 'showTip', + update: 'tooltip:manuallyShowTip' + }, + // noop + function() {} + ); + + registerAction({ + type: 'hideTip', + event: 'hideTip', + update: 'tooltip:manuallyHideTip' + }, + // noop + function() {} + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function getSeriesStackId$1(seriesModel) { + return seriesModel.get('stack') || + '__ec_stack_' + seriesModel.seriesIndex; + } + + function getAxisKey$1(axis) { + return axis.dim; + } + + /** + * @param {string} seriesType + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + */ + function barLayoutPolar(seriesType, ecModel, api) { + + var width = api.getWidth(); + var height = api.getHeight(); + + var lastStackCoords = {}; + + var barWidthAndOffset = calRadialBar( + filter( + ecModel.getSeriesByType(seriesType), + function(seriesModel) { + return !ecModel.isSeriesFiltered(seriesModel) && + seriesModel.coordinateSystem && + seriesModel.coordinateSystem.type === 'polar'; + } + ) + ); + + ecModel.eachSeriesByType(seriesType, function(seriesModel) { + // Check series coordinate, do layout for polar only + if (seriesModel.coordinateSystem.type !== 'polar') { + return; + } + + var data = seriesModel.getData(); + var polar = seriesModel.coordinateSystem; + var baseAxis = polar.getBaseAxis(); + + var stackId = getSeriesStackId$1(seriesModel); + var columnLayoutInfo = barWidthAndOffset[getAxisKey$1(baseAxis)][stackId]; + var columnOffset = columnLayoutInfo.offset; + var columnWidth = columnLayoutInfo.width; + var valueAxis = polar.getOtherAxis(baseAxis); + + var center = seriesModel.get('center') || ['50%', '50%']; + var cx = parsePercent$1(center[0], width); + var cy = parsePercent$1(center[1], height); + + var barMinHeight = seriesModel.get('barMinHeight') || 0; + var barMinAngle = seriesModel.get('barMinAngle') || 0; + + lastStackCoords[stackId] = lastStackCoords[stackId] || []; + + var valueDim = data.mapDimension(valueAxis.dim); + var baseDim = data.mapDimension(baseAxis.dim); + var stacked = isDimensionStacked(data, valueDim /*, baseDim*/ ); + + var valueAxisStart = valueAxis.getExtent()[0]; + + for (var idx = 0, len = data.count(); idx < len; idx++) { + var value = data.get(valueDim, idx); + var baseValue = data.get(baseDim, idx); + + if (isNaN(value)) { + continue; + } + + var sign = value >= 0 ? 'p' : 'n'; + var baseCoord = valueAxisStart; + + // Because of the barMinHeight, we can not use the value in + // stackResultDimension directly. + // Only ordinal axis can be stacked. + if (stacked) { + if (!lastStackCoords[stackId][baseValue]) { + lastStackCoords[stackId][baseValue] = { + p: valueAxisStart, // Positive stack + n: valueAxisStart // Negative stack + }; + } + // Should also consider #4243 + baseCoord = lastStackCoords[stackId][baseValue][sign]; + } + + var r0; + var r; + var startAngle; + var endAngle; + + // radial sector + if (valueAxis.dim === 'radius') { + var radiusSpan = valueAxis.dataToRadius(value) - valueAxisStart; + var angle = baseAxis.dataToAngle(baseValue); + + if (Math.abs(radiusSpan) < barMinHeight) { + radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight; + } + + r0 = baseCoord; + r = baseCoord + radiusSpan; + startAngle = angle - columnOffset; + endAngle = startAngle - columnWidth; + + stacked && (lastStackCoords[stackId][baseValue][sign] = r); + } + // tangential sector + else { + // angleAxis must be clamped. + var angleSpan = valueAxis.dataToAngle(value, true) - valueAxisStart; + var radius = baseAxis.dataToRadius(baseValue); + + if (Math.abs(angleSpan) < barMinAngle) { + angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle; + } + + r0 = radius + columnOffset; + r = r0 + columnWidth; + startAngle = baseCoord; + endAngle = baseCoord + angleSpan; + + // if the previous stack is at the end of the ring, + // add a round to differentiate it from origin + // var extent = angleAxis.getExtent(); + // var stackCoord = angle; + // if (stackCoord === extent[0] && value > 0) { + // stackCoord = extent[1]; + // } + // else if (stackCoord === extent[1] && value < 0) { + // stackCoord = extent[0]; + // } + stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle); + } + + data.setItemLayout(idx, { + cx: cx, + cy: cy, + r0: r0, + r: r, + // Consider that positive angle is anti-clockwise, + // while positive radian of sector is clockwise + startAngle: -startAngle * Math.PI / 180, + endAngle: -endAngle * Math.PI / 180 + }); + + } + + }, this); + + } + + /** + * Calculate bar width and offset for radial bar charts + */ + function calRadialBar(barSeries, api) { + // Columns info on each category axis. Key is polar name + var columnsMap = {}; + + each$1(barSeries, function(seriesModel, idx) { + var data = seriesModel.getData(); + var polar = seriesModel.coordinateSystem; + + var baseAxis = polar.getBaseAxis(); + + var axisExtent = baseAxis.getExtent(); + var bandWidth = baseAxis.type === 'category' ? + baseAxis.getBandWidth() : + (Math.abs(axisExtent[1] - axisExtent[0]) / data.count()); + + var columnsOnAxis = columnsMap[getAxisKey$1(baseAxis)] || { + bandWidth: bandWidth, + remainedWidth: bandWidth, + autoWidthCount: 0, + categoryGap: '20%', + gap: '30%', + stacks: {} + }; + var stacks = columnsOnAxis.stacks; + columnsMap[getAxisKey$1(baseAxis)] = columnsOnAxis; + + var stackId = getSeriesStackId$1(seriesModel); + + if (!stacks[stackId]) { + columnsOnAxis.autoWidthCount++; + } + stacks[stackId] = stacks[stackId] || { + width: 0, + maxWidth: 0 + }; + + var barWidth = parsePercent$1( + seriesModel.get('barWidth'), + bandWidth + ); + var barMaxWidth = parsePercent$1( + seriesModel.get('barMaxWidth'), + bandWidth + ); + var barGap = seriesModel.get('barGap'); + var barCategoryGap = seriesModel.get('barCategoryGap'); + + if (barWidth && !stacks[stackId].width) { + barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); + stacks[stackId].width = barWidth; + columnsOnAxis.remainedWidth -= barWidth; + } + + barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); + (barGap != null) && (columnsOnAxis.gap = barGap); + (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap); + }); + + + var result = {}; + + each$1(columnsMap, function(columnsOnAxis, coordSysName) { + + result[coordSysName] = {}; + + var stacks = columnsOnAxis.stacks; + var bandWidth = columnsOnAxis.bandWidth; + var categoryGap = parsePercent$1(columnsOnAxis.categoryGap, bandWidth); + var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1); + + var remainedWidth = columnsOnAxis.remainedWidth; + var autoWidthCount = columnsOnAxis.autoWidthCount; + var autoWidth = (remainedWidth - categoryGap) / + (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + + // Find if any auto calculated bar exceeded maxBarWidth + each$1(stacks, function(column, stack) { + var maxWidth = column.maxWidth; + if (maxWidth && maxWidth < autoWidth) { + maxWidth = Math.min(maxWidth, remainedWidth); + if (column.width) { + maxWidth = Math.min(maxWidth, column.width); + } + remainedWidth -= maxWidth; + column.width = maxWidth; + autoWidthCount--; + } + }); + + // Recalculate width again + autoWidth = (remainedWidth - categoryGap) / + (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + + var widthSum = 0; + var lastColumn; + each$1(stacks, function(column, idx) { + if (!column.width) { + column.width = autoWidth; + } + lastColumn = column; + widthSum += column.width * (1 + barGapPercent); + }); + if (lastColumn) { + widthSum -= lastColumn.width * barGapPercent; + } + + var offset = -widthSum / 2; + each$1(stacks, function(column, stackId) { + result[coordSysName][stackId] = result[coordSysName][stackId] || { + offset: offset, + width: column.width + }; + + offset += column.width * (1 + barGapPercent); + }); + }); + + return result; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function RadiusAxis(scale, radiusExtent) { + + Axis.call(this, 'radius', scale, radiusExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = 'category'; + } + + RadiusAxis.prototype = { + + constructor: RadiusAxis, + + /** + * @override + */ + pointToData: function(point, clamp) { + return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1]; + }, + + dataToRadius: Axis.prototype.dataToCoord, + + radiusToData: Axis.prototype.coordToData + }; + + inherits(RadiusAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function AngleAxis(scale, angleExtent) { + + angleExtent = angleExtent || [0, 360]; + + Axis.call(this, 'angle', scale, angleExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = 'category'; + } + + AngleAxis.prototype = { + + constructor: AngleAxis, + + /** + * @override + */ + pointToData: function(point, clamp) { + return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1]; + }, + + dataToAngle: Axis.prototype.dataToCoord, + + angleToData: Axis.prototype.coordToData + }; + + inherits(AngleAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @module echarts/coord/polar/Polar + */ + + /** + * @alias {module:echarts/coord/polar/Polar} + * @constructor + * @param {string} name + */ + var Polar = function(name) { + + /** + * @type {string} + */ + this.name = name || ''; + + /** + * x of polar center + * @type {number} + */ + this.cx = 0; + + /** + * y of polar center + * @type {number} + */ + this.cy = 0; + + /** + * @type {module:echarts/coord/polar/RadiusAxis} + * @private + */ + this._radiusAxis = new RadiusAxis(); + + /** + * @type {module:echarts/coord/polar/AngleAxis} + * @private + */ + this._angleAxis = new AngleAxis(); + + this._radiusAxis.polar = this._angleAxis.polar = this; + }; + + Polar.prototype = { + + type: 'polar', + + axisPointerEnabled: true, + + constructor: Polar, + + /** + * @param {Array.} + * @readOnly + */ + dimensions: ['radius', 'angle'], + + /** + * @type {module:echarts/coord/PolarModel} + */ + model: null, + + /** + * If contain coord + * @param {Array.} point + * @return {boolean} + */ + containPoint: function(point) { + var coord = this.pointToCoord(point); + return this._radiusAxis.contain(coord[0]) && + this._angleAxis.contain(coord[1]); + }, + + /** + * If contain data + * @param {Array.} data + * @return {boolean} + */ + containData: function(data) { + return this._radiusAxis.containData(data[0]) && + this._angleAxis.containData(data[1]); + }, + + /** + * @param {string} dim + * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + */ + getAxis: function(dim) { + return this['_' + dim + 'Axis']; + }, + + /** + * @return {Array.} + */ + getAxes: function() { + return [this._radiusAxis, this._angleAxis]; + }, + + /** + * Get axes by type of scale + * @param {string} scaleType + * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + */ + getAxesByScale: function(scaleType) { + var axes = []; + var angleAxis = this._angleAxis; + var radiusAxis = this._radiusAxis; + angleAxis.scale.type === scaleType && axes.push(angleAxis); + radiusAxis.scale.type === scaleType && axes.push(radiusAxis); + + return axes; + }, + + /** + * @return {module:echarts/coord/polar/AngleAxis} + */ + getAngleAxis: function() { + return this._angleAxis; + }, + + /** + * @return {module:echarts/coord/polar/RadiusAxis} + */ + getRadiusAxis: function() { + return this._radiusAxis; + }, + + /** + * @param {module:echarts/coord/polar/Axis} + * @return {module:echarts/coord/polar/Axis} + */ + getOtherAxis: function(axis) { + var angleAxis = this._angleAxis; + return axis === angleAxis ? this._radiusAxis : angleAxis; + }, + + /** + * Base axis will be used on stacking. + * + * @return {module:echarts/coord/polar/Axis} + */ + getBaseAxis: function() { + return this.getAxesByScale('ordinal')[0] || + this.getAxesByScale('time')[0] || + this.getAngleAxis(); + }, + + /** + * @param {string} [dim] 'radius' or 'angle' or 'auto' or null/undefined + * @return {Object} {baseAxes: [], otherAxes: []} + */ + getTooltipAxes: function(dim) { + var baseAxis = (dim != null && dim !== 'auto') ? + this.getAxis(dim) : this.getBaseAxis(); + return { + baseAxes: [baseAxis], + otherAxes: [this.getOtherAxis(baseAxis)] + }; + }, + + /** + * Convert a single data item to (x, y) point. + * Parameter data is an array which the first element is radius and the second is angle + * @param {Array.} data + * @param {boolean} [clamp=false] + * @return {Array.} + */ + dataToPoint: function(data, clamp) { + return this.coordToPoint([ + this._radiusAxis.dataToRadius(data[0], clamp), + this._angleAxis.dataToAngle(data[1], clamp) + ]); + }, + + /** + * Convert a (x, y) point to data + * @param {Array.} point + * @param {boolean} [clamp=false] + * @return {Array.} + */ + pointToData: function(point, clamp) { + var coord = this.pointToCoord(point); + return [ + this._radiusAxis.radiusToData(coord[0], clamp), + this._angleAxis.angleToData(coord[1], clamp) + ]; + }, + + /** + * Convert a (x, y) point to (radius, angle) coord + * @param {Array.} point + * @return {Array.} + */ + pointToCoord: function(point) { + var dx = point[0] - this.cx; + var dy = point[1] - this.cy; + var angleAxis = this.getAngleAxis(); + var extent = angleAxis.getExtent(); + var minAngle = Math.min(extent[0], extent[1]); + var maxAngle = Math.max(extent[0], extent[1]); + // Fix fixed extent in polarCreator + // FIXME + angleAxis.inverse ? + (minAngle = maxAngle - 360) : + (maxAngle = minAngle + 360); + + var radius = Math.sqrt(dx * dx + dy * dy); + dx /= radius; + dy /= radius; + + var radian = Math.atan2(-dy, dx) / Math.PI * 180; + + // move to angleExtent + var dir = radian < minAngle ? 1 : -1; + while (radian < minAngle || radian > maxAngle) { + radian += dir * 360; + } + + return [radius, radian]; + }, + + /** + * Convert a (radius, angle) coord to (x, y) point + * @param {Array.} coord + * @return {Array.} + */ + coordToPoint: function(coord) { + var radius = coord[0]; + var radian = coord[1] / 180 * Math.PI; + var x = Math.cos(radian) * radius + this.cx; + // Inverse the y + var y = -Math.sin(radian) * radius + this.cy; + + return [x, y]; + } + + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PolarAxisModel = ComponentModel.extend({ + + type: 'polarAxis', + + /** + * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + */ + axis: null, + + /** + * @override + */ + getCoordSysModel: function() { + return this.ecModel.queryComponents({ + mainType: 'polar', + index: this.option.polarIndex, + id: this.option.polarId + })[0]; + } + + }); + + merge(PolarAxisModel.prototype, axisModelCommonMixin); + + var polarAxisDefaultExtendedOption = { + angle: { + // polarIndex: 0, + // polarId: '', + + startAngle: 90, + + clockwise: true, + + splitNumber: 12, + + axisLabel: { + rotate: false + } + }, + radius: { + // polarIndex: 0, + // polarId: '', + + splitNumber: 5 + } + }; + + function getAxisType$3(axisDim, option) { + // Default axis with data is category axis + return option.type || (option.data ? 'category' : 'value'); + } + + axisModelCreator('angle', PolarAxisModel, getAxisType$3, polarAxisDefaultExtendedOption.angle); + axisModelCreator('radius', PolarAxisModel, getAxisType$3, polarAxisDefaultExtendedOption.radius); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentModel({ + + type: 'polar', + + dependencies: ['polarAxis', 'angleAxis'], + + /** + * @type {module:echarts/coord/polar/Polar} + */ + coordinateSystem: null, + + /** + * @param {string} axisType + * @return {module:echarts/coord/polar/AxisModel} + */ + findAxisModel: function(axisType) { + var foundAxisModel; + var ecModel = this.ecModel; + + ecModel.eachComponent(axisType, function(axisModel) { + if (axisModel.getCoordSysModel() === this) { + foundAxisModel = axisModel; + } + }, this); + return foundAxisModel; + }, + + defaultOption: { + + zlevel: 0, + + z: 0, + + center: ['50%', '50%'], + + radius: '80%' + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO Axis scale + + /** + * Resize method bound to the polar + * @param {module:echarts/coord/polar/PolarModel} polarModel + * @param {module:echarts/ExtensionAPI} api + */ + function resizePolar(polar, polarModel, api) { + var center = polarModel.get('center'); + var width = api.getWidth(); + var height = api.getHeight(); + + polar.cx = parsePercent$1(center[0], width); + polar.cy = parsePercent$1(center[1], height); + + var radiusAxis = polar.getRadiusAxis(); + var size = Math.min(width, height) / 2; + var radius = parsePercent$1(polarModel.get('radius'), size); + radiusAxis.inverse ? + radiusAxis.setExtent(radius, 0) : + radiusAxis.setExtent(0, radius); + } + + /** + * Update polar + */ + function updatePolarScale(ecModel, api) { + var polar = this; + var angleAxis = polar.getAngleAxis(); + var radiusAxis = polar.getRadiusAxis(); + // Reset scale + angleAxis.scale.setExtent(Infinity, -Infinity); + radiusAxis.scale.setExtent(Infinity, -Infinity); + + ecModel.eachSeries(function(seriesModel) { + if (seriesModel.coordinateSystem === polar) { + var data = seriesModel.getData(); + each$1(data.mapDimension('radius', true), function(dim) { + radiusAxis.scale.unionExtentFromData( + data, getStackedDimension(data, dim) + ); + }); + each$1(data.mapDimension('angle', true), function(dim) { + angleAxis.scale.unionExtentFromData( + data, getStackedDimension(data, dim) + ); + }); + } + }); + + niceScaleExtent(angleAxis.scale, angleAxis.model); + niceScaleExtent(radiusAxis.scale, radiusAxis.model); + + // Fix extent of category angle axis + if (angleAxis.type === 'category' && !angleAxis.onBand) { + var extent = angleAxis.getExtent(); + var diff = 360 / angleAxis.scale.count(); + angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff); + angleAxis.setExtent(extent[0], extent[1]); + } + } + + /** + * Set common axis properties + * @param {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + * @param {module:echarts/coord/polar/AxisModel} + * @inner + */ + function setAxis(axis, axisModel) { + axis.type = axisModel.get('type'); + axis.scale = createScaleByModel(axisModel); + axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category'; + axis.inverse = axisModel.get('inverse'); + + if (axisModel.mainType === 'angleAxis') { + axis.inverse ^= axisModel.get('clockwise'); + var startAngle = axisModel.get('startAngle'); + axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360)); + } + + // Inject axis instance + axisModel.axis = axis; + axis.model = axisModel; + } + + + var polarCreator = { + + dimensions: Polar.prototype.dimensions, + + create: function(ecModel, api) { + var polarList = []; + ecModel.eachComponent('polar', function(polarModel, idx) { + var polar = new Polar(idx); + // Inject resize and update method + polar.update = updatePolarScale; + + var radiusAxis = polar.getRadiusAxis(); + var angleAxis = polar.getAngleAxis(); + + var radiusAxisModel = polarModel.findAxisModel('radiusAxis'); + var angleAxisModel = polarModel.findAxisModel('angleAxis'); + + setAxis(radiusAxis, radiusAxisModel); + setAxis(angleAxis, angleAxisModel); + + resizePolar(polar, polarModel, api); + + polarList.push(polar); + + polarModel.coordinateSystem = polar; + polar.model = polarModel; + }); + // Inject coordinateSystem to series + ecModel.eachSeries(function(seriesModel) { + if (seriesModel.get('coordinateSystem') === 'polar') { + var polarModel = ecModel.queryComponents({ + mainType: 'polar', + index: seriesModel.get('polarIndex'), + id: seriesModel.get('polarId') + })[0]; + + if (__DEV__) { + if (!polarModel) { + throw new Error( + 'Polar "' + retrieve( + seriesModel.get('polarIndex'), + seriesModel.get('polarId'), + 0 + ) + '" not found' + ); + } + } + seriesModel.coordinateSystem = polarModel.coordinateSystem; + } + }); + + return polarList; + } + }; + + CoordinateSystemManager.register('polar', polarCreator); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea']; + + function getAxisLineShape(polar, rExtent, angle) { + rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse()); + var start = polar.coordToPoint([rExtent[0], angle]); + var end = polar.coordToPoint([rExtent[1], angle]); + + return { + x1: start[0], + y1: start[1], + x2: end[0], + y2: end[1] + }; + } + + function getRadiusIdx(polar) { + var radiusAxis = polar.getRadiusAxis(); + return radiusAxis.inverse ? 0 : 1; + } + + // Remove the last tick which will overlap the first tick + function fixAngleOverlap(list) { + var firstItem = list[0]; + var lastItem = list[list.length - 1]; + if (firstItem && + lastItem && + Math.abs(Math.abs(firstItem.coord - lastItem.coord) - 360) < 1e-4 + ) { + list.pop(); + } + } + + AxisView.extend({ + + type: 'angleAxis', + + axisPointerClass: 'PolarAxisPointer', + + render: function(angleAxisModel, ecModel) { + this.group.removeAll(); + if (!angleAxisModel.get('show')) { + return; + } + + var angleAxis = angleAxisModel.axis; + var polar = angleAxis.polar; + var radiusExtent = polar.getRadiusAxis().getExtent(); + + var ticksAngles = angleAxis.getTicksCoords(); + var labels = map(angleAxis.getViewLabels(), function(labelItem) { + var labelItem = clone(labelItem); + labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue); + return labelItem; + }); + + fixAngleOverlap(labels); + fixAngleOverlap(ticksAngles); + + each$1(elementList$1, function(name) { + if (angleAxisModel.get(name + '.show') && + (!angleAxis.scale.isBlank() || name === 'axisLine') + ) { + this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent, labels); + } + }, this); + }, + + /** + * @private + */ + _axisLine: function(angleAxisModel, polar, ticksAngles, radiusExtent) { + var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle'); + + var circle = new Circle({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: radiusExtent[getRadiusIdx(polar)] + }, + style: lineStyleModel.getLineStyle(), + z2: 1, + silent: true + }); + circle.style.fill = null; + + this.group.add(circle); + }, + + /** + * @private + */ + _axisTick: function(angleAxisModel, polar, ticksAngles, radiusExtent) { + var tickModel = angleAxisModel.getModel('axisTick'); + + var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length'); + var radius = radiusExtent[getRadiusIdx(polar)]; + + var lines = map(ticksAngles, function(tickAngleItem) { + return new Line({ + shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord) + }); + }); + this.group.add(mergePath( + lines, { + style: defaults( + tickModel.getModel('lineStyle').getLineStyle(), { + stroke: angleAxisModel.get('axisLine.lineStyle.color') + } + ) + } + )); + }, + + /** + * @private + */ + _axisLabel: function(angleAxisModel, polar, ticksAngles, radiusExtent, labels) { + var rawCategoryData = angleAxisModel.getCategories(true); + + var commonLabelModel = angleAxisModel.getModel('axisLabel'); + + var labelMargin = commonLabelModel.get('margin'); + + // Use length of ticksAngles because it may remove the last tick to avoid overlapping + each$1(labels, function(labelItem, idx) { + var labelModel = commonLabelModel; + var tickValue = labelItem.tickValue; + + var r = radiusExtent[getRadiusIdx(polar)]; + var p = polar.coordToPoint([r + labelMargin, labelItem.coord]); + var cx = polar.cx; + var cy = polar.cy; + + var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3 ? + 'center' : (p[0] > cx ? 'left' : 'right'); + var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3 ? + 'middle' : (p[1] > cy ? 'top' : 'bottom'); + + if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) { + labelModel = new Model(rawCategoryData[tickValue].textStyle, commonLabelModel, commonLabelModel.ecModel); + } + + var textEl = new Text({ + silent: true + }); + this.group.add(textEl); + setTextStyle(textEl.style, labelModel, { + x: p[0], + y: p[1], + textFill: labelModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'), + text: labelItem.formattedLabel, + textAlign: labelTextAlign, + textVerticalAlign: labelTextVerticalAlign + }); + }, this); + }, + + /** + * @private + */ + _splitLine: function(angleAxisModel, polar, ticksAngles, radiusExtent) { + var splitLineModel = angleAxisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + var lineCount = 0; + + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + + var splitLines = []; + + for (var i = 0; i < ticksAngles.length; i++) { + var colorIndex = (lineCount++) % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new Line({ + shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord) + })); + } + + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitLines.length; i++) { + this.group.add(mergePath(splitLines[i], { + style: defaults({ + stroke: lineColors[i % lineColors.length] + }, lineStyleModel.getLineStyle()), + silent: true, + z: angleAxisModel.get('z') + })); + } + }, + + /** + * @private + */ + _splitArea: function(angleAxisModel, polar, ticksAngles, radiusExtent) { + if (!ticksAngles.length) { + return; + } + + var splitAreaModel = angleAxisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + var lineCount = 0; + + areaColors = areaColors instanceof Array ? areaColors : [areaColors]; + + var splitAreas = []; + + var RADIAN = Math.PI / 180; + var prevAngle = -ticksAngles[0].coord * RADIAN; + var r0 = Math.min(radiusExtent[0], radiusExtent[1]); + var r1 = Math.max(radiusExtent[0], radiusExtent[1]); + + var clockwise = angleAxisModel.get('clockwise'); + + for (var i = 1; i < ticksAngles.length; i++) { + var colorIndex = (lineCount++) % areaColors.length; + splitAreas[colorIndex] = splitAreas[colorIndex] || []; + splitAreas[colorIndex].push(new Sector({ + shape: { + cx: polar.cx, + cy: polar.cy, + r0: r0, + r: r1, + startAngle: prevAngle, + endAngle: -ticksAngles[i].coord * RADIAN, + clockwise: clockwise + }, + silent: true + })); + prevAngle = -ticksAngles[i].coord * RADIAN; + } + + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitAreas.length; i++) { + this.group.add(mergePath(splitAreas[i], { + style: defaults({ + fill: areaColors[i % areaColors.length] + }, areaStyleModel.getAreaStyle()), + silent: true + })); + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var axisBuilderAttrs$3 = [ + 'axisLine', 'axisTickLabel', 'axisName' + ]; + var selfBuilderAttrs$1 = [ + 'splitLine', 'splitArea' + ]; + + AxisView.extend({ + + type: 'radiusAxis', + + axisPointerClass: 'PolarAxisPointer', + + render: function(radiusAxisModel, ecModel) { + this.group.removeAll(); + if (!radiusAxisModel.get('show')) { + return; + } + var radiusAxis = radiusAxisModel.axis; + var polar = radiusAxis.polar; + var angleAxis = polar.getAngleAxis(); + var ticksCoords = radiusAxis.getTicksCoords(); + var axisAngle = angleAxis.getExtent()[0]; + var radiusExtent = radiusAxis.getExtent(); + + var layout = layoutAxis(polar, radiusAxisModel, axisAngle); + var axisBuilder = new AxisBuilder(radiusAxisModel, layout); + each$1(axisBuilderAttrs$3, axisBuilder.add, axisBuilder); + this.group.add(axisBuilder.getGroup()); + + each$1(selfBuilderAttrs$1, function(name) { + if (radiusAxisModel.get(name + '.show') && !radiusAxis.scale.isBlank()) { + this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords); + } + }, this); + }, + + /** + * @private + */ + _splitLine: function(radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) { + var splitLineModel = radiusAxisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + var lineCount = 0; + + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + + var splitLines = []; + + for (var i = 0; i < ticksCoords.length; i++) { + var colorIndex = (lineCount++) % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new Circle({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: ticksCoords[i].coord + }, + silent: true + })); + } + + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitLines.length; i++) { + this.group.add(mergePath(splitLines[i], { + style: defaults({ + stroke: lineColors[i % lineColors.length], + fill: null + }, lineStyleModel.getLineStyle()), + silent: true + })); + } + }, + + /** + * @private + */ + _splitArea: function(radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) { + if (!ticksCoords.length) { + return; + } + + var splitAreaModel = radiusAxisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + var lineCount = 0; + + areaColors = areaColors instanceof Array ? areaColors : [areaColors]; + + var splitAreas = []; + + var prevRadius = ticksCoords[0].coord; + for (var i = 1; i < ticksCoords.length; i++) { + var colorIndex = (lineCount++) % areaColors.length; + splitAreas[colorIndex] = splitAreas[colorIndex] || []; + splitAreas[colorIndex].push(new Sector({ + shape: { + cx: polar.cx, + cy: polar.cy, + r0: prevRadius, + r: ticksCoords[i].coord, + startAngle: 0, + endAngle: Math.PI * 2 + }, + silent: true + })); + prevRadius = ticksCoords[i].coord; + } + + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitAreas.length; i++) { + this.group.add(mergePath(splitAreas[i], { + style: defaults({ + fill: areaColors[i % areaColors.length] + }, areaStyleModel.getAreaStyle()), + silent: true + })); + } + } + }); + + /** + * @inner + */ + function layoutAxis(polar, radiusAxisModel, axisAngle) { + return { + position: [polar.cx, polar.cy], + rotation: axisAngle / 180 * Math.PI, + labelDirection: -1, + tickDirection: -1, + nameDirection: 1, + labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'), + // Over splitLine and splitArea + z2: 1 + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PolarAxisPointer = BaseAxisPointer.extend({ + + /** + * @override + */ + makeElOption: function(elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + + if (axis.dim === 'angle') { + this.animationThreshold = Math.PI / 18; + } + + var polar = axis.polar; + var otherAxis = polar.getOtherAxis(axis); + var otherExtent = otherAxis.getExtent(); + + var coordValue; + coordValue = axis['dataTo' + capitalFirst(axis.dim)](value); + + var axisPointerType = axisPointerModel.get('type'); + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder$2[axisPointerType]( + axis, polar, coordValue, otherExtent, elStyle + ); + pointerOption.style = elStyle; + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + + var labelMargin = axisPointerModel.get('label.margin'); + var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin); + buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos); + } + + // Do not support handle, utill any user requires it. + + }); + + function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) { + var axis = axisModel.axis; + var coord = axis.dataToCoord(value); + var axisAngle = polar.getAngleAxis().getExtent()[0]; + axisAngle = axisAngle / 180 * Math.PI; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var position; + var align; + var verticalAlign; + + if (axis.dim === 'radius') { + var transform = create$1(); + rotate(transform, transform, axisAngle); + translate(transform, transform, [polar.cx, polar.cy]); + position = applyTransform$1([coord, -labelMargin], transform); + + var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0; + var labelLayout = AxisBuilder.innerTextLayout( + axisAngle, labelRotation * Math.PI / 180, -1 + ); + align = labelLayout.textAlign; + verticalAlign = labelLayout.textVerticalAlign; + } else { // angle axis + var r = radiusExtent[1]; + position = polar.coordToPoint([r + labelMargin, coord]); + var cx = polar.cx; + var cy = polar.cy; + align = Math.abs(position[0] - cx) / r < 0.3 ? + 'center' : (position[0] > cx ? 'left' : 'right'); + verticalAlign = Math.abs(position[1] - cy) / r < 0.3 ? + 'middle' : (position[1] > cy ? 'top' : 'bottom'); + } + + return { + position: position, + align: align, + verticalAlign: verticalAlign + }; + } + + + var pointerShapeBuilder$2 = { + + line: function(axis, polar, coordValue, otherExtent, elStyle) { + return axis.dim === 'angle' ? + { + type: 'Line', + shape: makeLineShape( + polar.coordToPoint([otherExtent[0], coordValue]), + polar.coordToPoint([otherExtent[1], coordValue]) + ) + } : + { + type: 'Circle', + shape: { + cx: polar.cx, + cy: polar.cy, + r: coordValue + } + }; + }, + + shadow: function(axis, polar, coordValue, otherExtent, elStyle) { + var bandWidth = Math.max(1, axis.getBandWidth()); + var radian = Math.PI / 180; + + return axis.dim === 'angle' ? + { + type: 'Sector', + shape: makeSectorShape( + polar.cx, polar.cy, + otherExtent[0], otherExtent[1], + // In ECharts y is negative if angle is positive + (-coordValue - bandWidth / 2) * radian, + (-coordValue + bandWidth / 2) * radian + ) + } : + { + type: 'Sector', + shape: makeSectorShape( + polar.cx, polar.cy, + coordValue - bandWidth / 2, + coordValue + bandWidth / 2, + 0, Math.PI * 2 + ) + }; + } + }; + + AxisView.registerAxisPointerClass('PolarAxisPointer', PolarAxisPointer); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // For reducing size of echarts.min, barLayoutPolar is required by polar. + registerLayout(curry(barLayoutPolar, 'bar')); + + // Polar view + extendComponentView({ + type: 'polar' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var GeoModel = ComponentModel.extend({ + + type: 'geo', + + /** + * @type {module:echarts/coord/geo/Geo} + */ + coordinateSystem: null, + + layoutMode: 'box', + + init: function(option) { + ComponentModel.prototype.init.apply(this, arguments); + + // Default label emphasis `show` + defaultEmphasis(option, 'label', ['show']); + }, + + optionUpdated: function() { + var option = this.option; + var self = this; + + option.regions = geoCreator.getFilledRegions(option.regions, option.map, option.nameMap); + + this._optionModelMap = reduce(option.regions || [], function(optionModelMap, regionOpt) { + if (regionOpt.name) { + optionModelMap.set(regionOpt.name, new Model(regionOpt, self)); + } + return optionModelMap; + }, createHashMap()); + + this.updateSelectedMap(option.regions); + }, + + defaultOption: { + + zlevel: 0, + + z: 0, + + show: true, + + left: 'center', + + top: 'center', + + + // width:, + // height:, + // right + // bottom + + // Aspect is width / height. Inited to be geoJson bbox aspect + // This parameter is used for scale this aspect + aspectScale: 0.75, + + ///// Layout with center and size + // If you wan't to put map in a fixed size box with right aspect ratio + // This two properties may more conveninet + // layoutCenter: [50%, 50%] + // layoutSize: 100 + + + silent: false, + + // Map type + map: '', + + // Define left-top, right-bottom coords to control view + // For example, [ [180, 90], [-180, -90] ] + boundingCoords: null, + + // Default on center of map + center: null, + + zoom: 1, + + scaleLimit: null, + + // selectedMode: false + + label: { + show: false, + color: '#000' + }, + + itemStyle: { + // color: 各异, + borderWidth: 0.5, + borderColor: '#444', + color: '#eee' + }, + + emphasis: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + color: 'rgba(255,215,0,0.8)' + } + }, + + regions: [] + }, + + /** + * Get model of region + * @param {string} name + * @return {module:echarts/model/Model} + */ + getRegionModel: function(name) { + return this._optionModelMap.get(name) || new Model(null, this, this.ecModel); + }, + + /** + * Format label + * @param {string} name Region name + * @param {string} [status='normal'] 'normal' or 'emphasis' + * @return {string} + */ + getFormattedLabel: function(name, status) { + var regionModel = this.getRegionModel(name); + var formatter = regionModel.get('label.' + status + '.formatter'); + var params = { + name: name + }; + if (typeof formatter === 'function') { + params.status = status; + return formatter(params); + } else if (typeof formatter === 'string') { + return formatter.replace('{a}', name != null ? name : ''); + } + }, + + setZoom: function(zoom) { + this.option.zoom = zoom; + }, + + setCenter: function(center) { + this.option.center = center; + } + }); + + mixin(GeoModel, selectableMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentView({ + + type: 'geo', + + init: function(ecModel, api) { + var mapDraw = new MapDraw(api, true); + this._mapDraw = mapDraw; + + this.group.add(mapDraw.group); + }, + + render: function(geoModel, ecModel, api, payload) { + // Not render if it is an toggleSelect action from self + if (payload && payload.type === 'geoToggleSelect' && + payload.from === this.uid + ) { + return; + } + + var mapDraw = this._mapDraw; + if (geoModel.get('show')) { + mapDraw.draw(geoModel, ecModel, api, this, payload); + } else { + this._mapDraw.group.removeAll(); + } + + this.group.silent = geoModel.get('silent'); + }, + + dispose: function() { + this._mapDraw && this._mapDraw.remove(); + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function makeAction(method, actionInfo) { + actionInfo.update = 'updateView'; + registerAction(actionInfo, function(payload, ecModel) { + var selected = {}; + + ecModel.eachComponent({ + mainType: 'geo', + query: payload + }, + function(geoModel) { + geoModel[method](payload.name); + var geo = geoModel.coordinateSystem; + each$1(geo.regions, function(region) { + selected[region.name] = geoModel.isSelected(region.name) || false; + }); + } + ); + + return { + selected: selected, + name: payload.name + }; + }); + } + + makeAction('toggleSelected', { + type: 'geoToggleSelect', + event: 'geoselectchanged' + }); + makeAction('select', { + type: 'geoSelect', + event: 'geoselected' + }); + makeAction('unSelect', { + type: 'geoUnSelect', + event: 'geounselected' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var DEFAULT_TOOLBOX_BTNS = ['rect', 'polygon', 'keep', 'clear']; + + var preprocessor$1 = function(option, isNew) { + var brushComponents = option && option.brush; + if (!isArray(brushComponents)) { + brushComponents = brushComponents ? [brushComponents] : []; + } + + if (!brushComponents.length) { + return; + } + + var brushComponentSpecifiedBtns = []; + + each$1(brushComponents, function(brushOpt) { + var tbs = brushOpt.hasOwnProperty('toolbox') ? + brushOpt.toolbox : []; + + if (tbs instanceof Array) { + brushComponentSpecifiedBtns = brushComponentSpecifiedBtns.concat(tbs); + } + }); + + var toolbox = option && option.toolbox; + + if (isArray(toolbox)) { + toolbox = toolbox[0]; + } + if (!toolbox) { + toolbox = { + feature: {} + }; + option.toolbox = [toolbox]; + } + + var toolboxFeature = (toolbox.feature || (toolbox.feature = {})); + var toolboxBrush = toolboxFeature.brush || (toolboxFeature.brush = {}); + var brushTypes = toolboxBrush.type || (toolboxBrush.type = []); + + brushTypes.push.apply(brushTypes, brushComponentSpecifiedBtns); + + removeDuplicate(brushTypes); + + if (isNew && !brushTypes.length) { + brushTypes.push.apply(brushTypes, DEFAULT_TOOLBOX_BTNS); + } + }; + + function removeDuplicate(arr) { + var map$$1 = {}; + each$1(arr, function(val) { + map$$1[val] = 1; + }); + arr.length = 0; + each$1(map$$1, function(flag, val) { + arr.push(val); + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Visual solution, for consistent option specification. + */ + + var each$19 = each$1; + + function hasKeys(obj) { + if (obj) { + for (var name in obj) { + if (obj.hasOwnProperty(name)) { + return true; + } + } + } + } + + /** + * @param {Object} option + * @param {Array.} stateList + * @param {Function} [supplementVisualOption] + * @return {Object} visualMappings > + */ + function createVisualMappings(option, stateList, supplementVisualOption) { + var visualMappings = {}; + + each$19(stateList, function(state) { + var mappings = visualMappings[state] = createMappings(); + + each$19(option[state], function(visualData, visualType) { + if (!VisualMapping.isValidType(visualType)) { + return; + } + var mappingOption = { + type: visualType, + visual: visualData + }; + supplementVisualOption && supplementVisualOption(mappingOption, state); + mappings[visualType] = new VisualMapping(mappingOption); + + // Prepare a alpha for opacity, for some case that opacity + // is not supported, such as rendering using gradient color. + if (visualType === 'opacity') { + mappingOption = clone(mappingOption); + mappingOption.type = 'colorAlpha'; + mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption); + } + }); + }); + + return visualMappings; + + function createMappings() { + var Creater = function() {}; + // Make sure hidden fields will not be visited by + // object iteration (with hasOwnProperty checking). + Creater.prototype.__hidden = Creater.prototype; + var obj = new Creater(); + return obj; + } + } + + /** + * @param {Object} thisOption + * @param {Object} newOption + * @param {Array.} keys + */ + function replaceVisualOption(thisOption, newOption, keys) { + // Visual attributes merge is not supported, otherwise it + // brings overcomplicated merge logic. See #2853. So if + // newOption has anyone of these keys, all of these keys + // will be reset. Otherwise, all keys remain. + var has; + each$1(keys, function(key) { + if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { + has = true; + } + }); + has && each$1(keys, function(key) { + if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { + thisOption[key] = clone(newOption[key]); + } else { + delete thisOption[key]; + } + }); + } + + /** + * @param {Array.} stateList + * @param {Object} visualMappings > + * @param {module:echarts/data/List} list + * @param {Function} getValueState param: valueOrIndex, return: state. + * @param {object} [scope] Scope for getValueState + * @param {string} [dimension] Concrete dimension, if used. + */ + // ???! handle brush? + function applyVisual(stateList, visualMappings, data, getValueState, scope, dimension) { + var visualTypesMap = {}; + each$1(stateList, function(state) { + var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); + visualTypesMap[state] = visualTypes; + }); + + var dataIndex; + + function getVisual(key) { + return data.getItemVisual(dataIndex, key); + } + + function setVisual(key, value) { + data.setItemVisual(dataIndex, key, value); + } + + if (dimension == null) { + data.each(eachItem); + } else { + data.each([dimension], eachItem); + } + + function eachItem(valueOrIndex, index) { + dataIndex = dimension == null ? valueOrIndex : index; + + var rawDataItem = data.getRawDataItem(dataIndex); + // Consider performance + if (rawDataItem && rawDataItem.visualMap === false) { + return; + } + + var valueState = getValueState.call(scope, valueOrIndex); + var mappings = visualMappings[valueState]; + var visualTypes = visualTypesMap[valueState]; + + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + mappings[type] && mappings[type].applyVisual( + valueOrIndex, getVisual, setVisual + ); + } + } + } + + /** + * @param {module:echarts/data/List} data + * @param {Array.} stateList + * @param {Object} visualMappings > + * @param {Function} getValueState param: valueOrIndex, return: state. + * @param {number} [dim] dimension or dimension index. + */ + function incrementalApplyVisual(stateList, visualMappings, getValueState, dim) { + var visualTypesMap = {}; + each$1(stateList, function(state) { + var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); + visualTypesMap[state] = visualTypes; + }); + + function progress(params, data) { + if (dim != null) { + dim = data.getDimension(dim); + } + + function getVisual(key) { + return data.getItemVisual(dataIndex, key); + } + + function setVisual(key, value) { + data.setItemVisual(dataIndex, key, value); + } + + var dataIndex; + while ((dataIndex = params.next()) != null) { + var rawDataItem = data.getRawDataItem(dataIndex); + + // Consider performance + if (rawDataItem && rawDataItem.visualMap === false) { + return; + } + + var value = dim != null ? + data.get(dim, dataIndex, true) : + dataIndex; + + var valueState = getValueState(value); + var mappings = visualMappings[valueState]; + var visualTypes = visualTypesMap[valueState]; + + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual); + } + } + } + + return { + progress: progress + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Key of the first level is brushType: `line`, `rect`, `polygon`. + // Key of the second level is chart element type: `point`, `rect`. + // See moudule:echarts/component/helper/BrushController + // function param: + // {Object} itemLayout fetch from data.getItemLayout(dataIndex) + // {Object} selectors {point: selector, rect: selector, ...} + // {Object} area {range: [[], [], ..], boudingRect} + // function return: + // {boolean} Whether in the given brush. + var selector = { + lineX: getLineSelectors(0), + lineY: getLineSelectors(1), + rect: { + point: function(itemLayout, selectors, area) { + return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]); + }, + rect: function(itemLayout, selectors, area) { + return itemLayout && area.boundingRect.intersect(itemLayout); + } + }, + polygon: { + point: function(itemLayout, selectors, area) { + return itemLayout && + area.boundingRect.contain(itemLayout[0], itemLayout[1]) && + contain$1(area.range, itemLayout[0], itemLayout[1]); + }, + rect: function(itemLayout, selectors, area) { + var points = area.range; + + if (!itemLayout || points.length <= 1) { + return false; + } + + var x = itemLayout.x; + var y = itemLayout.y; + var width = itemLayout.width; + var height = itemLayout.height; + var p = points[0]; + + if (contain$1(points, x, y) || + contain$1(points, x + width, y) || + contain$1(points, x, y + height) || + contain$1(points, x + width, y + height) || + BoundingRect.create(itemLayout).contain(p[0], p[1]) || + lineIntersectPolygon(x, y, x + width, y, points) || + lineIntersectPolygon(x, y, x, y + height, points) || + lineIntersectPolygon(x + width, y, x + width, y + height, points) || + lineIntersectPolygon(x, y + height, x + width, y + height, points) + ) { + return true; + } + } + } + }; + + function getLineSelectors(xyIndex) { + var xy = ['x', 'y']; + var wh = ['width', 'height']; + + return { + point: function(itemLayout, selectors, area) { + if (itemLayout) { + var range = area.range; + var p = itemLayout[xyIndex]; + return inLineRange(p, range); + } + }, + rect: function(itemLayout, selectors, area) { + if (itemLayout) { + var range = area.range; + var layoutRange = [ + itemLayout[xy[xyIndex]], + itemLayout[xy[xyIndex]] + itemLayout[wh[xyIndex]] + ]; + layoutRange[1] < layoutRange[0] && layoutRange.reverse(); + return inLineRange(layoutRange[0], range) || + inLineRange(layoutRange[1], range) || + inLineRange(range[0], layoutRange) || + inLineRange(range[1], layoutRange); + } + } + }; + } + + function inLineRange(p, range) { + return range[0] <= p && p <= range[1]; + } + + function lineIntersectPolygon(lx, ly, l2x, l2y, points) { + for (var i = 0, p2 = points[points.length - 1]; i < points.length; i++) { + var p = points[i]; + if (lineIntersect(lx, ly, l2x, l2y, p[0], p[1], p2[0], p2[1])) { + return true; + } + p2 = p; + } + } + + // Code from with some fix. + // See + function lineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) { + var delta = determinant(a2x - a1x, b1x - b2x, a2y - a1y, b1y - b2y); + if (nearZero(delta)) { // parallel + return false; + } + var namenda = determinant(b1x - a1x, b1x - b2x, b1y - a1y, b1y - b2y) / delta; + if (namenda < 0 || namenda > 1) { + return false; + } + var miu = determinant(a2x - a1x, b1x - a1x, a2y - a1y, b1y - a1y) / delta; + if (miu < 0 || miu > 1) { + return false; + } + return true; + } + + function nearZero(val) { + return val <= (1e-6) && val >= -(1e-6); + } + + function determinant(v1, v2, v3, v4) { + return v1 * v4 - v2 * v3; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$20 = each$1; + var indexOf$1 = indexOf; + var curry$5 = curry; + + var COORD_CONVERTS = ['dataToPoint', 'pointToData']; + + // FIXME + // how to genarialize to more coordinate systems. + var INCLUDE_FINDER_MAIN_TYPES = [ + 'grid', 'xAxis', 'yAxis', 'geo', 'graph', + 'polar', 'radiusAxis', 'angleAxis', 'bmap' + ]; + + /** + * [option in constructor]: + * { + * Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder. + * } + * + * + * [targetInfo]: + * + * There can be multiple axes in a single targetInfo. Consider the case + * of `grid` component, a targetInfo represents a grid which contains one or more + * cartesian and one or more axes. And consider the case of parallel system, + * which has multiple axes in a coordinate system. + * Can be { + * panelId: ..., + * coordSys: , + * coordSyses: all cartesians. + * gridModel: + * xAxes: correspond to coordSyses on index + * yAxes: correspond to coordSyses on index + * } + * or { + * panelId: ..., + * coordSys: + * coordSyses: [] + * geoModel: + * } + * + * + * [panelOpt]: + * + * Make from targetInfo. Input to BrushController. + * { + * panelId: ..., + * rect: ... + * } + * + * + * [area]: + * + * Generated by BrushController or user input. + * { + * panelId: Used to locate coordInfo directly. If user inpput, no panelId. + * brushType: determine how to convert to/from coord('rect' or 'polygon' or 'lineX/Y'). + * Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder. + * range: pixel range. + * coordRange: representitive coord range (the first one of coordRanges). + * coordRanges: coord ranges, used in multiple cartesian in one grid. + * } + */ + + /** + * @param {Object} option contains Index/Id/Name of xAxis/yAxis/geo/grid + * Each can be {number|Array.}. like: {xAxisIndex: [3, 4]} + * @param {module:echarts/model/Global} ecModel + * @param {Object} [opt] + * @param {Array.} [opt.include] include coordinate system types. + */ + function BrushTargetManager(option, ecModel, opt) { + /** + * @private + * @type {Array.} + */ + var targetInfoList = this._targetInfoList = []; + var info = {}; + var foundCpts = parseFinder$1(ecModel, option); + + each$20(targetInfoBuilders, function(builder, type) { + if (!opt || !opt.include || indexOf$1(opt.include, type) >= 0) { + builder(foundCpts, targetInfoList, info); + } + }); + } + + var proto$2 = BrushTargetManager.prototype; + + proto$2.setOutputRanges = function(areas, ecModel) { + this.matchOutputRanges(areas, ecModel, function(area, coordRange, coordSys) { + (area.coordRanges || (area.coordRanges = [])).push(coordRange); + // area.coordRange is the first of area.coordRanges + if (!area.coordRange) { + area.coordRange = coordRange; + // In 'category' axis, coord to pixel is not reversible, so we can not + // rebuild range by coordRange accrately, which may bring trouble when + // brushing only one item. So we use __rangeOffset to rebuilding range + // by coordRange. And this it only used in brush component so it is no + // need to be adapted to coordRanges. + var result = coordConvert[area.brushType](0, coordSys, coordRange); + area.__rangeOffset = { + offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]), + xyMinMax: result.xyMinMax + }; + } + }); + }; + + proto$2.matchOutputRanges = function(areas, ecModel, cb) { + each$20(areas, function(area) { + var targetInfo = this.findTargetInfo(area, ecModel); + + if (targetInfo && targetInfo !== true) { + each$1( + targetInfo.coordSyses, + function(coordSys) { + var result = coordConvert[area.brushType](1, coordSys, area.range); + cb(area, result.values, coordSys, ecModel); + } + ); + } + }, this); + }; + + proto$2.setInputRanges = function(areas, ecModel) { + each$20(areas, function(area) { + var targetInfo = this.findTargetInfo(area, ecModel); + + if (__DEV__) { + assert$1( + !targetInfo || targetInfo === true || area.coordRange, + 'coordRange must be specified when coord index specified.' + ); + assert$1( + !targetInfo || targetInfo !== true || area.range, + 'range must be specified in global brush.' + ); + } + + area.range = area.range || []; + + // convert coordRange to global range and set panelId. + if (targetInfo && targetInfo !== true) { + area.panelId = targetInfo.panelId; + // (1) area.range shoule always be calculate from coordRange but does + // not keep its original value, for the sake of the dataZoom scenario, + // where area.coordRange remains unchanged but area.range may be changed. + // (2) Only support converting one coordRange to pixel range in brush + // component. So do not consider `coordRanges`. + // (3) About __rangeOffset, see comment above. + var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange); + var rangeOffset = area.__rangeOffset; + area.range = rangeOffset ? + diffProcessor[area.brushType]( + result.values, + rangeOffset.offset, + getScales(result.xyMinMax, rangeOffset.xyMinMax) + ) : + result.values; + } + }, this); + }; + + proto$2.makePanelOpts = function(api, getDefaultBrushType) { + return map(this._targetInfoList, function(targetInfo) { + var rect = targetInfo.getPanelRect(); + return { + panelId: targetInfo.panelId, + defaultBrushType: getDefaultBrushType && getDefaultBrushType(targetInfo), + clipPath: makeRectPanelClipPath(rect), + isTargetByCursor: makeRectIsTargetByCursor( + rect, api, targetInfo.coordSysModel + ), + getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect) + }; + }); + }; + + proto$2.controlSeries = function(area, seriesModel, ecModel) { + // Check whether area is bound in coord, and series do not belong to that coord. + // If do not do this check, some brush (like lineX) will controll all axes. + var targetInfo = this.findTargetInfo(area, ecModel); + return targetInfo === true || ( + targetInfo && indexOf$1(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0 + ); + }; + + /** + * If return Object, a coord found. + * If reutrn true, global found. + * Otherwise nothing found. + * + * @param {Object} area + * @param {Array} targetInfoList + * @return {Object|boolean} + */ + proto$2.findTargetInfo = function(area, ecModel) { + var targetInfoList = this._targetInfoList; + var foundCpts = parseFinder$1(ecModel, area); + + for (var i = 0; i < targetInfoList.length; i++) { + var targetInfo = targetInfoList[i]; + var areaPanelId = area.panelId; + if (areaPanelId) { + if (targetInfo.panelId === areaPanelId) { + return targetInfo; + } + } else { + for (var i = 0; i < targetInfoMatchers.length; i++) { + if (targetInfoMatchers[i](foundCpts, targetInfo)) { + return targetInfo; + } + } + } + } + + return true; + }; + + function formatMinMax(minMax) { + minMax[0] > minMax[1] && minMax.reverse(); + return minMax; + } + + function parseFinder$1(ecModel, option) { + return parseFinder( + ecModel, option, { + includeMainTypes: INCLUDE_FINDER_MAIN_TYPES + } + ); + } + + var targetInfoBuilders = { + + grid: function(foundCpts, targetInfoList) { + var xAxisModels = foundCpts.xAxisModels; + var yAxisModels = foundCpts.yAxisModels; + var gridModels = foundCpts.gridModels; + // Remove duplicated. + var gridModelMap = createHashMap(); + var xAxesHas = {}; + var yAxesHas = {}; + + if (!xAxisModels && !yAxisModels && !gridModels) { + return; + } + + each$20(xAxisModels, function(axisModel) { + var gridModel = axisModel.axis.grid.model; + gridModelMap.set(gridModel.id, gridModel); + xAxesHas[gridModel.id] = true; + }); + each$20(yAxisModels, function(axisModel) { + var gridModel = axisModel.axis.grid.model; + gridModelMap.set(gridModel.id, gridModel); + yAxesHas[gridModel.id] = true; + }); + each$20(gridModels, function(gridModel) { + gridModelMap.set(gridModel.id, gridModel); + xAxesHas[gridModel.id] = true; + yAxesHas[gridModel.id] = true; + }); + + gridModelMap.each(function(gridModel) { + var grid = gridModel.coordinateSystem; + var cartesians = []; + + each$20(grid.getCartesians(), function(cartesian, index) { + if (indexOf$1(xAxisModels, cartesian.getAxis('x').model) >= 0 || + indexOf$1(yAxisModels, cartesian.getAxis('y').model) >= 0 + ) { + cartesians.push(cartesian); + } + }); + targetInfoList.push({ + panelId: 'grid--' + gridModel.id, + gridModel: gridModel, + coordSysModel: gridModel, + // Use the first one as the representitive coordSys. + coordSys: cartesians[0], + coordSyses: cartesians, + getPanelRect: panelRectBuilder.grid, + xAxisDeclared: xAxesHas[gridModel.id], + yAxisDeclared: yAxesHas[gridModel.id] + }); + }); + }, + + geo: function(foundCpts, targetInfoList) { + each$20(foundCpts.geoModels, function(geoModel) { + var coordSys = geoModel.coordinateSystem; + targetInfoList.push({ + panelId: 'geo--' + geoModel.id, + geoModel: geoModel, + coordSysModel: geoModel, + coordSys: coordSys, + coordSyses: [coordSys], + getPanelRect: panelRectBuilder.geo + }); + }); + } + }; + + var targetInfoMatchers = [ + + // grid + function(foundCpts, targetInfo) { + var xAxisModel = foundCpts.xAxisModel; + var yAxisModel = foundCpts.yAxisModel; + var gridModel = foundCpts.gridModel; + + !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model); + !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model); + + return gridModel && gridModel === targetInfo.gridModel; + }, + + // geo + function(foundCpts, targetInfo) { + var geoModel = foundCpts.geoModel; + return geoModel && geoModel === targetInfo.geoModel; + } + ]; + + var panelRectBuilder = { + + grid: function() { + // grid is not Transformable. + return this.coordSys.grid.getRect().clone(); + }, + + geo: function() { + var coordSys = this.coordSys; + var rect = coordSys.getBoundingRect().clone(); + // geo roam and zoom transform + rect.applyTransform(getTransform(coordSys)); + return rect; + } + }; + + var coordConvert = { + + lineX: curry$5(axisConvert, 0), + + lineY: curry$5(axisConvert, 1), + + rect: function(to, coordSys, rangeOrCoordRange) { + var xminymin = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]]); + var xmaxymax = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]]); + var values = [ + formatMinMax([xminymin[0], xmaxymax[0]]), + formatMinMax([xminymin[1], xmaxymax[1]]) + ]; + return { + values: values, + xyMinMax: values + }; + }, + + polygon: function(to, coordSys, rangeOrCoordRange) { + var xyMinMax = [ + [Infinity, -Infinity], + [Infinity, -Infinity] + ]; + var values = map(rangeOrCoordRange, function(item) { + var p = coordSys[COORD_CONVERTS[to]](item); + xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]); + xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]); + xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]); + xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]); + return p; + }); + return { + values: values, + xyMinMax: xyMinMax + }; + } + }; + + function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) { + if (__DEV__) { + assert$1( + coordSys.type === 'cartesian2d', + 'lineX/lineY brush is available only in cartesian2d.' + ); + } + + var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]); + var values = formatMinMax(map([0, 1], function(i) { + return to ? + axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i])) : + axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i])); + })); + var xyMinMax = []; + xyMinMax[axisNameIndex] = values; + xyMinMax[1 - axisNameIndex] = [NaN, NaN]; + + return { + values: values, + xyMinMax: xyMinMax + }; + } + + var diffProcessor = { + lineX: curry$5(axisDiffProcessor, 0), + + lineY: curry$5(axisDiffProcessor, 1), + + rect: function(values, refer, scales) { + return [ + [values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], + [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]] + ]; + }, + + polygon: function(values, refer, scales) { + return map(values, function(item, idx) { + return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]]; + }); + } + }; + + function axisDiffProcessor(axisNameIndex, values, refer, scales) { + return [ + values[0] - scales[axisNameIndex] * refer[0], + values[1] - scales[axisNameIndex] * refer[1] + ]; + } + + // We have to process scale caused by dataZoom manually, + // although it might be not accurate. + function getScales(xyMinMaxCurr, xyMinMaxOrigin) { + var sizeCurr = getSize(xyMinMaxCurr); + var sizeOrigin = getSize(xyMinMaxOrigin); + var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]]; + isNaN(scales[0]) && (scales[0] = 1); + isNaN(scales[1]) && (scales[1] = 1); + return scales; + } + + function getSize(xyMinMax) { + return xyMinMax ? + [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : + [NaN, NaN]; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var STATE_LIST = ['inBrush', 'outOfBrush']; + var DISPATCH_METHOD = '__ecBrushSelect'; + var DISPATCH_FLAG = '__ecInBrushSelectEvent'; + var PRIORITY_BRUSH = PRIORITY.VISUAL.BRUSH; + + /** + * Layout for visual, the priority higher than other layout, and before brush visual. + */ + registerLayout(PRIORITY_BRUSH, function(ecModel, api, payload) { + ecModel.eachComponent({ + mainType: 'brush' + }, function(brushModel) { + + payload && payload.type === 'takeGlobalCursor' && brushModel.setBrushOption( + payload.key === 'brush' ? payload.brushOption : { + brushType: false + } + ); + + var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel); + + brushTargetManager.setInputRanges(brushModel.areas, ecModel); + }); + }); + + /** + * Register the visual encoding if this modules required. + */ + registerVisual(PRIORITY_BRUSH, function(ecModel, api, payload) { + + var brushSelected = []; + var throttleType; + var throttleDelay; + + ecModel.eachComponent({ + mainType: 'brush' + }, function(brushModel, brushIndex) { + + var thisBrushSelected = { + brushId: brushModel.id, + brushIndex: brushIndex, + brushName: brushModel.name, + areas: clone(brushModel.areas), + selected: [] + }; + // Every brush component exists in event params, convenient + // for user to find by index. + brushSelected.push(thisBrushSelected); + + var brushOption = brushModel.option; + var brushLink = brushOption.brushLink; + var linkedSeriesMap = []; + var selectedDataIndexForLink = []; + var rangeInfoBySeries = []; + var hasBrushExists = 0; + + if (!brushIndex) { // Only the first throttle setting works. + throttleType = brushOption.throttleType; + throttleDelay = brushOption.throttleDelay; + } + + // Add boundingRect and selectors to range. + var areas = map(brushModel.areas, function(area) { + return bindSelector( + defaults({ + boundingRect: boundingRectBuilders[area.brushType](area) + }, + area + ) + ); + }); + + var visualMappings = createVisualMappings( + brushModel.option, STATE_LIST, + function(mappingOption) { + mappingOption.mappingMethod = 'fixed'; + } + ); + + isArray(brushLink) && each$1(brushLink, function(seriesIndex) { + linkedSeriesMap[seriesIndex] = 1; + }); + + function linkOthers(seriesIndex) { + return brushLink === 'all' || linkedSeriesMap[seriesIndex]; + } + + // If no supported brush or no brush on the series, + // all visuals should be in original state. + function brushed(rangeInfoList) { + return !!rangeInfoList.length; + } + + /** + * Logic for each series: (If the logic has to be modified one day, do it carefully!) + * + * ( brushed ┬ && ┬hasBrushExist ┬ && linkOthers ) => StepA: ┬record, ┬ StepB: ┬visualByRecord. + * !brushed┘ ├hasBrushExist ┤ └nothing,┘ ├visualByRecord. + * └!hasBrushExist┘ └nothing. + * ( !brushed && ┬hasBrushExist ┬ && linkOthers ) => StepA: nothing, StepB: ┬visualByRecord. + * └!hasBrushExist┘ └nothing. + * ( brushed ┬ && !linkOthers ) => StepA: nothing, StepB: ┬visualByCheck. + * !brushed┘ └nothing. + * ( !brushed && !linkOthers ) => StepA: nothing, StepB: nothing. + */ + + // Step A + ecModel.eachSeries(function(seriesModel, seriesIndex) { + var rangeInfoList = rangeInfoBySeries[seriesIndex] = []; + + seriesModel.subType === 'parallel' ? + stepAParallel(seriesModel, seriesIndex, rangeInfoList) : + stepAOthers(seriesModel, seriesIndex, rangeInfoList); + }); + + function stepAParallel(seriesModel, seriesIndex) { + var coordSys = seriesModel.coordinateSystem; + hasBrushExists |= coordSys.hasAxisBrushed(); + + linkOthers(seriesIndex) && coordSys.eachActiveState( + seriesModel.getData(), + function(activeState, dataIndex) { + activeState === 'active' && (selectedDataIndexForLink[dataIndex] = 1); + } + ); + } + + function stepAOthers(seriesModel, seriesIndex, rangeInfoList) { + var selectorsByBrushType = getSelectorsByBrushType(seriesModel); + if (!selectorsByBrushType || brushModelNotControll(brushModel, seriesIndex)) { + return; + } + + each$1(areas, function(area) { + selectorsByBrushType[area.brushType] && + brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel) && + rangeInfoList.push(area); + hasBrushExists |= brushed(rangeInfoList); + }); + + if (linkOthers(seriesIndex) && brushed(rangeInfoList)) { + var data = seriesModel.getData(); + data.each(function(dataIndex) { + if (checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex)) { + selectedDataIndexForLink[dataIndex] = 1; + } + }); + } + } + + // Step B + ecModel.eachSeries(function(seriesModel, seriesIndex) { + var seriesBrushSelected = { + seriesId: seriesModel.id, + seriesIndex: seriesIndex, + seriesName: seriesModel.name, + dataIndex: [] + }; + // Every series exists in event params, convenient + // for user to find series by seriesIndex. + thisBrushSelected.selected.push(seriesBrushSelected); + + var selectorsByBrushType = getSelectorsByBrushType(seriesModel); + var rangeInfoList = rangeInfoBySeries[seriesIndex]; + + var data = seriesModel.getData(); + var getValueState = linkOthers(seriesIndex) ? + function(dataIndex) { + return selectedDataIndexForLink[dataIndex] ? + (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : + 'outOfBrush'; + } : + function(dataIndex) { + return checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex) ? + (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : + 'outOfBrush'; + }; + + // If no supported brush or no brush, all visuals are in original state. + (linkOthers(seriesIndex) ? hasBrushExists : brushed(rangeInfoList)) && + applyVisual( + STATE_LIST, visualMappings, data, getValueState + ); + }); + + }); + + dispatchAction(api, throttleType, throttleDelay, brushSelected, payload); + }); + + function dispatchAction(api, throttleType, throttleDelay, brushSelected, payload) { + // This event will not be triggered when `setOpion`, otherwise dead lock may + // triggered when do `setOption` in event listener, which we do not find + // satisfactory way to solve yet. Some considered resolutions: + // (a) Diff with prevoius selected data ant only trigger event when changed. + // But store previous data and diff precisely (i.e., not only by dataIndex, but + // also detect value changes in selected data) might bring complexity or fragility. + // (b) Use spectial param like `silent` to suppress event triggering. + // But such kind of volatile param may be weird in `setOption`. + if (!payload) { + return; + } + + var zr = api.getZr(); + if (zr[DISPATCH_FLAG]) { + return; + } + + if (!zr[DISPATCH_METHOD]) { + zr[DISPATCH_METHOD] = doDispatch; + } + + var fn = createOrUpdate(zr, DISPATCH_METHOD, throttleDelay, throttleType); + + fn(api, brushSelected); + } + + function doDispatch(api, brushSelected) { + if (!api.isDisposed()) { + var zr = api.getZr(); + zr[DISPATCH_FLAG] = true; + api.dispatchAction({ + type: 'brushSelect', + batch: brushSelected + }); + zr[DISPATCH_FLAG] = false; + } + } + + function checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex) { + for (var i = 0, len = rangeInfoList.length; i < len; i++) { + var area = rangeInfoList[i]; + if (selectorsByBrushType[area.brushType]( + dataIndex, data, area.selectors, area + )) { + return true; + } + } + } + + function getSelectorsByBrushType(seriesModel) { + var brushSelector = seriesModel.brushSelector; + if (isString(brushSelector)) { + var sels = []; + each$1(selector, function(selectorsByElementType, brushType) { + sels[brushType] = function(dataIndex, data, selectors, area) { + var itemLayout = data.getItemLayout(dataIndex); + return selectorsByElementType[brushSelector](itemLayout, selectors, area); + }; + }); + return sels; + } else if (isFunction$1(brushSelector)) { + var bSelector = {}; + each$1(selector, function(sel, brushType) { + bSelector[brushType] = brushSelector; + }); + return bSelector; + } + return brushSelector; + } + + function brushModelNotControll(brushModel, seriesIndex) { + var seriesIndices = brushModel.option.seriesIndex; + return seriesIndices != null && + seriesIndices !== 'all' && + ( + isArray(seriesIndices) ? + indexOf(seriesIndices, seriesIndex) < 0 : + seriesIndex !== seriesIndices + ); + } + + function bindSelector(area) { + var selectors = area.selectors = {}; + each$1(selector[area.brushType], function(selFn, elType) { + // Do not use function binding or curry for performance. + selectors[elType] = function(itemLayout) { + return selFn(itemLayout, selectors, area); + }; + }); + return area; + } + + var boundingRectBuilders = { + + lineX: noop, + + lineY: noop, + + rect: function(area) { + return getBoundingRectFromMinMax(area.range); + }, + + polygon: function(area) { + var minMax; + var range = area.range; + + for (var i = 0, len = range.length; i < len; i++) { + minMax = minMax || [ + [Infinity, -Infinity], + [Infinity, -Infinity] + ]; + var rg = range[i]; + rg[0] < minMax[0][0] && (minMax[0][0] = rg[0]); + rg[0] > minMax[0][1] && (minMax[0][1] = rg[0]); + rg[1] < minMax[1][0] && (minMax[1][0] = rg[1]); + rg[1] > minMax[1][1] && (minMax[1][1] = rg[1]); + } + + return minMax && getBoundingRectFromMinMax(minMax); + } + }; + + function getBoundingRectFromMinMax(minMax) { + return new BoundingRect( + minMax[0][0], + minMax[1][0], + minMax[0][1] - minMax[0][0], + minMax[1][1] - minMax[1][0] + ); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var DEFAULT_OUT_OF_BRUSH_COLOR = ['#ddd']; + + var BrushModel = extendComponentModel({ + + type: 'brush', + + dependencies: ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series'], + + /** + * @protected + */ + defaultOption: { + // inBrush: null, + // outOfBrush: null, + toolbox: null, // Default value see preprocessor. + brushLink: null, // Series indices array, broadcast using dataIndex. + // or 'all', which means all series. 'none' or null means no series. + seriesIndex: 'all', // seriesIndex array, specify series controlled by this brush component. + geoIndex: null, // + xAxisIndex: null, + yAxisIndex: null, + + brushType: 'rect', // Default brushType, see BrushController. + brushMode: 'single', // Default brushMode, 'single' or 'multiple' + transformable: true, // Default transformable. + brushStyle: { // Default brushStyle + borderWidth: 1, + color: 'rgba(120,140,180,0.3)', + borderColor: 'rgba(120,140,180,0.8)' + }, + + throttleType: 'fixRate', // Throttle in brushSelected event. 'fixRate' or 'debounce'. + // If null, no throttle. Valid only in the first brush component + throttleDelay: 0, // Unit: ms, 0 means every event will be triggered. + + // FIXME + // 试验效果 + removeOnClick: true, + + z: 10000 + }, + + /** + * @readOnly + * @type {Array.} + */ + areas: [], + + /** + * Current activated brush type. + * If null, brush is inactived. + * see module:echarts/component/helper/BrushController + * @readOnly + * @type {string} + */ + brushType: null, + + /** + * Current brush opt. + * see module:echarts/component/helper/BrushController + * @readOnly + * @type {Object} + */ + brushOption: {}, + + /** + * @readOnly + * @type {Array.} + */ + coordInfoList: [], + + optionUpdated: function(newOption, isInit) { + var thisOption = this.option; + + !isInit && replaceVisualOption( + thisOption, newOption, ['inBrush', 'outOfBrush'] + ); + + var inBrush = thisOption.inBrush = thisOption.inBrush || {}; + // Always give default visual, consider setOption at the second time. + thisOption.outOfBrush = thisOption.outOfBrush || { + color: DEFAULT_OUT_OF_BRUSH_COLOR + }; + + if (!inBrush.hasOwnProperty('liftZ')) { + // Bigger than the highlight z lift, otherwise it will + // be effected by the highlight z when brush. + inBrush.liftZ = 5; + } + }, + + /** + * If ranges is null/undefined, range state remain. + * + * @param {Array.} [ranges] + */ + setAreas: function(areas) { + if (__DEV__) { + assert$1(isArray(areas)); + each$1(areas, function(area) { + assert$1(area.brushType, 'Illegal areas'); + }); + } + + // If ranges is null/undefined, range state remain. + // This helps user to dispatchAction({type: 'brush'}) with no areas + // set but just want to get the current brush select info from a `brush` event. + if (!areas) { + return; + } + + this.areas = map(areas, function(area) { + return generateBrushOption(this.option, area); + }, this); + }, + + /** + * see module:echarts/component/helper/BrushController + * @param {Object} brushOption + */ + setBrushOption: function(brushOption) { + this.brushOption = generateBrushOption(this.option, brushOption); + this.brushType = this.brushOption.brushType; + } + + }); + + function generateBrushOption(option, brushOption) { + return merge({ + brushType: option.brushType, + brushMode: option.brushMode, + transformable: option.transformable, + brushStyle: new Model(option.brushStyle).getItemStyle(), + removeOnClick: option.removeOnClick, + z: option.z + }, + brushOption, + true + ); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentView({ + + type: 'brush', + + init: function(ecModel, api) { + + /** + * @readOnly + * @type {module:echarts/model/Global} + */ + this.ecModel = ecModel; + + /** + * @readOnly + * @type {module:echarts/ExtensionAPI} + */ + this.api = api; + + /** + * @readOnly + * @type {module:echarts/component/brush/BrushModel} + */ + this.model; + + /** + * @private + * @type {module:echarts/component/helper/BrushController} + */ + (this._brushController = new BrushController(api.getZr())) + .on('brush', bind(this._onBrush, this)) + .mount(); + }, + + /** + * @override + */ + render: function(brushModel) { + this.model = brushModel; + return updateController.apply(this, arguments); + }, + + /** + * @override + */ + updateTransform: updateController, + + /** + * @override + */ + updateView: updateController, + + // /** + // * @override + // */ + // updateLayout: updateController, + + // /** + // * @override + // */ + // updateVisual: updateController, + + /** + * @override + */ + dispose: function() { + this._brushController.dispose(); + }, + + /** + * @private + */ + _onBrush: function(areas, opt) { + var modelId = this.model.id; + + this.model.brushTargetManager.setOutputRanges(areas, this.ecModel); + + // Action is not dispatched on drag end, because the drag end + // emits the same params with the last drag move event, and + // may have some delay when using touch pad, which makes + // animation not smooth (when using debounce). + (!opt.isEnd || opt.removeOnClick) && this.api.dispatchAction({ + type: 'brush', + brushId: modelId, + areas: clone(areas), + $from: modelId + }); + } + + }); + + function updateController(brushModel, ecModel, api, payload) { + // Do not update controller when drawing. + (!payload || payload.$from !== brushModel.id) && this._brushController + .setPanels(brushModel.brushTargetManager.makePanelOpts(api)) + .enableBrush(brushModel.brushOption) + .updateCovers(brushModel.areas.slice()); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * payload: { + * brushIndex: number, or, + * brushId: string, or, + * brushName: string, + * globalRanges: Array + * } + */ + registerAction({ + type: 'brush', + event: 'brush' /*, update: 'updateView' */ + }, + function(payload, ecModel) { + ecModel.eachComponent({ + mainType: 'brush', + query: payload + }, function(brushModel) { + brushModel.setAreas(payload.areas); + }); + } + ); + + /** + * payload: { + * brushComponents: [ + * { + * brushId, + * brushIndex, + * brushName, + * series: [ + * { + * seriesId, + * seriesIndex, + * seriesName, + * rawIndices: [21, 34, ...] + * }, + * ... + * ] + * }, + * ... + * ] + * } + */ + registerAction({ + type: 'brushSelect', + event: 'brushSelected', + update: 'none' + }, + function() {} + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + var features = {}; + + function register$1(name, ctor) { + features[name] = ctor; + } + + function get$1(name) { + return features[name]; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var brushLang = lang.toolbox.brush; + + function Brush(model, ecModel, api) { + this.model = model; + this.ecModel = ecModel; + this.api = api; + + /** + * @private + * @type {string} + */ + this._brushType; + + /** + * @private + * @type {string} + */ + this._brushMode; + } + + Brush.defaultOption = { + show: true, + type: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'], + icon: { + rect: 'M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13', // jshint ignore:line + polygon: 'M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2', // jshint ignore:line + lineX: 'M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4', // jshint ignore:line + lineY: 'M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4', // jshint ignore:line + keep: 'M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z', // jshint ignore:line + clear: 'M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2' // jshint ignore:line + }, + // `rect`, `polygon`, `lineX`, `lineY`, `keep`, `clear` + title: clone(brushLang.title) + }; + + var proto$3 = Brush.prototype; + + // proto.updateLayout = function (featureModel, ecModel, api) { + proto$3.render = + proto$3.updateView = function(featureModel, ecModel, api) { + var brushType; + var brushMode; + var isBrushed; + + ecModel.eachComponent({ + mainType: 'brush' + }, function(brushModel) { + brushType = brushModel.brushType; + brushMode = brushModel.brushOption.brushMode || 'single'; + isBrushed |= brushModel.areas.length; + }); + this._brushType = brushType; + this._brushMode = brushMode; + + each$1(featureModel.get('type', true), function(type) { + featureModel.setIconStatus( + type, + ( + type === 'keep' ? + brushMode === 'multiple' : + type === 'clear' ? + isBrushed : + type === brushType + ) ? 'emphasis' : 'normal' + ); + }); + }; + + proto$3.getIcons = function() { + var model = this.model; + var availableIcons = model.get('icon', true); + var icons = {}; + each$1(model.get('type', true), function(type) { + if (availableIcons[type]) { + icons[type] = availableIcons[type]; + } + }); + return icons; + }; + + proto$3.onclick = function(ecModel, api, type) { + var brushType = this._brushType; + var brushMode = this._brushMode; + + if (type === 'clear') { + // Trigger parallel action firstly + api.dispatchAction({ + type: 'axisAreaSelect', + intervals: [] + }); + + api.dispatchAction({ + type: 'brush', + command: 'clear', + // Clear all areas of all brush components. + areas: [] + }); + } else { + api.dispatchAction({ + type: 'takeGlobalCursor', + key: 'brush', + brushOption: { + brushType: type === 'keep' ? + brushType : + (brushType === type ? false : type), + brushMode: type === 'keep' ? + (brushMode === 'multiple' ? 'single' : 'multiple') : + brushMode + } + }); + } + }; + + register$1('brush', Brush); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Brush component entry + */ + + registerPreprocessor(preprocessor$1); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // (24*60*60*1000) + var PROXIMATE_ONE_DAY = 86400000; + + /** + * Calendar + * + * @constructor + * + * @param {Object} calendarModel calendarModel + * @param {Object} ecModel ecModel + * @param {Object} api api + */ + function Calendar(calendarModel, ecModel, api) { + this._model = calendarModel; + } + + Calendar.prototype = { + + constructor: Calendar, + + type: 'calendar', + + dimensions: ['time', 'value'], + + // Required in createListFromData + getDimensionsInfo: function() { + return [{ + name: 'time', + type: 'time' + }, 'value']; + }, + + getRangeInfo: function() { + return this._rangeInfo; + }, + + getModel: function() { + return this._model; + }, + + getRect: function() { + return this._rect; + }, + + getCellWidth: function() { + return this._sw; + }, + + getCellHeight: function() { + return this._sh; + }, + + getOrient: function() { + return this._orient; + }, + + /** + * getFirstDayOfWeek + * + * @example + * 0 : start at Sunday + * 1 : start at Monday + * + * @return {number} + */ + getFirstDayOfWeek: function() { + return this._firstDayOfWeek; + }, + + /** + * get date info + * + * @param {string|number} date date + * @return {Object} + * { + * y: string, local full year, eg., '1940', + * m: string, local month, from '01' ot '12', + * d: string, local date, from '01' to '31' (if exists), + * day: It is not date.getDay(). It is the location of the cell in a week, from 0 to 6, + * time: timestamp, + * formatedDate: string, yyyy-MM-dd, + * date: original date object. + * } + */ + getDateInfo: function(date) { + + date = parseDate(date); + + var y = date.getFullYear(); + + var m = date.getMonth() + 1; + m = m < 10 ? '0' + m : m; + + var d = date.getDate(); + d = d < 10 ? '0' + d : d; + + var day = date.getDay(); + + day = Math.abs((day + 7 - this.getFirstDayOfWeek()) % 7); + + return { + y: y, + m: m, + d: d, + day: day, + time: date.getTime(), + formatedDate: y + '-' + m + '-' + d, + date: date + }; + }, + + getNextNDay: function(date, n) { + n = n || 0; + if (n === 0) { + return this.getDateInfo(date); + } + + date = new Date(this.getDateInfo(date).time); + date.setDate(date.getDate() + n); + + return this.getDateInfo(date); + }, + + update: function(ecModel, api) { + + this._firstDayOfWeek = +this._model.getModel('dayLabel').get('firstDay'); + this._orient = this._model.get('orient'); + this._lineWidth = this._model.getModel('itemStyle').getItemStyle().lineWidth || 0; + + + this._rangeInfo = this._getRangeInfo(this._initRangeOption()); + var weeks = this._rangeInfo.weeks || 1; + var whNames = ['width', 'height']; + var cellSize = this._model.get('cellSize').slice(); + var layoutParams = this._model.getBoxLayoutParams(); + var cellNumbers = this._orient === 'horizontal' ? [weeks, 7] : [7, weeks]; + + each$1([0, 1], function(idx) { + if (cellSizeSpecified(cellSize, idx)) { + layoutParams[whNames[idx]] = cellSize[idx] * cellNumbers[idx]; + } + }); + + var whGlobal = { + width: api.getWidth(), + height: api.getHeight() + }; + var calendarRect = this._rect = getLayoutRect(layoutParams, whGlobal); + + each$1([0, 1], function(idx) { + if (!cellSizeSpecified(cellSize, idx)) { + cellSize[idx] = calendarRect[whNames[idx]] / cellNumbers[idx]; + } + }); + + function cellSizeSpecified(cellSize, idx) { + return cellSize[idx] != null && cellSize[idx] !== 'auto'; + } + + this._sw = cellSize[0]; + this._sh = cellSize[1]; + }, + + + /** + * Convert a time data(time, value) item to (x, y) point. + * + * @override + * @param {Array|number} data data + * @param {boolean} [clamp=true] out of range + * @return {Array} point + */ + dataToPoint: function(data, clamp) { + isArray(data) && (data = data[0]); + clamp == null && (clamp = true); + + var dayInfo = this.getDateInfo(data); + var range = this._rangeInfo; + var date = dayInfo.formatedDate; + + // if not in range return [NaN, NaN] + if (clamp && !( + dayInfo.time >= range.start.time && + dayInfo.time < range.end.time + PROXIMATE_ONE_DAY + )) { + return [NaN, NaN]; + } + + var week = dayInfo.day; + var nthWeek = this._getRangeInfo([range.start.time, date]).nthWeek; + + if (this._orient === 'vertical') { + return [ + this._rect.x + week * this._sw + this._sw / 2, + this._rect.y + nthWeek * this._sh + this._sh / 2 + ]; + + } + + return [ + this._rect.x + nthWeek * this._sw + this._sw / 2, + this._rect.y + week * this._sh + this._sh / 2 + ]; + + }, + + /** + * Convert a (x, y) point to time data + * + * @override + * @param {string} point point + * @return {string} data + */ + pointToData: function(point) { + + var date = this.pointToDate(point); + + return date && date.time; + }, + + /** + * Convert a time date item to (x, y) four point. + * + * @param {Array} data date[0] is date + * @param {boolean} [clamp=true] out of range + * @return {Object} point + */ + dataToRect: function(data, clamp) { + var point = this.dataToPoint(data, clamp); + + return { + contentShape: { + x: point[0] - (this._sw - this._lineWidth) / 2, + y: point[1] - (this._sh - this._lineWidth) / 2, + width: this._sw - this._lineWidth, + height: this._sh - this._lineWidth + }, + + center: point, + + tl: [ + point[0] - this._sw / 2, + point[1] - this._sh / 2 + ], + + tr: [ + point[0] + this._sw / 2, + point[1] - this._sh / 2 + ], + + br: [ + point[0] + this._sw / 2, + point[1] + this._sh / 2 + ], + + bl: [ + point[0] - this._sw / 2, + point[1] + this._sh / 2 + ] + + }; + }, + + /** + * Convert a (x, y) point to time date + * + * @param {Array} point point + * @return {Object} date + */ + pointToDate: function(point) { + var nthX = Math.floor((point[0] - this._rect.x) / this._sw) + 1; + var nthY = Math.floor((point[1] - this._rect.y) / this._sh) + 1; + var range = this._rangeInfo.range; + + if (this._orient === 'vertical') { + return this._getDateByWeeksAndDay(nthY, nthX - 1, range); + } + + return this._getDateByWeeksAndDay(nthX, nthY - 1, range); + }, + + /** + * @inheritDoc + */ + convertToPixel: curry(doConvert$2, 'dataToPoint'), + + /** + * @inheritDoc + */ + convertFromPixel: curry(doConvert$2, 'pointToData'), + + /** + * initRange + * + * @private + * @return {Array} [start, end] + */ + _initRangeOption: function() { + var range = this._model.get('range'); + + var rg = range; + + if (isArray(rg) && rg.length === 1) { + rg = rg[0]; + } + + if (/^\d{4}$/.test(rg)) { + range = [rg + '-01-01', rg + '-12-31']; + } + + if (/^\d{4}[\/|-]\d{1,2}$/.test(rg)) { + + var start = this.getDateInfo(rg); + var firstDay = start.date; + firstDay.setMonth(firstDay.getMonth() + 1); + + var end = this.getNextNDay(firstDay, -1); + range = [start.formatedDate, end.formatedDate]; + } + + if (/^\d{4}[\/|-]\d{1,2}[\/|-]\d{1,2}$/.test(rg)) { + range = [rg, rg]; + } + + var tmp = this._getRangeInfo(range); + + if (tmp.start.time > tmp.end.time) { + range.reverse(); + } + + return range; + }, + + /** + * range info + * + * @private + * @param {Array} range range ['2017-01-01', '2017-07-08'] + * If range[0] > range[1], they will not be reversed. + * @return {Object} obj + */ + _getRangeInfo: function(range) { + range = [ + this.getDateInfo(range[0]), + this.getDateInfo(range[1]) + ]; + + var reversed; + if (range[0].time > range[1].time) { + reversed = true; + range.reverse(); + } + + var allDay = Math.floor(range[1].time / PROXIMATE_ONE_DAY) - + Math.floor(range[0].time / PROXIMATE_ONE_DAY) + 1; + + // Consider case: + // Firstly set system timezone as "Time Zone: America/Toronto", + // ``` + // var first = new Date(1478412000000 - 3600 * 1000 * 2.5); + // var second = new Date(1478412000000); + // var allDays = Math.floor(second / ONE_DAY) - Math.floor(first / ONE_DAY) + 1; + // ``` + // will get wrong result because of DST. So we should fix it. + var date = new Date(range[0].time); + var startDateNum = date.getDate(); + var endDateNum = range[1].date.getDate(); + date.setDate(startDateNum + allDay - 1); + // The bias can not over a month, so just compare date. + if (date.getDate() !== endDateNum) { + var sign = date.getTime() - range[1].time > 0 ? 1 : -1; + while (date.getDate() !== endDateNum && (date.getTime() - range[1].time) * sign > 0) { + allDay -= sign; + date.setDate(startDateNum + allDay - 1); + } + } + + var weeks = Math.floor((allDay + range[0].day + 6) / 7); + var nthWeek = reversed ? -weeks + 1 : weeks - 1; + + reversed && range.reverse(); + + return { + range: [range[0].formatedDate, range[1].formatedDate], + start: range[0], + end: range[1], + allDay: allDay, + weeks: weeks, + // From 0. + nthWeek: nthWeek, + fweek: range[0].day, + lweek: range[1].day + }; + }, + + /** + * get date by nthWeeks and week day in range + * + * @private + * @param {number} nthWeek the week + * @param {number} day the week day + * @param {Array} range [d1, d2] + * @return {Object} + */ + _getDateByWeeksAndDay: function(nthWeek, day, range) { + var rangeInfo = this._getRangeInfo(range); + + if (nthWeek > rangeInfo.weeks || + (nthWeek === 0 && day < rangeInfo.fweek) || + (nthWeek === rangeInfo.weeks && day > rangeInfo.lweek) + ) { + return false; + } + + var nthDay = (nthWeek - 1) * 7 - rangeInfo.fweek + day; + var date = new Date(rangeInfo.start.time); + date.setDate(rangeInfo.start.d + nthDay); + + return this.getDateInfo(date); + } + }; + + Calendar.dimensions = Calendar.prototype.dimensions; + + Calendar.getDimensionsInfo = Calendar.prototype.getDimensionsInfo; + + Calendar.create = function(ecModel, api) { + var calendarList = []; + + ecModel.eachComponent('calendar', function(calendarModel) { + var calendar = new Calendar(calendarModel, ecModel, api); + calendarList.push(calendar); + calendarModel.coordinateSystem = calendar; + }); + + ecModel.eachSeries(function(calendarSeries) { + if (calendarSeries.get('coordinateSystem') === 'calendar') { + // Inject coordinate system + calendarSeries.coordinateSystem = calendarList[calendarSeries.get('calendarIndex') || 0]; + } + }); + return calendarList; + }; + + function doConvert$2(methodName, ecModel, finder, value) { + var calendarModel = finder.calendarModel; + var seriesModel = finder.seriesModel; + + var coordSys = calendarModel ? + calendarModel.coordinateSystem : + seriesModel ? + seriesModel.coordinateSystem : + null; + + return coordSys === this ? coordSys[methodName](value) : null; + } + + CoordinateSystemManager.register('calendar', Calendar); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var CalendarModel = ComponentModel.extend({ + + type: 'calendar', + + /** + * @type {module:echarts/coord/calendar/Calendar} + */ + coordinateSystem: null, + + defaultOption: { + zlevel: 0, + z: 2, + left: 80, + top: 60, + + cellSize: 20, + + // horizontal vertical + orient: 'horizontal', + + // month separate line style + splitLine: { + show: true, + lineStyle: { + color: '#000', + width: 1, + type: 'solid' + } + }, + + // rect style temporarily unused emphasis + itemStyle: { + color: '#fff', + borderWidth: 1, + borderColor: '#ccc' + }, + + // week text style + dayLabel: { + show: true, + + // a week first day + firstDay: 0, + + // start end + position: 'start', + margin: '50%', // 50% of cellSize + nameMap: 'en', + color: '#000' + }, + + // month text style + monthLabel: { + show: true, + + // start end + position: 'start', + margin: 5, + + // center or left + align: 'center', + + // cn en [] + nameMap: 'en', + formatter: null, + color: '#000' + }, + + // year text style + yearLabel: { + show: true, + + // top bottom left right + position: null, + margin: 30, + formatter: null, + color: '#ccc', + fontFamily: 'sans-serif', + fontWeight: 'bolder', + fontSize: 20 + } + }, + + /** + * @override + */ + init: function(option, parentModel, ecModel, extraOpt) { + var inputPositionParams = getLayoutParams(option); + + CalendarModel.superApply(this, 'init', arguments); + + mergeAndNormalizeLayoutParams$1(option, inputPositionParams); + }, + + /** + * @override + */ + mergeOption: function(option, extraOpt) { + CalendarModel.superApply(this, 'mergeOption', arguments); + + mergeAndNormalizeLayoutParams$1(this.option, option); + } + }); + + function mergeAndNormalizeLayoutParams$1(target, raw) { + // Normalize cellSize + var cellSize = target.cellSize; + + if (!isArray(cellSize)) { + cellSize = target.cellSize = [cellSize, cellSize]; + } else if (cellSize.length === 1) { + cellSize[1] = cellSize[0]; + } + + var ignoreSize = map([0, 1], function(hvIdx) { + // If user have set `width` or both `left` and `right`, cellSize + // will be automatically set to 'auto', otherwise the default + // setting of cellSize will make `width` setting not work. + if (sizeCalculable(raw, hvIdx)) { + cellSize[hvIdx] = 'auto'; + } + return cellSize[hvIdx] != null && cellSize[hvIdx] !== 'auto'; + }); + + mergeLayoutParam(target, raw, { + type: 'box', + ignoreSize: ignoreSize + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var MONTH_TEXT = { + EN: [ + 'Jan', 'Feb', 'Mar', + 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec' + ], + CN: [ + '一月', '二月', '三月', + '四月', '五月', '六月', + '七月', '八月', '九月', + '十月', '十一月', '十二月' + ] + }; + + var WEEK_TEXT = { + EN: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], + CN: ['日', '一', '二', '三', '四', '五', '六'] + }; + + extendComponentView({ + + type: 'calendar', + + /** + * top/left line points + * @private + */ + _tlpoints: null, + + /** + * bottom/right line points + * @private + */ + _blpoints: null, + + /** + * first day of month + * @private + */ + _firstDayOfMonth: null, + + /** + * first day point of month + * @private + */ + _firstDayPoints: null, + + render: function(calendarModel, ecModel, api) { + + var group = this.group; + + group.removeAll(); + + var coordSys = calendarModel.coordinateSystem; + + // range info + var rangeData = coordSys.getRangeInfo(); + var orient = coordSys.getOrient(); + + this._renderDayRect(calendarModel, rangeData, group); + + // _renderLines must be called prior to following function + this._renderLines(calendarModel, rangeData, orient, group); + + this._renderYearText(calendarModel, rangeData, orient, group); + + this._renderMonthText(calendarModel, orient, group); + + this._renderWeekText(calendarModel, rangeData, orient, group); + }, + + // render day rect + _renderDayRect: function(calendarModel, rangeData, group) { + var coordSys = calendarModel.coordinateSystem; + var itemRectStyleModel = calendarModel.getModel('itemStyle').getItemStyle(); + var sw = coordSys.getCellWidth(); + var sh = coordSys.getCellHeight(); + + for (var i = rangeData.start.time; i <= rangeData.end.time; i = coordSys.getNextNDay(i, 1).time) { + + var point = coordSys.dataToRect([i], false).tl; + + // every rect + var rect = new Rect({ + shape: { + x: point[0], + y: point[1], + width: sw, + height: sh + }, + cursor: 'default', + style: itemRectStyleModel + }); + + group.add(rect); + } + + }, + + // render separate line + _renderLines: function(calendarModel, rangeData, orient, group) { + + var self = this; + + var coordSys = calendarModel.coordinateSystem; + + var lineStyleModel = calendarModel.getModel('splitLine.lineStyle').getLineStyle(); + var show = calendarModel.get('splitLine.show'); + + var lineWidth = lineStyleModel.lineWidth; + + this._tlpoints = []; + this._blpoints = []; + this._firstDayOfMonth = []; + this._firstDayPoints = []; + + + var firstDay = rangeData.start; + + for (var i = 0; firstDay.time <= rangeData.end.time; i++) { + addPoints(firstDay.formatedDate); + + if (i === 0) { + firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m); + } + + var date = firstDay.date; + date.setMonth(date.getMonth() + 1); + firstDay = coordSys.getDateInfo(date); + } + + addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate); + + function addPoints(date) { + + self._firstDayOfMonth.push(coordSys.getDateInfo(date)); + self._firstDayPoints.push(coordSys.dataToRect([date], false).tl); + + var points = self._getLinePointsOfOneWeek(calendarModel, date, orient); + + self._tlpoints.push(points[0]); + self._blpoints.push(points[points.length - 1]); + + show && self._drawSplitline(points, lineStyleModel, group); + } + + + // render top/left line + show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group); + + // render bottom/right line + show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group); + + }, + + // get points at both ends + _getEdgesPoints: function(points, lineWidth, orient) { + var rs = [points[0].slice(), points[points.length - 1].slice()]; + var idx = orient === 'horizontal' ? 0 : 1; + + // both ends of the line are extend half lineWidth + rs[0][idx] = rs[0][idx] - lineWidth / 2; + rs[1][idx] = rs[1][idx] + lineWidth / 2; + + return rs; + }, + + // render split line + _drawSplitline: function(points, lineStyleModel, group) { + + var poyline = new Polyline({ + z2: 20, + shape: { + points: points + }, + style: lineStyleModel + }); + + group.add(poyline); + }, + + // render month line of one week points + _getLinePointsOfOneWeek: function(calendarModel, date, orient) { + + var coordSys = calendarModel.coordinateSystem; + date = coordSys.getDateInfo(date); + + var points = []; + + for (var i = 0; i < 7; i++) { + + var tmpD = coordSys.getNextNDay(date.time, i); + var point = coordSys.dataToRect([tmpD.time], false); + + points[2 * tmpD.day] = point.tl; + points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr']; + } + + return points; + + }, + + _formatterLabel: function(formatter, params) { + + if (typeof formatter === 'string' && formatter) { + return formatTplSimple(formatter, params); + } + + if (typeof formatter === 'function') { + return formatter(params); + } + + return params.nameMap; + + }, + + _yearTextPositionControl: function(textEl, point, orient, position, margin) { + + point = point.slice(); + var aligns = ['center', 'bottom']; + + if (position === 'bottom') { + point[1] += margin; + aligns = ['center', 'top']; + } else if (position === 'left') { + point[0] -= margin; + } else if (position === 'right') { + point[0] += margin; + aligns = ['center', 'top']; + } else { // top + point[1] -= margin; + } + + var rotate = 0; + if (position === 'left' || position === 'right') { + rotate = Math.PI / 2; + } + + return { + rotation: rotate, + position: point, + style: { + textAlign: aligns[0], + textVerticalAlign: aligns[1] + } + }; + }, + + // render year + _renderYearText: function(calendarModel, rangeData, orient, group) { + var yearLabel = calendarModel.getModel('yearLabel'); + + if (!yearLabel.get('show')) { + return; + } + + var margin = yearLabel.get('margin'); + var pos = yearLabel.get('position'); + + if (!pos) { + pos = orient !== 'horizontal' ? 'top' : 'left'; + } + + var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]]; + var xc = (points[0][0] + points[1][0]) / 2; + var yc = (points[0][1] + points[1][1]) / 2; + + var idx = orient === 'horizontal' ? 0 : 1; + + var posPoints = { + top: [xc, points[idx][1]], + bottom: [xc, points[1 - idx][1]], + left: [points[1 - idx][0], yc], + right: [points[idx][0], yc] + }; + + var name = rangeData.start.y; + + if (+rangeData.end.y > +rangeData.start.y) { + name = name + '-' + rangeData.end.y; + } + + var formatter = yearLabel.get('formatter'); + + var params = { + start: rangeData.start.y, + end: rangeData.end.y, + nameMap: name + }; + + var content = this._formatterLabel(formatter, params); + + var yearText = new Text({ + z2: 30 + }); + setTextStyle(yearText.style, yearLabel, { + text: content + }), + yearText.attr(this._yearTextPositionControl(yearText, posPoints[pos], orient, pos, margin)); + + group.add(yearText); + }, + + _monthTextPositionControl: function(point, isCenter, orient, position, margin) { + var align = 'left'; + var vAlign = 'top'; + var x = point[0]; + var y = point[1]; + + if (orient === 'horizontal') { + y = y + margin; + + if (isCenter) { + align = 'center'; + } + + if (position === 'start') { + vAlign = 'bottom'; + } + } else { + x = x + margin; + + if (isCenter) { + vAlign = 'middle'; + } + + if (position === 'start') { + align = 'right'; + } + } + + return { + x: x, + y: y, + textAlign: align, + textVerticalAlign: vAlign + }; + }, + + // render month and year text + _renderMonthText: function(calendarModel, orient, group) { + var monthLabel = calendarModel.getModel('monthLabel'); + + if (!monthLabel.get('show')) { + return; + } + + var nameMap = monthLabel.get('nameMap'); + var margin = monthLabel.get('margin'); + var pos = monthLabel.get('position'); + var align = monthLabel.get('align'); + + var termPoints = [this._tlpoints, this._blpoints]; + + if (isString(nameMap)) { + nameMap = MONTH_TEXT[nameMap.toUpperCase()] || []; + } + + var idx = pos === 'start' ? 0 : 1; + var axis = orient === 'horizontal' ? 0 : 1; + margin = pos === 'start' ? -margin : margin; + var isCenter = (align === 'center'); + + for (var i = 0; i < termPoints[idx].length - 1; i++) { + + var tmp = termPoints[idx][i].slice(); + var firstDay = this._firstDayOfMonth[i]; + + if (isCenter) { + var firstDayPoints = this._firstDayPoints[i]; + tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2; + } + + var formatter = monthLabel.get('formatter'); + var name = nameMap[+firstDay.m - 1]; + var params = { + yyyy: firstDay.y, + yy: (firstDay.y + '').slice(2), + MM: firstDay.m, + M: +firstDay.m, + nameMap: name + }; + + var content = this._formatterLabel(formatter, params); + + var monthText = new Text({ + z2: 30 + }); + extend( + setTextStyle(monthText.style, monthLabel, { + text: content + }), + this._monthTextPositionControl(tmp, isCenter, orient, pos, margin) + ); + + group.add(monthText); + } + }, + + _weekTextPositionControl: function(point, orient, position, margin, cellSize) { + var align = 'center'; + var vAlign = 'middle'; + var x = point[0]; + var y = point[1]; + var isStart = position === 'start'; + + if (orient === 'horizontal') { + x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2; + align = isStart ? 'right' : 'left'; + } else { + y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2; + vAlign = isStart ? 'bottom' : 'top'; + } + + return { + x: x, + y: y, + textAlign: align, + textVerticalAlign: vAlign + }; + }, + + // render weeks + _renderWeekText: function(calendarModel, rangeData, orient, group) { + var dayLabel = calendarModel.getModel('dayLabel'); + + if (!dayLabel.get('show')) { + return; + } + + var coordSys = calendarModel.coordinateSystem; + var pos = dayLabel.get('position'); + var nameMap = dayLabel.get('nameMap'); + var margin = dayLabel.get('margin'); + var firstDayOfWeek = coordSys.getFirstDayOfWeek(); + + if (isString(nameMap)) { + nameMap = WEEK_TEXT[nameMap.toUpperCase()] || []; + } + + var start = coordSys.getNextNDay( + rangeData.end.time, (7 - rangeData.lweek) + ).time; + + var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()]; + margin = parsePercent$1(margin, cellSize[orient === 'horizontal' ? 0 : 1]); + + if (pos === 'start') { + start = coordSys.getNextNDay( + rangeData.start.time, -(7 + rangeData.fweek) + ).time; + margin = -margin; + } + + for (var i = 0; i < 7; i++) { + + var tmpD = coordSys.getNextNDay(start, i); + var point = coordSys.dataToRect([tmpD.time], false).center; + var day = i; + day = Math.abs((i + firstDayOfWeek) % 7); + var weekText = new Text({ + z2: 30 + }); + + extend( + setTextStyle(weekText.style, dayLabel, { + text: nameMap[day] + }), + this._weekTextPositionControl(point, orient, pos, margin, cellSize) + ); + group.add(weekText); + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file calendar.js + * @author dxh + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Model + extendComponentModel({ + + type: 'title', + + layoutMode: { + type: 'box', + ignoreSize: true + }, + + defaultOption: { + // 一级层叠 + zlevel: 0, + // 二级层叠 + z: 6, + show: true, + + text: '', + // 超链接跳转 + // link: null, + // 仅支持self | blank + target: 'blank', + subtext: '', + + // 超链接跳转 + // sublink: null, + // 仅支持self | blank + subtarget: 'blank', + + // 'center' ¦ 'left' ¦ 'right' + // ¦ {number}(x坐标,单位px) + left: 0, + // 'top' ¦ 'bottom' ¦ 'center' + // ¦ {number}(y坐标,单位px) + top: 0, + + // 水平对齐 + // 'auto' | 'left' | 'right' | 'center' + // 默认根据 left 的位置判断是左对齐还是右对齐 + // textAlign: null + // + // 垂直对齐 + // 'auto' | 'top' | 'bottom' | 'middle' + // 默认根据 top 位置判断是上对齐还是下对齐 + // textBaseline: null + + backgroundColor: 'rgba(0,0,0,0)', + + // 标题边框颜色 + borderColor: '#ccc', + + // 标题边框线宽,单位px,默认为0(无边框) + borderWidth: 0, + + // 标题内边距,单位px,默认各方向内边距为5, + // 接受数组分别设定上右下左边距,同css + padding: 5, + + // 主副标题纵向间隔,单位px,默认为10, + itemGap: 10, + textStyle: { + fontSize: 18, + fontWeight: 'bolder', + color: '#333' + }, + subtextStyle: { + color: '#aaa' + } + } + }); + + // View + extendComponentView({ + + type: 'title', + + render: function(titleModel, ecModel, api) { + this.group.removeAll(); + + if (!titleModel.get('show')) { + return; + } + + var group = this.group; + + var textStyleModel = titleModel.getModel('textStyle'); + var subtextStyleModel = titleModel.getModel('subtextStyle'); + + var textAlign = titleModel.get('textAlign'); + var textBaseline = titleModel.get('textBaseline'); + + var textEl = new Text({ + style: setTextStyle({}, textStyleModel, { + text: titleModel.get('text'), + textFill: textStyleModel.getTextColor() + }, { + disableBox: true + }), + z2: 10 + }); + + var textRect = textEl.getBoundingRect(); + + var subText = titleModel.get('subtext'); + var subTextEl = new Text({ + style: setTextStyle({}, subtextStyleModel, { + text: subText, + textFill: subtextStyleModel.getTextColor(), + y: textRect.height + titleModel.get('itemGap'), + textVerticalAlign: 'top' + }, { + disableBox: true + }), + z2: 10 + }); + + var link = titleModel.get('link'); + var sublink = titleModel.get('sublink'); + + textEl.silent = !link; + subTextEl.silent = !sublink; + + if (link) { + textEl.on('click', function() { + window.open(link, '_' + titleModel.get('target')); + }); + } + if (sublink) { + subTextEl.on('click', function() { + window.open(sublink, '_' + titleModel.get('subtarget')); + }); + } + + group.add(textEl); + subText && group.add(subTextEl); + // If no subText, but add subTextEl, there will be an empty line. + + var groupRect = group.getBoundingRect(); + var layoutOption = titleModel.getBoxLayoutParams(); + layoutOption.width = groupRect.width; + layoutOption.height = groupRect.height; + var layoutRect = getLayoutRect( + layoutOption, { + width: api.getWidth(), + height: api.getHeight() + }, titleModel.get('padding') + ); + // Adjust text align based on position + if (!textAlign) { + // Align left if title is on the left. center and right is same + textAlign = titleModel.get('left') || titleModel.get('right'); + if (textAlign === 'middle') { + textAlign = 'center'; + } + // Adjust layout by text align + if (textAlign === 'right') { + layoutRect.x += layoutRect.width; + } else if (textAlign === 'center') { + layoutRect.x += layoutRect.width / 2; + } + } + if (!textBaseline) { + textBaseline = titleModel.get('top') || titleModel.get('bottom'); + if (textBaseline === 'center') { + textBaseline = 'middle'; + } + if (textBaseline === 'bottom') { + layoutRect.y += layoutRect.height; + } else if (textBaseline === 'middle') { + layoutRect.y += layoutRect.height / 2; + } + + textBaseline = textBaseline || 'top'; + } + + group.attr('position', [layoutRect.x, layoutRect.y]); + var alignStyle = { + textAlign: textAlign, + textVerticalAlign: textBaseline + }; + textEl.setStyle(alignStyle); + subTextEl.setStyle(alignStyle); + + // Render background + // Get groupRect again because textAlign has been changed + groupRect = group.getBoundingRect(); + var padding = layoutRect.margin; + var style = titleModel.getItemStyle(['color', 'opacity']); + style.fill = titleModel.get('backgroundColor'); + var rect = new Rect({ + shape: { + x: groupRect.x - padding[3], + y: groupRect.y - padding[0], + width: groupRect.width + padding[1] + padding[3], + height: groupRect.height + padding[0] + padding[2], + r: titleModel.get('borderRadius') + }, + style: style, + silent: true + }); + subPixelOptimizeRect(rect); + + group.add(rect); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + ComponentModel.registerSubTypeDefaulter('dataZoom', function() { + // Default 'slider' when no type specified. + return 'slider'; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle', 'single']; + // Supported coords. + var COORDS = ['cartesian2d', 'polar', 'singleAxis']; + + /** + * @param {string} coordType + * @return {boolean} + */ + function isCoordSupported(coordType) { + return indexOf(COORDS, coordType) >= 0; + } + + /** + * Create "each" method to iterate names. + * + * @pubilc + * @param {Array.} names + * @param {Array.=} attrs + * @return {Function} + */ + function createNameEach(names, attrs) { + names = names.slice(); + var capitalNames = map(names, capitalFirst); + attrs = (attrs || []).slice(); + var capitalAttrs = map(attrs, capitalFirst); + + return function(callback, context) { + each$1(names, function(name, index) { + var nameObj = { + name: name, + capital: capitalNames[index] + }; + + for (var j = 0; j < attrs.length; j++) { + nameObj[attrs[j]] = name + capitalAttrs[j]; + } + + callback.call(context, nameObj); + }); + }; + } + + /** + * Iterate each dimension name. + * + * @public + * @param {Function} callback The parameter is like: + * { + * name: 'angle', + * capital: 'Angle', + * axis: 'angleAxis', + * axisIndex: 'angleAixs', + * index: 'angleIndex' + * } + * @param {Object} context + */ + var eachAxisDim$1 = createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index', 'id']); + + /** + * If tow dataZoomModels has the same axis controlled, we say that they are 'linked'. + * dataZoomModels and 'links' make up one or more graphics. + * This function finds the graphic where the source dataZoomModel is in. + * + * @public + * @param {Function} forEachNode Node iterator. + * @param {Function} forEachEdgeType edgeType iterator + * @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id. + * @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}} + */ + function createLinkedNodesFinder(forEachNode, forEachEdgeType, edgeIdGetter) { + + return function(sourceNode) { + var result = { + nodes: [], + records: {} // key: edgeType.name, value: Object (key: edge id, value: boolean). + }; + + forEachEdgeType(function(edgeType) { + result.records[edgeType.name] = {}; + }); + + if (!sourceNode) { + return result; + } + + absorb(sourceNode, result); + + var existsLink; + do { + existsLink = false; + forEachNode(processSingleNode); + } + while (existsLink); + + function processSingleNode(node) { + if (!isNodeAbsorded(node, result) && isLinked(node, result)) { + absorb(node, result); + existsLink = true; + } + } + + return result; + }; + + function isNodeAbsorded(node, result) { + return indexOf(result.nodes, node) >= 0; + } + + function isLinked(node, result) { + var hasLink = false; + forEachEdgeType(function(edgeType) { + each$1(edgeIdGetter(node, edgeType) || [], function(edgeId) { + result.records[edgeType.name][edgeId] && (hasLink = true); + }); + }); + return hasLink; + } + + function absorb(node, result) { + result.nodes.push(node); + forEachEdgeType(function(edgeType) { + each$1(edgeIdGetter(node, edgeType) || [], function(edgeId) { + result.records[edgeType.name][edgeId] = true; + }); + }); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$22 = each$1; + var asc$1 = asc; + + /** + * Operate single axis. + * One axis can only operated by one axis operator. + * Different dataZoomModels may be defined to operate the same axis. + * (i.e. 'inside' data zoom and 'slider' data zoom components) + * So dataZoomModels share one axisProxy in that case. + * + * @class + */ + var AxisProxy = function(dimName, axisIndex, dataZoomModel, ecModel) { + + /** + * @private + * @type {string} + */ + this._dimName = dimName; + + /** + * @private + */ + this._axisIndex = axisIndex; + + /** + * @private + * @type {Array.} + */ + this._valueWindow; + + /** + * @private + * @type {Array.} + */ + this._percentWindow; + + /** + * @private + * @type {Array.} + */ + this._dataExtent; + + /** + * {minSpan, maxSpan, minValueSpan, maxValueSpan} + * @private + * @type {Object} + */ + this._minMaxSpan; + + /** + * @readOnly + * @type {module: echarts/model/Global} + */ + this.ecModel = ecModel; + + /** + * @private + * @type {module: echarts/component/dataZoom/DataZoomModel} + */ + this._dataZoomModel = dataZoomModel; + + // /** + // * @readOnly + // * @private + // */ + // this.hasSeriesStacked; + }; + + AxisProxy.prototype = { + + constructor: AxisProxy, + + /** + * Whether the axisProxy is hosted by dataZoomModel. + * + * @public + * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel + * @return {boolean} + */ + hostedBy: function(dataZoomModel) { + return this._dataZoomModel === dataZoomModel; + }, + + /** + * @return {Array.} Value can only be NaN or finite value. + */ + getDataValueWindow: function() { + return this._valueWindow.slice(); + }, + + /** + * @return {Array.} + */ + getDataPercentWindow: function() { + return this._percentWindow.slice(); + }, + + /** + * @public + * @param {number} axisIndex + * @return {Array} seriesModels + */ + getTargetSeriesModels: function() { + var seriesModels = []; + var ecModel = this.ecModel; + + ecModel.eachSeries(function(seriesModel) { + if (isCoordSupported(seriesModel.get('coordinateSystem'))) { + var dimName = this._dimName; + var axisModel = ecModel.queryComponents({ + mainType: dimName + 'Axis', + index: seriesModel.get(dimName + 'AxisIndex'), + id: seriesModel.get(dimName + 'AxisId') + })[0]; + if (this._axisIndex === (axisModel && axisModel.componentIndex)) { + seriesModels.push(seriesModel); + } + } + }, this); + + return seriesModels; + }, + + getAxisModel: function() { + return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex); + }, + + getOtherAxisModel: function() { + var axisDim = this._dimName; + var ecModel = this.ecModel; + var axisModel = this.getAxisModel(); + var isCartesian = axisDim === 'x' || axisDim === 'y'; + var otherAxisDim; + var coordSysIndexName; + if (isCartesian) { + coordSysIndexName = 'gridIndex'; + otherAxisDim = axisDim === 'x' ? 'y' : 'x'; + } else { + coordSysIndexName = 'polarIndex'; + otherAxisDim = axisDim === 'angle' ? 'radius' : 'angle'; + } + var foundOtherAxisModel; + ecModel.eachComponent(otherAxisDim + 'Axis', function(otherAxisModel) { + if ((otherAxisModel.get(coordSysIndexName) || 0) === + (axisModel.get(coordSysIndexName) || 0) + ) { + foundOtherAxisModel = otherAxisModel; + } + }); + return foundOtherAxisModel; + }, + + getMinMaxSpan: function() { + return clone(this._minMaxSpan); + }, + + /** + * Only calculate by given range and this._dataExtent, do not change anything. + * + * @param {Object} opt + * @param {number} [opt.start] + * @param {number} [opt.end] + * @param {number} [opt.startValue] + * @param {number} [opt.endValue] + */ + calculateDataWindow: function(opt) { + var dataExtent = this._dataExtent; + var axisModel = this.getAxisModel(); + var scale = axisModel.axis.scale; + var rangePropMode = this._dataZoomModel.getRangePropMode(); + var percentExtent = [0, 100]; + var percentWindow = [ + opt.start, + opt.end + ]; + var valueWindow = []; + + each$22(['startValue', 'endValue'], function(prop) { + valueWindow.push(opt[prop] != null ? scale.parse(opt[prop]) : null); + }); + + // Normalize bound. + each$22([0, 1], function(idx) { + var boundValue = valueWindow[idx]; + var boundPercent = percentWindow[idx]; + + // Notice: dataZoom is based either on `percentProp` ('start', 'end') or + // on `valueProp` ('startValue', 'endValue'). The former one is suitable + // for cases that a dataZoom component controls multiple axes with different + // unit or extent, and the latter one is suitable for accurate zoom by pixel + // (e.g., in dataZoomSelect). `valueProp` can be calculated from `percentProp`, + // but it is awkward that `percentProp` can not be obtained from `valueProp` + // accurately (because all of values that are overflow the `dataExtent` will + // be calculated to percent '100%'). So we have to use + // `dataZoom.getRangePropMode()` to mark which prop is used. + // `rangePropMode` is updated only when setOption or dispatchAction, otherwise + // it remains its original value. + + if (rangePropMode[idx] === 'percent') { + if (boundPercent == null) { + boundPercent = percentExtent[idx]; + } + // Use scale.parse to math round for category or time axis. + boundValue = scale.parse(linearMap( + boundPercent, percentExtent, dataExtent, true + )); + } else { + // Calculating `percent` from `value` may be not accurate, because + // This calculation can not be inversed, because all of values that + // are overflow the `dataExtent` will be calculated to percent '100%' + boundPercent = linearMap( + boundValue, dataExtent, percentExtent, true + ); + } + + // valueWindow[idx] = round(boundValue); + // percentWindow[idx] = round(boundPercent); + valueWindow[idx] = boundValue; + percentWindow[idx] = boundPercent; + }); + + return { + valueWindow: asc$1(valueWindow), + percentWindow: asc$1(percentWindow) + }; + }, + + /** + * Notice: reset should not be called before series.restoreData() called, + * so it is recommanded to be called in "process stage" but not "model init + * stage". + * + * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel + */ + reset: function(dataZoomModel) { + if (dataZoomModel !== this._dataZoomModel) { + return; + } + + var targetSeries = this.getTargetSeriesModels(); + // Culculate data window and data extent, and record them. + this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries); + + // this.hasSeriesStacked = false; + // each(targetSeries, function (series) { + // var data = series.getData(); + // var dataDim = data.mapDimension(this._dimName); + // var stackedDimension = data.getCalculationInfo('stackedDimension'); + // if (stackedDimension && stackedDimension === dataDim) { + // this.hasSeriesStacked = true; + // } + // }, this); + + var dataWindow = this.calculateDataWindow(dataZoomModel.option); + + this._valueWindow = dataWindow.valueWindow; + this._percentWindow = dataWindow.percentWindow; + + setMinMaxSpan(this); + + // Update axis setting then. + setAxisModel(this); + }, + + /** + * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel + */ + restore: function(dataZoomModel) { + if (dataZoomModel !== this._dataZoomModel) { + return; + } + + this._valueWindow = this._percentWindow = null; + setAxisModel(this, true); + }, + + /** + * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel + */ + filterData: function(dataZoomModel, api) { + if (dataZoomModel !== this._dataZoomModel) { + return; + } + + var axisDim = this._dimName; + var seriesModels = this.getTargetSeriesModels(); + var filterMode = dataZoomModel.get('filterMode'); + var valueWindow = this._valueWindow; + + if (filterMode === 'none') { + return; + } + + // FIXME + // Toolbox may has dataZoom injected. And if there are stacked bar chart + // with NaN data, NaN will be filtered and stack will be wrong. + // So we need to force the mode to be set empty. + // In fect, it is not a big deal that do not support filterMode-'filter' + // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis + // selection" some day, which might need "adapt to data extent on the + // otherAxis", which is disabled by filterMode-'empty'. + // But currently, stack has been fixed to based on value but not index, + // so this is not an issue any more. + // var otherAxisModel = this.getOtherAxisModel(); + // if (dataZoomModel.get('$fromToolbox') + // && otherAxisModel + // && otherAxisModel.hasSeriesStacked + // ) { + // filterMode = 'empty'; + // } + + // TODO + // filterMode 'weakFilter' and 'empty' is not optimized for huge data yet. + + // Process series data + each$22(seriesModels, function(seriesModel) { + var seriesData = seriesModel.getData(); + var dataDims = seriesData.mapDimension(axisDim, true); + + if (filterMode === 'weakFilter') { + seriesData.filterSelf(function(dataIndex) { + var leftOut; + var rightOut; + var hasValue; + for (var i = 0; i < dataDims.length; i++) { + var value = seriesData.get(dataDims[i], dataIndex); + var thisHasValue = !isNaN(value); + var thisLeftOut = value < valueWindow[0]; + var thisRightOut = value > valueWindow[1]; + if (thisHasValue && !thisLeftOut && !thisRightOut) { + return true; + } + thisHasValue && (hasValue = true); + thisLeftOut && (leftOut = true); + thisRightOut && (rightOut = true); + } + // If both left out and right out, do not filter. + return hasValue && leftOut && rightOut; + }); + } else { + each$22(dataDims, function(dim) { + if (filterMode === 'empty') { + seriesModel.setData( + seriesData.map(dim, function(value) { + return !isInWindow(value) ? NaN : value; + }) + ); + } else { + var range = {}; + range[dim] = valueWindow; + + // console.time('select'); + seriesData.selectRange(range); + // console.timeEnd('select'); + } + }); + } + + each$22(dataDims, function(dim) { + seriesData.setApproximateExtent(valueWindow, dim); + }); + }); + + function isInWindow(value) { + return value >= valueWindow[0] && value <= valueWindow[1]; + } + } + }; + + function calculateDataExtent(axisProxy, axisDim, seriesModels) { + var dataExtent = [Infinity, -Infinity]; + + each$22(seriesModels, function(seriesModel) { + var seriesData = seriesModel.getData(); + if (seriesData) { + each$22(seriesData.mapDimension(axisDim, true), function(dim) { + var seriesExtent = seriesData.getApproximateExtent(dim); + seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]); + seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]); + }); + } + }); + + if (dataExtent[1] < dataExtent[0]) { + dataExtent = [NaN, NaN]; + } + + // It is important to get "consistent" extent when more then one axes is + // controlled by a `dataZoom`, otherwise those axes will not be synchronized + // when zooming. But it is difficult to know what is "consistent", considering + // axes have different type or even different meanings (For example, two + // time axes are used to compare data of the same date in different years). + // So basically dataZoom just obtains extent by series.data (in category axis + // extent can be obtained from axis.data). + // Nevertheless, user can set min/max/scale on axes to make extent of axes + // consistent. + fixExtentByAxis(axisProxy, dataExtent); + + return dataExtent; + } + + function fixExtentByAxis(axisProxy, dataExtent) { + var axisModel = axisProxy.getAxisModel(); + var min = axisModel.getMin(true); + + // For category axis, if min/max/scale are not set, extent is determined + // by axis.data by default. + var isCategoryAxis = axisModel.get('type') === 'category'; + var axisDataLen = isCategoryAxis && axisModel.getCategories().length; + + if (min != null && min !== 'dataMin' && typeof min !== 'function') { + dataExtent[0] = min; + } else if (isCategoryAxis) { + dataExtent[0] = axisDataLen > 0 ? 0 : NaN; + } + + var max = axisModel.getMax(true); + if (max != null && max !== 'dataMax' && typeof max !== 'function') { + dataExtent[1] = max; + } else if (isCategoryAxis) { + dataExtent[1] = axisDataLen > 0 ? axisDataLen - 1 : NaN; + } + + if (!axisModel.get('scale', true)) { + dataExtent[0] > 0 && (dataExtent[0] = 0); + dataExtent[1] < 0 && (dataExtent[1] = 0); + } + + // For value axis, if min/max/scale are not set, we just use the extent obtained + // by series data, which may be a little different from the extent calculated by + // `axisHelper.getScaleExtent`. But the different just affects the experience a + // little when zooming. So it will not be fixed until some users require it strongly. + + return dataExtent; + } + + function setAxisModel(axisProxy, isRestore) { + var axisModel = axisProxy.getAxisModel(); + + var percentWindow = axisProxy._percentWindow; + var valueWindow = axisProxy._valueWindow; + + if (!percentWindow) { + return; + } + + // [0, 500]: arbitrary value, guess axis extent. + var precision = getPixelPrecision(valueWindow, [0, 500]); + precision = Math.min(precision, 20); + // isRestore or isFull + var useOrigin = isRestore || (percentWindow[0] === 0 && percentWindow[1] === 100); + + axisModel.setRange( + useOrigin ? null : +valueWindow[0].toFixed(precision), + useOrigin ? null : +valueWindow[1].toFixed(precision) + ); + } + + function setMinMaxSpan(axisProxy) { + var minMaxSpan = axisProxy._minMaxSpan = {}; + var dataZoomModel = axisProxy._dataZoomModel; + + each$22(['min', 'max'], function(minMax) { + minMaxSpan[minMax + 'Span'] = dataZoomModel.get(minMax + 'Span'); + + // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan + var valueSpan = dataZoomModel.get(minMax + 'ValueSpan'); + + if (valueSpan != null) { + minMaxSpan[minMax + 'ValueSpan'] = valueSpan; + valueSpan = axisProxy.getAxisModel().axis.scale.parse(valueSpan); + + if (valueSpan != null) { + var dataExtent = axisProxy._dataExtent; + minMaxSpan[minMax + 'Span'] = linearMap( + dataExtent[0] + valueSpan, dataExtent, [0, 100], true + ); + } + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$21 = each$1; + var eachAxisDim = eachAxisDim$1; + + var DataZoomModel = extendComponentModel({ + + type: 'dataZoom', + + dependencies: [ + 'xAxis', 'yAxis', 'zAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series' + ], + + /** + * @protected + */ + defaultOption: { + zlevel: 0, + z: 4, // Higher than normal component (z: 2). + orient: null, // Default auto by axisIndex. Possible value: 'horizontal', 'vertical'. + xAxisIndex: null, // Default the first horizontal category axis. + yAxisIndex: null, // Default the first vertical category axis. + + filterMode: 'filter', // Possible values: 'filter' or 'empty' or 'weakFilter'. + // 'filter': data items which are out of window will be removed. This option is + // applicable when filtering outliers. For each data item, it will be + // filtered if one of the relevant dimensions is out of the window. + // 'weakFilter': data items which are out of window will be removed. This option + // is applicable when filtering outliers. For each data item, it will be + // filtered only if all of the relevant dimensions are out of the same + // side of the window. + // 'empty': data items which are out of window will be set to empty. + // This option is applicable when user should not neglect + // that there are some data items out of window. + // 'none': Do not filter. + // Taking line chart as an example, line will be broken in + // the filtered points when filterModel is set to 'empty', but + // be connected when set to 'filter'. + + throttle: null, // Dispatch action by the fixed rate, avoid frequency. + // default 100. Do not throttle when use null/undefined. + // If animation === true and animationDurationUpdate > 0, + // default value is 100, otherwise 20. + start: 0, // Start percent. 0 ~ 100 + end: 100, // End percent. 0 ~ 100 + startValue: null, // Start value. If startValue specified, start is ignored. + endValue: null, // End value. If endValue specified, end is ignored. + minSpan: null, // 0 ~ 100 + maxSpan: null, // 0 ~ 100 + minValueSpan: null, // The range of dataZoom can not be smaller than that. + maxValueSpan: null, // The range of dataZoom can not be larger than that. + rangeMode: null // Array, can be 'value' or 'percent'. + }, + + /** + * @override + */ + init: function(option, parentModel, ecModel) { + + /** + * key like x_0, y_1 + * @private + * @type {Object} + */ + this._dataIntervalByAxis = {}; + + /** + * @private + */ + this._dataInfo = {}; + + /** + * key like x_0, y_1 + * @private + */ + this._axisProxies = {}; + + /** + * @readOnly + */ + this.textStyleModel; + + /** + * @private + */ + this._autoThrottle = true; + + /** + * 'percent' or 'value' + * @private + */ + this._rangePropMode = ['percent', 'percent']; + + var rawOption = retrieveRaw(option); + + this.mergeDefaultAndTheme(option, ecModel); + + this.doInit(rawOption); + }, + + /** + * @override + */ + mergeOption: function(newOption) { + var rawOption = retrieveRaw(newOption); + + //FIX #2591 + merge(this.option, newOption, true); + + this.doInit(rawOption); + }, + + /** + * @protected + */ + doInit: function(rawOption) { + var thisOption = this.option; + + // Disable realtime view update if canvas is not supported. + if (!env$1.canvasSupported) { + thisOption.realtime = false; + } + + this._setDefaultThrottle(rawOption); + + updateRangeUse(this, rawOption); + + each$21([ + ['start', 'startValue'], + ['end', 'endValue'] + ], function(names, index) { + // start/end has higher priority over startValue/endValue if they + // both set, but we should make chart.setOption({endValue: 1000}) + // effective, rather than chart.setOption({endValue: 1000, end: null}). + if (this._rangePropMode[index] === 'value') { + thisOption[names[0]] = null; + } + // Otherwise do nothing and use the merge result. + }, this); + + this.textStyleModel = this.getModel('textStyle'); + + this._resetTarget(); + + this._giveAxisProxies(); + }, + + /** + * @private + */ + _giveAxisProxies: function() { + var axisProxies = this._axisProxies; + + this.eachTargetAxis(function(dimNames, axisIndex, dataZoomModel, ecModel) { + var axisModel = this.dependentModels[dimNames.axis][axisIndex]; + + // If exists, share axisProxy with other dataZoomModels. + var axisProxy = axisModel.__dzAxisProxy || ( + // Use the first dataZoomModel as the main model of axisProxy. + axisModel.__dzAxisProxy = new AxisProxy( + dimNames.name, axisIndex, this, ecModel + ) + ); + // FIXME + // dispose __dzAxisProxy + + axisProxies[dimNames.name + '_' + axisIndex] = axisProxy; + }, this); + }, + + /** + * @private + */ + _resetTarget: function() { + var thisOption = this.option; + + var autoMode = this._judgeAutoMode(); + + eachAxisDim(function(dimNames) { + var axisIndexName = dimNames.axisIndex; + thisOption[axisIndexName] = normalizeToArray( + thisOption[axisIndexName] + ); + }, this); + + if (autoMode === 'axisIndex') { + this._autoSetAxisIndex(); + } else if (autoMode === 'orient') { + this._autoSetOrient(); + } + }, + + /** + * @private + */ + _judgeAutoMode: function() { + // Auto set only works for setOption at the first time. + // The following is user's reponsibility. So using merged + // option is OK. + var thisOption = this.option; + + var hasIndexSpecified = false; + eachAxisDim(function(dimNames) { + // When user set axisIndex as a empty array, we think that user specify axisIndex + // but do not want use auto mode. Because empty array may be encountered when + // some error occured. + if (thisOption[dimNames.axisIndex] != null) { + hasIndexSpecified = true; + } + }, this); + + var orient = thisOption.orient; + + if (orient == null && hasIndexSpecified) { + return 'orient'; + } else if (!hasIndexSpecified) { + if (orient == null) { + thisOption.orient = 'horizontal'; + } + return 'axisIndex'; + } + }, + + /** + * @private + */ + _autoSetAxisIndex: function() { + var autoAxisIndex = true; + var orient = this.get('orient', true); + var thisOption = this.option; + var dependentModels = this.dependentModels; + + if (autoAxisIndex) { + // Find axis that parallel to dataZoom as default. + var dimName = orient === 'vertical' ? 'y' : 'x'; + + if (dependentModels[dimName + 'Axis'].length) { + thisOption[dimName + 'AxisIndex'] = [0]; + autoAxisIndex = false; + } else { + each$21(dependentModels.singleAxis, function(singleAxisModel) { + if (autoAxisIndex && singleAxisModel.get('orient', true) === orient) { + thisOption.singleAxisIndex = [singleAxisModel.componentIndex]; + autoAxisIndex = false; + } + }); + } + } + + if (autoAxisIndex) { + // Find the first category axis as default. (consider polar) + eachAxisDim(function(dimNames) { + if (!autoAxisIndex) { + return; + } + var axisIndices = []; + var axisModels = this.dependentModels[dimNames.axis]; + if (axisModels.length && !axisIndices.length) { + for (var i = 0, len = axisModels.length; i < len; i++) { + if (axisModels[i].get('type') === 'category') { + axisIndices.push(i); + } + } + } + thisOption[dimNames.axisIndex] = axisIndices; + if (axisIndices.length) { + autoAxisIndex = false; + } + }, this); + } + + if (autoAxisIndex) { + // FIXME + // 这里是兼容ec2的写法(没指定xAxisIndex和yAxisIndex时把scatter和双数值轴折柱纳入dataZoom控制), + // 但是实际是否需要Grid.js#getScaleByOption来判断(考虑time,log等axis type)? + + // If both dataZoom.xAxisIndex and dataZoom.yAxisIndex is not specified, + // dataZoom component auto adopts series that reference to + // both xAxis and yAxis which type is 'value'. + this.ecModel.eachSeries(function(seriesModel) { + if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) { + eachAxisDim(function(dimNames) { + var axisIndices = thisOption[dimNames.axisIndex]; + + var axisIndex = seriesModel.get(dimNames.axisIndex); + var axisId = seriesModel.get(dimNames.axisId); + + var axisModel = seriesModel.ecModel.queryComponents({ + mainType: dimNames.axis, + index: axisIndex, + id: axisId + })[0]; + + if (__DEV__) { + if (!axisModel) { + throw new Error( + dimNames.axis + ' "' + retrieve( + axisIndex, + axisId, + 0 + ) + '" not found' + ); + } + } + axisIndex = axisModel.componentIndex; + + if (indexOf(axisIndices, axisIndex) < 0) { + axisIndices.push(axisIndex); + } + }); + } + }, this); + } + }, + + /** + * @private + */ + _autoSetOrient: function() { + var dim; + + // Find the first axis + this.eachTargetAxis(function(dimNames) { + !dim && (dim = dimNames.name); + }, this); + + this.option.orient = dim === 'y' ? 'vertical' : 'horizontal'; + }, + + /** + * @private + */ + _isSeriesHasAllAxesTypeOf: function(seriesModel, axisType) { + // FIXME + // 需要series的xAxisIndex和yAxisIndex都首先自动设置上。 + // 例如series.type === scatter时。 + + var is = true; + eachAxisDim(function(dimNames) { + var seriesAxisIndex = seriesModel.get(dimNames.axisIndex); + var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex]; + + if (!axisModel || axisModel.get('type') !== axisType) { + is = false; + } + }, this); + return is; + }, + + /** + * @private + */ + _setDefaultThrottle: function(rawOption) { + // When first time user set throttle, auto throttle ends. + if (rawOption.hasOwnProperty('throttle')) { + this._autoThrottle = false; + } + if (this._autoThrottle) { + var globalOption = this.ecModel.option; + this.option.throttle = + (globalOption.animation && globalOption.animationDurationUpdate > 0) ? + 100 : 20; + } + }, + + /** + * @public + */ + getFirstTargetAxisModel: function() { + var firstAxisModel; + eachAxisDim(function(dimNames) { + if (firstAxisModel == null) { + var indices = this.get(dimNames.axisIndex); + if (indices.length) { + firstAxisModel = this.dependentModels[dimNames.axis][indices[0]]; + } + } + }, this); + + return firstAxisModel; + }, + + /** + * @public + * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel + */ + eachTargetAxis: function(callback, context) { + var ecModel = this.ecModel; + eachAxisDim(function(dimNames) { + each$21( + this.get(dimNames.axisIndex), + function(axisIndex) { + callback.call(context, dimNames, axisIndex, this, ecModel); + }, + this + ); + }, this); + }, + + /** + * @param {string} dimName + * @param {number} axisIndex + * @return {module:echarts/component/dataZoom/AxisProxy} If not found, return null/undefined. + */ + getAxisProxy: function(dimName, axisIndex) { + return this._axisProxies[dimName + '_' + axisIndex]; + }, + + /** + * @param {string} dimName + * @param {number} axisIndex + * @return {module:echarts/model/Model} If not found, return null/undefined. + */ + getAxisModel: function(dimName, axisIndex) { + var axisProxy = this.getAxisProxy(dimName, axisIndex); + return axisProxy && axisProxy.getAxisModel(); + }, + + /** + * If not specified, set to undefined. + * + * @public + * @param {Object} opt + * @param {number} [opt.start] + * @param {number} [opt.end] + * @param {number} [opt.startValue] + * @param {number} [opt.endValue] + * @param {boolean} [ignoreUpdateRangeUsg=false] + */ + setRawRange: function(opt, ignoreUpdateRangeUsg) { + var option = this.option; + each$21([ + ['start', 'startValue'], + ['end', 'endValue'] + ], function(names) { + // If only one of 'start' and 'startValue' is not null/undefined, the other + // should be cleared, which enable clear the option. + // If both of them are not set, keep option with the original value, which + // enable use only set start but not set end when calling `dispatchAction`. + // The same as 'end' and 'endValue'. + if (opt[names[0]] != null || opt[names[1]] != null) { + option[names[0]] = opt[names[0]]; + option[names[1]] = opt[names[1]]; + } + }, this); + + !ignoreUpdateRangeUsg && updateRangeUse(this, opt); + }, + + /** + * @public + * @return {Array.} [startPercent, endPercent] + */ + getPercentRange: function() { + var axisProxy = this.findRepresentativeAxisProxy(); + if (axisProxy) { + return axisProxy.getDataPercentWindow(); + } + }, + + /** + * @public + * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0); + * + * @param {string} [axisDimName] + * @param {number} [axisIndex] + * @return {Array.} [startValue, endValue] value can only be '-' or finite number. + */ + getValueRange: function(axisDimName, axisIndex) { + if (axisDimName == null && axisIndex == null) { + var axisProxy = this.findRepresentativeAxisProxy(); + if (axisProxy) { + return axisProxy.getDataValueWindow(); + } + } else { + return this.getAxisProxy(axisDimName, axisIndex).getDataValueWindow(); + } + }, + + /** + * @public + * @param {module:echarts/model/Model} [axisModel] If axisModel given, find axisProxy + * corresponding to the axisModel + * @return {module:echarts/component/dataZoom/AxisProxy} + */ + findRepresentativeAxisProxy: function(axisModel) { + if (axisModel) { + return axisModel.__dzAxisProxy; + } + + // Find the first hosted axisProxy + var axisProxies = this._axisProxies; + for (var key in axisProxies) { + if (axisProxies.hasOwnProperty(key) && axisProxies[key].hostedBy(this)) { + return axisProxies[key]; + } + } + + // If no hosted axis find not hosted axisProxy. + // Consider this case: dataZoomModel1 and dataZoomModel2 control the same axis, + // and the option.start or option.end settings are different. The percentRange + // should follow axisProxy. + // (We encounter this problem in toolbox data zoom.) + for (var key in axisProxies) { + if (axisProxies.hasOwnProperty(key) && !axisProxies[key].hostedBy(this)) { + return axisProxies[key]; + } + } + }, + + /** + * @return {Array.} + */ + getRangePropMode: function() { + return this._rangePropMode.slice(); + } + + }); + + function retrieveRaw(option) { + var ret = {}; + each$21( + ['start', 'end', 'startValue', 'endValue', 'throttle'], + function(name) { + option.hasOwnProperty(name) && (ret[name] = option[name]); + } + ); + return ret; + } + + function updateRangeUse(dataZoomModel, rawOption) { + var rangePropMode = dataZoomModel._rangePropMode; + var rangeModeInOption = dataZoomModel.get('rangeMode'); + + each$21([ + ['start', 'startValue'], + ['end', 'endValue'] + ], function(names, index) { + var percentSpecified = rawOption[names[0]] != null; + var valueSpecified = rawOption[names[1]] != null; + if (percentSpecified && !valueSpecified) { + rangePropMode[index] = 'percent'; + } else if (!percentSpecified && valueSpecified) { + rangePropMode[index] = 'value'; + } else if (rangeModeInOption) { + rangePropMode[index] = rangeModeInOption[index]; + } else if (percentSpecified) { // percentSpecified && valueSpecified + rangePropMode[index] = 'percent'; + } + // else remain its original setting. + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var DataZoomView = Component.extend({ + + type: 'dataZoom', + + render: function(dataZoomModel, ecModel, api, payload) { + this.dataZoomModel = dataZoomModel; + this.ecModel = ecModel; + this.api = api; + }, + + /** + * Find the first target coordinate system. + * + * @protected + * @return {Object} { + * grid: [ + * {model: coord0, axisModels: [axis1, axis3], coordIndex: 1}, + * {model: coord1, axisModels: [axis0, axis2], coordIndex: 0}, + * ... + * ], // cartesians must not be null/undefined. + * polar: [ + * {model: coord0, axisModels: [axis4], coordIndex: 0}, + * ... + * ], // polars must not be null/undefined. + * singleAxis: [ + * {model: coord0, axisModels: [], coordIndex: 0} + * ] + */ + getTargetCoordInfo: function() { + var dataZoomModel = this.dataZoomModel; + var ecModel = this.ecModel; + var coordSysLists = {}; + + dataZoomModel.eachTargetAxis(function(dimNames, axisIndex) { + var axisModel = ecModel.getComponent(dimNames.axis, axisIndex); + if (axisModel) { + var coordModel = axisModel.getCoordSysModel(); + coordModel && save( + coordModel, + axisModel, + coordSysLists[coordModel.mainType] || (coordSysLists[coordModel.mainType] = []), + coordModel.componentIndex + ); + } + }, this); + + function save(coordModel, axisModel, store, coordIndex) { + var item; + for (var i = 0; i < store.length; i++) { + if (store[i].model === coordModel) { + item = store[i]; + break; + } + } + if (!item) { + store.push(item = { + model: coordModel, + axisModels: [], + coordIndex: coordIndex + }); + } + item.axisModels.push(axisModel); + } + + return coordSysLists; + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var SliderZoomModel = DataZoomModel.extend({ + + type: 'dataZoom.slider', + + layoutMode: 'box', + + /** + * @protected + */ + defaultOption: { + show: true, + + // ph => placeholder. Using placehoder here because + // deault value can only be drived in view stage. + right: 'ph', // Default align to grid rect. + top: 'ph', // Default align to grid rect. + width: 'ph', // Default align to grid rect. + height: 'ph', // Default align to grid rect. + left: null, // Default align to grid rect. + bottom: null, // Default align to grid rect. + + backgroundColor: 'rgba(47,69,84,0)', // Background of slider zoom component. + // dataBackgroundColor: '#ddd', // Background coor of data shadow and border of box, + // highest priority, remain for compatibility of + // previous version, but not recommended any more. + dataBackground: { + lineStyle: { + color: '#2f4554', + width: 0.5, + opacity: 0.3 + }, + areaStyle: { + color: 'rgba(47,69,84,0.3)', + opacity: 0.3 + } + }, + borderColor: '#ddd', // border color of the box. For compatibility, + // if dataBackgroundColor is set, borderColor + // is ignored. + + fillerColor: 'rgba(167,183,204,0.4)', // Color of selected area. + // handleColor: 'rgba(89,170,216,0.95)', // Color of handle. + // handleIcon: 'path://M4.9,17.8c0-1.4,4.5-10.5,5.5-12.4c0-0.1,0.6-1.1,0.9-1.1c0.4,0,0.9,1,0.9,1.1c1.1,2.2,5.4,11,5.4,12.4v17.8c0,1.5-0.6,2.1-1.3,2.1H6.1c-0.7,0-1.3-0.6-1.3-2.1V17.8z', + handleIcon: 'M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z', + // Percent of the slider height + handleSize: '100%', + + handleStyle: { + color: '#a7b7cc' + }, + + labelPrecision: null, + labelFormatter: null, + showDetail: true, + showDataShadow: 'auto', // Default auto decision. + realtime: true, + zoomLock: false, // Whether disable zoom. + textStyle: { + color: '#333' + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var Rect$2 = Rect; + var linearMap$1 = linearMap; + var asc$2 = asc; + var bind$4 = bind; + var each$23 = each$1; + + // Constants + var DEFAULT_LOCATION_EDGE_GAP = 7; + var DEFAULT_FRAME_BORDER_WIDTH = 1; + var DEFAULT_FILLER_SIZE = 30; + var HORIZONTAL = 'horizontal'; + var VERTICAL = 'vertical'; + var LABEL_GAP = 5; + var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter']; + + var SliderZoomView = DataZoomView.extend({ + + type: 'dataZoom.slider', + + init: function(ecModel, api) { + + /** + * @private + * @type {Object} + */ + this._displayables = {}; + + /** + * @private + * @type {string} + */ + this._orient; + + /** + * [0, 100] + * @private + */ + this._range; + + /** + * [coord of the first handle, coord of the second handle] + * @private + */ + this._handleEnds; + + /** + * [length, thick] + * @private + * @type {Array.} + */ + this._size; + + /** + * @private + * @type {number} + */ + this._handleWidth; + + /** + * @private + * @type {number} + */ + this._handleHeight; + + /** + * @private + */ + this._location; + + /** + * @private + */ + this._dragging; + + /** + * @private + */ + this._dataShadowInfo; + + this.api = api; + }, + + /** + * @override + */ + render: function(dataZoomModel, ecModel, api, payload) { + SliderZoomView.superApply(this, 'render', arguments); + + createOrUpdate( + this, + '_dispatchZoomAction', + this.dataZoomModel.get('throttle'), + 'fixRate' + ); + + this._orient = dataZoomModel.get('orient'); + + if (this.dataZoomModel.get('show') === false) { + this.group.removeAll(); + return; + } + + // Notice: this._resetInterval() should not be executed when payload.type + // is 'dataZoom', origin this._range should be maintained, otherwise 'pan' + // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction, + if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) { + this._buildView(); + } + + this._updateView(); + }, + + /** + * @override + */ + remove: function() { + SliderZoomView.superApply(this, 'remove', arguments); + clear(this, '_dispatchZoomAction'); + }, + + /** + * @override + */ + dispose: function() { + SliderZoomView.superApply(this, 'dispose', arguments); + clear(this, '_dispatchZoomAction'); + }, + + _buildView: function() { + var thisGroup = this.group; + + thisGroup.removeAll(); + + this._resetLocation(); + this._resetInterval(); + + var barGroup = this._displayables.barGroup = new Group(); + + this._renderBackground(); + + this._renderHandle(); + + this._renderDataShadow(); + + thisGroup.add(barGroup); + + this._positionGroup(); + }, + + /** + * @private + */ + _resetLocation: function() { + var dataZoomModel = this.dataZoomModel; + var api = this.api; + + // If some of x/y/width/height are not specified, + // auto-adapt according to target grid. + var coordRect = this._findCoordRect(); + var ecSize = { + width: api.getWidth(), + height: api.getHeight() + }; + // Default align by coordinate system rect. + var positionInfo = this._orient === HORIZONTAL ? + { + // Why using 'right', because right should be used in vertical, + // and it is better to be consistent for dealing with position param merge. + right: ecSize.width - coordRect.x - coordRect.width, + top: (ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP), + width: coordRect.width, + height: DEFAULT_FILLER_SIZE + } : + { // vertical + right: DEFAULT_LOCATION_EDGE_GAP, + top: coordRect.y, + width: DEFAULT_FILLER_SIZE, + height: coordRect.height + }; + + // Do not write back to option and replace value 'ph', because + // the 'ph' value should be recalculated when resize. + var layoutParams = getLayoutParams(dataZoomModel.option); + + // Replace the placeholder value. + each$1(['right', 'top', 'width', 'height'], function(name) { + if (layoutParams[name] === 'ph') { + layoutParams[name] = positionInfo[name]; + } + }); + + var layoutRect = getLayoutRect( + layoutParams, + ecSize, + dataZoomModel.padding + ); + + this._location = { + x: layoutRect.x, + y: layoutRect.y + }; + this._size = [layoutRect.width, layoutRect.height]; + this._orient === VERTICAL && this._size.reverse(); + }, + + /** + * @private + */ + _positionGroup: function() { + var thisGroup = this.group; + var location = this._location; + var orient = this._orient; + + // Just use the first axis to determine mapping. + var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel(); + var inverse = targetAxisModel && targetAxisModel.get('inverse'); + + var barGroup = this._displayables.barGroup; + var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; + + // Transform barGroup. + barGroup.attr( + (orient === HORIZONTAL && !inverse) ? + { + scale: otherAxisInverse ? [1, 1] : [1, -1] + } : + (orient === HORIZONTAL && inverse) ? + { + scale: otherAxisInverse ? [-1, 1] : [-1, -1] + } : + (orient === VERTICAL && !inverse) ? + { + scale: otherAxisInverse ? [1, -1] : [1, 1], + rotation: Math.PI / 2 + } + // Dont use Math.PI, considering shadow direction. + : + { + scale: otherAxisInverse ? [-1, -1] : [-1, 1], + rotation: Math.PI / 2 + } + ); + + // Position barGroup + var rect = thisGroup.getBoundingRect([barGroup]); + thisGroup.attr('position', [location.x - rect.x, location.y - rect.y]); + }, + + /** + * @private + */ + _getViewExtent: function() { + return [0, this._size[0]]; + }, + + _renderBackground: function() { + var dataZoomModel = this.dataZoomModel; + var size = this._size; + var barGroup = this._displayables.barGroup; + + barGroup.add(new Rect$2({ + silent: true, + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1] + }, + style: { + fill: dataZoomModel.get('backgroundColor') + }, + z2: -40 + })); + + // Click panel, over shadow, below handles. + barGroup.add(new Rect$2({ + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1] + }, + style: { + fill: 'transparent' + }, + z2: 0, + onclick: bind(this._onClickPanelClick, this) + })); + }, + + _renderDataShadow: function() { + var info = this._dataShadowInfo = this._prepareDataShadowInfo(); + + if (!info) { + return; + } + + var size = this._size; + var seriesModel = info.series; + var data = seriesModel.getRawData(); + + var otherDim = seriesModel.getShadowDim ? + seriesModel.getShadowDim() // @see candlestick + : + info.otherDim; + + if (otherDim == null) { + return; + } + + var otherDataExtent = data.getDataExtent(otherDim); + // Nice extent. + var otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3; + otherDataExtent = [ + otherDataExtent[0] - otherOffset, + otherDataExtent[1] + otherOffset + ]; + var otherShadowExtent = [0, size[1]]; + + var thisShadowExtent = [0, size[0]]; + + var areaPoints = [ + [size[0], 0], + [0, 0] + ]; + var linePoints = []; + var step = thisShadowExtent[1] / (data.count() - 1); + var thisCoord = 0; + + // Optimize for large data shadow + var stride = Math.round(data.count() / size[0]); + var lastIsEmpty; + data.each([otherDim], function(value, index) { + if (stride > 0 && (index % stride)) { + thisCoord += step; + return; + } + + // FIXME + // Should consider axis.min/axis.max when drawing dataShadow. + + // FIXME + // 应该使用统一的空判断?还是在list里进行空判断? + var isEmpty = value == null || isNaN(value) || value === ''; + // See #4235. + var otherCoord = isEmpty ? + 0 : linearMap$1(value, otherDataExtent, otherShadowExtent, true); + + // Attempt to draw data shadow precisely when there are empty value. + if (isEmpty && !lastIsEmpty && index) { + areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]); + linePoints.push([linePoints[linePoints.length - 1][0], 0]); + } else if (!isEmpty && lastIsEmpty) { + areaPoints.push([thisCoord, 0]); + linePoints.push([thisCoord, 0]); + } + + areaPoints.push([thisCoord, otherCoord]); + linePoints.push([thisCoord, otherCoord]); + + thisCoord += step; + lastIsEmpty = isEmpty; + }); + + var dataZoomModel = this.dataZoomModel; + // var dataBackgroundModel = dataZoomModel.getModel('dataBackground'); + this._displayables.barGroup.add(new Polygon({ + shape: { + points: areaPoints + }, + style: defaults({ + fill: dataZoomModel.get('dataBackgroundColor') + }, + dataZoomModel.getModel('dataBackground.areaStyle').getAreaStyle() + ), + silent: true, + z2: -20 + })); + this._displayables.barGroup.add(new Polyline({ + shape: { + points: linePoints + }, + style: dataZoomModel.getModel('dataBackground.lineStyle').getLineStyle(), + silent: true, + z2: -19 + })); + }, + + _prepareDataShadowInfo: function() { + var dataZoomModel = this.dataZoomModel; + var showDataShadow = dataZoomModel.get('showDataShadow'); + + if (showDataShadow === false) { + return; + } + + // Find a representative series. + var result; + var ecModel = this.ecModel; + + dataZoomModel.eachTargetAxis(function(dimNames, axisIndex) { + var seriesModels = dataZoomModel + .getAxisProxy(dimNames.name, axisIndex) + .getTargetSeriesModels(); + + each$1(seriesModels, function(seriesModel) { + if (result) { + return; + } + + if (showDataShadow !== true && indexOf( + SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type') + ) < 0) { + return; + } + + var thisAxis = ecModel.getComponent(dimNames.axis, axisIndex).axis; + var otherDim = getOtherDim(dimNames.name); + var otherAxisInverse; + var coordSys = seriesModel.coordinateSystem; + + if (otherDim != null && coordSys.getOtherAxis) { + otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse; + } + + otherDim = seriesModel.getData().mapDimension(otherDim); + + result = { + thisAxis: thisAxis, + series: seriesModel, + thisDim: dimNames.name, + otherDim: otherDim, + otherAxisInverse: otherAxisInverse + }; + + }, this); + + }, this); + + return result; + }, + + _renderHandle: function() { + var displaybles = this._displayables; + var handles = displaybles.handles = []; + var handleLabels = displaybles.handleLabels = []; + var barGroup = this._displayables.barGroup; + var size = this._size; + var dataZoomModel = this.dataZoomModel; + + barGroup.add(displaybles.filler = new Rect$2({ + draggable: true, + cursor: getCursor(this._orient), + drift: bind$4(this._onDragMove, this, 'all'), + onmousemove: function(e) { + // Fot mobile devicem, prevent screen slider on the button. + stop(e.event); + }, + ondragstart: bind$4(this._showDataInfo, this, true), + ondragend: bind$4(this._onDragEnd, this), + onmouseover: bind$4(this._showDataInfo, this, true), + onmouseout: bind$4(this._showDataInfo, this, false), + style: { + fill: dataZoomModel.get('fillerColor'), + textPosition: 'inside' + } + })); + + // Frame border. + barGroup.add(new Rect$2(subPixelOptimizeRect({ + silent: true, + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1] + }, + style: { + stroke: dataZoomModel.get('dataBackgroundColor') || + dataZoomModel.get('borderColor'), + lineWidth: DEFAULT_FRAME_BORDER_WIDTH, + fill: 'rgba(0,0,0,0)' + } + }))); + + each$23([0, 1], function(handleIndex) { + var path = createIcon( + dataZoomModel.get('handleIcon'), { + cursor: getCursor(this._orient), + draggable: true, + drift: bind$4(this._onDragMove, this, handleIndex), + onmousemove: function(e) { + // Fot mobile devicem, prevent screen slider on the button. + stop(e.event); + }, + ondragend: bind$4(this._onDragEnd, this), + onmouseover: bind$4(this._showDataInfo, this, true), + onmouseout: bind$4(this._showDataInfo, this, false) + }, { + x: -1, + y: 0, + width: 2, + height: 2 + } + ); + + var bRect = path.getBoundingRect(); + this._handleHeight = parsePercent$1(dataZoomModel.get('handleSize'), this._size[1]); + this._handleWidth = bRect.width / bRect.height * this._handleHeight; + + path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle()); + var handleColor = dataZoomModel.get('handleColor'); + // Compatitable with previous version + if (handleColor != null) { + path.style.fill = handleColor; + } + + barGroup.add(handles[handleIndex] = path); + + var textStyleModel = dataZoomModel.textStyleModel; + + this.group.add( + handleLabels[handleIndex] = new Text({ + silent: true, + invisible: true, + style: { + x: 0, + y: 0, + text: '', + textVerticalAlign: 'middle', + textAlign: 'center', + textFill: textStyleModel.getTextColor(), + textFont: textStyleModel.getFont() + }, + z2: 10 + })); + + }, this); + }, + + /** + * @private + */ + _resetInterval: function() { + var range = this._range = this.dataZoomModel.getPercentRange(); + var viewExtent = this._getViewExtent(); + + this._handleEnds = [ + linearMap$1(range[0], [0, 100], viewExtent, true), + linearMap$1(range[1], [0, 100], viewExtent, true) + ]; + }, + + /** + * @private + * @param {(number|string)} handleIndex 0 or 1 or 'all' + * @param {number} delta + * @return {boolean} changed + */ + _updateInterval: function(handleIndex, delta) { + var dataZoomModel = this.dataZoomModel; + var handleEnds = this._handleEnds; + var viewExtend = this._getViewExtent(); + var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan(); + var percentExtent = [0, 100]; + + sliderMove( + delta, + handleEnds, + viewExtend, + dataZoomModel.get('zoomLock') ? 'all' : handleIndex, + minMaxSpan.minSpan != null ? + linearMap$1(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, + minMaxSpan.maxSpan != null ? + linearMap$1(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null + ); + + var lastRange = this._range; + var range = this._range = asc$2([ + linearMap$1(handleEnds[0], viewExtend, percentExtent, true), + linearMap$1(handleEnds[1], viewExtend, percentExtent, true) + ]); + + return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1]; + }, + + /** + * @private + */ + _updateView: function(nonRealtime) { + var displaybles = this._displayables; + var handleEnds = this._handleEnds; + var handleInterval = asc$2(handleEnds.slice()); + var size = this._size; + + each$23([0, 1], function(handleIndex) { + // Handles + var handle = displaybles.handles[handleIndex]; + var handleHeight = this._handleHeight; + handle.attr({ + scale: [handleHeight / 2, handleHeight / 2], + position: [handleEnds[handleIndex], size[1] / 2 - handleHeight / 2] + }); + }, this); + + // Filler + displaybles.filler.setShape({ + x: handleInterval[0], + y: 0, + width: handleInterval[1] - handleInterval[0], + height: size[1] + }); + + this._updateDataInfo(nonRealtime); + }, + + /** + * @private + */ + _updateDataInfo: function(nonRealtime) { + var dataZoomModel = this.dataZoomModel; + var displaybles = this._displayables; + var handleLabels = displaybles.handleLabels; + var orient = this._orient; + var labelTexts = ['', '']; + + // FIXME + // date型,支持formatter,autoformatter(ec2 date.getAutoFormatter) + if (dataZoomModel.get('showDetail')) { + var axisProxy = dataZoomModel.findRepresentativeAxisProxy(); + + if (axisProxy) { + var axis = axisProxy.getAxisModel().axis; + var range = this._range; + + var dataInterval = nonRealtime + // See #4434, data and axis are not processed and reset yet in non-realtime mode. + ? + axisProxy.calculateDataWindow({ + start: range[0], + end: range[1] + }).valueWindow : + axisProxy.getDataValueWindow(); + + labelTexts = [ + this._formatLabel(dataInterval[0], axis), + this._formatLabel(dataInterval[1], axis) + ]; + } + } + + var orderedHandleEnds = asc$2(this._handleEnds.slice()); + + setLabel.call(this, 0); + setLabel.call(this, 1); + + function setLabel(handleIndex) { + // Label + // Text should not transform by barGroup. + // Ignore handlers transform + var barTransform = getTransform( + displaybles.handles[handleIndex].parent, this.group + ); + var direction = transformDirection( + handleIndex === 0 ? 'right' : 'left', barTransform + ); + var offset = this._handleWidth / 2 + LABEL_GAP; + var textPoint = applyTransform$1( + [ + orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), + this._size[1] / 2 + ], + barTransform + ); + handleLabels[handleIndex].setStyle({ + x: textPoint[0], + y: textPoint[1], + textVerticalAlign: orient === HORIZONTAL ? 'middle' : direction, + textAlign: orient === HORIZONTAL ? direction : 'center', + text: labelTexts[handleIndex] + }); + } + }, + + /** + * @private + */ + _formatLabel: function(value, axis) { + var dataZoomModel = this.dataZoomModel; + var labelFormatter = dataZoomModel.get('labelFormatter'); + + var labelPrecision = dataZoomModel.get('labelPrecision'); + if (labelPrecision == null || labelPrecision === 'auto') { + labelPrecision = axis.getPixelPrecision(); + } + + var valueStr = (value == null || isNaN(value)) ? + '' + // FIXME Glue code + : + (axis.type === 'category' || axis.type === 'time') ? + axis.scale.getLabel(Math.round(value)) + // param of toFixed should less then 20. + : + value.toFixed(Math.min(labelPrecision, 20)); + + return isFunction$1(labelFormatter) ? + labelFormatter(value, valueStr) : + isString(labelFormatter) ? + labelFormatter.replace('{value}', valueStr) : + valueStr; + }, + + /** + * @private + * @param {boolean} showOrHide true: show, false: hide + */ + _showDataInfo: function(showOrHide) { + // Always show when drgging. + showOrHide = this._dragging || showOrHide; + + var handleLabels = this._displayables.handleLabels; + handleLabels[0].attr('invisible', !showOrHide); + handleLabels[1].attr('invisible', !showOrHide); + }, + + _onDragMove: function(handleIndex, dx, dy) { + this._dragging = true; + + // Transform dx, dy to bar coordination. + var barTransform = this._displayables.barGroup.getLocalTransform(); + var vertex = applyTransform$1([dx, dy], barTransform, true); + + var changed = this._updateInterval(handleIndex, vertex[0]); + + var realtime = this.dataZoomModel.get('realtime'); + + this._updateView(!realtime); + + // Avoid dispatch dataZoom repeatly but range not changed, + // which cause bad visual effect when progressive enabled. + changed && realtime && this._dispatchZoomAction(); + }, + + _onDragEnd: function() { + this._dragging = false; + this._showDataInfo(false); + + // While in realtime mode and stream mode, dispatch action when + // drag end will cause the whole view rerender, which is unnecessary. + var realtime = this.dataZoomModel.get('realtime'); + !realtime && this._dispatchZoomAction(); + }, + + _onClickPanelClick: function(e) { + var size = this._size; + var localPoint = this._displayables.barGroup.transformCoordToLocal(e.offsetX, e.offsetY); + + if (localPoint[0] < 0 || localPoint[0] > size[0] || + localPoint[1] < 0 || localPoint[1] > size[1] + ) { + return; + } + + var handleEnds = this._handleEnds; + var center = (handleEnds[0] + handleEnds[1]) / 2; + + var changed = this._updateInterval('all', localPoint[0] - center); + this._updateView(); + changed && this._dispatchZoomAction(); + }, + + /** + * This action will be throttled. + * @private + */ + _dispatchZoomAction: function() { + var range = this._range; + + this.api.dispatchAction({ + type: 'dataZoom', + from: this.uid, + dataZoomId: this.dataZoomModel.id, + start: range[0], + end: range[1] + }); + }, + + /** + * @private + */ + _findCoordRect: function() { + // Find the grid coresponding to the first axis referred by dataZoom. + var rect; + each$23(this.getTargetCoordInfo(), function(coordInfoList) { + if (!rect && coordInfoList.length) { + var coordSys = coordInfoList[0].model.coordinateSystem; + rect = coordSys.getRect && coordSys.getRect(); + } + }); + if (!rect) { + var width = this.api.getWidth(); + var height = this.api.getHeight(); + rect = { + x: width * 0.2, + y: height * 0.2, + width: width * 0.6, + height: height * 0.6 + }; + } + + return rect; + } + + }); + + function getOtherDim(thisDim) { + // FIXME + // 这个逻辑和getOtherAxis里一致,但是写在这里是否不好 + var map$$1 = { + x: 'y', + y: 'x', + radius: 'angle', + angle: 'radius' + }; + return map$$1[thisDim]; + } + + function getCursor(orient) { + return orient === 'vertical' ? 'ns-resize' : 'ew-resize'; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + DataZoomModel.extend({ + + type: 'dataZoom.inside', + + /** + * @protected + */ + defaultOption: { + disabled: false, // Whether disable this inside zoom. + zoomLock: false, // Whether disable zoom but only pan. + zoomOnMouseWheel: true, // Can be: true / false / 'shift' / 'ctrl' / 'alt'. + moveOnMouseMove: true, // Can be: true / false / 'shift' / 'ctrl' / 'alt'. + preventDefaultMouseMove: true + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Only create one roam controller for each coordinate system. + // one roam controller might be refered by two inside data zoom + // components (for example, one for x and one for y). When user + // pan or zoom, only dispatch one action for those data zoom + // components. + + var curry$6 = curry; + + var ATTR$1 = '\0_ec_dataZoom_roams'; + + + /** + * @public + * @param {module:echarts/ExtensionAPI} api + * @param {Object} dataZoomInfo + * @param {string} dataZoomInfo.coordId + * @param {Function} dataZoomInfo.containsPoint + * @param {Array.} dataZoomInfo.allCoordIds + * @param {string} dataZoomInfo.dataZoomId + * @param {number} dataZoomInfo.throttleRate + * @param {Function} dataZoomInfo.panGetRange + * @param {Function} dataZoomInfo.zoomGetRange + * @param {boolean} [dataZoomInfo.zoomLock] + * @param {boolean} [dataZoomInfo.disabled] + */ + function register$2(api, dataZoomInfo) { + var store = giveStore(api); + var theDataZoomId = dataZoomInfo.dataZoomId; + var theCoordId = dataZoomInfo.coordId; + + // Do clean when a dataZoom changes its target coordnate system. + // Avoid memory leak, dispose all not-used-registered. + each$1(store, function(record, coordId) { + var dataZoomInfos = record.dataZoomInfos; + if (dataZoomInfos[theDataZoomId] && + indexOf(dataZoomInfo.allCoordIds, theCoordId) < 0 + ) { + delete dataZoomInfos[theDataZoomId]; + record.count--; + } + }); + + cleanStore(store); + + var record = store[theCoordId]; + // Create if needed. + if (!record) { + record = store[theCoordId] = { + coordId: theCoordId, + dataZoomInfos: {}, + count: 0 + }; + record.controller = createController(api, record); + record.dispatchAction = curry(dispatchAction$1, api); + } + + // Update reference of dataZoom. + !(record.dataZoomInfos[theDataZoomId]) && record.count++; + record.dataZoomInfos[theDataZoomId] = dataZoomInfo; + + var controllerParams = mergeControllerParams(record.dataZoomInfos); + record.controller.enable(controllerParams.controlType, controllerParams.opt); + + // Consider resize, area should be always updated. + record.controller.setPointerChecker(dataZoomInfo.containsPoint); + + // Update throttle. + createOrUpdate( + record, + 'dispatchAction', + dataZoomInfo.throttleRate, + 'fixRate' + ); + } + + /** + * @public + * @param {module:echarts/ExtensionAPI} api + * @param {string} dataZoomId + */ + function unregister$1(api, dataZoomId) { + var store = giveStore(api); + + each$1(store, function(record) { + record.controller.dispose(); + var dataZoomInfos = record.dataZoomInfos; + if (dataZoomInfos[dataZoomId]) { + delete dataZoomInfos[dataZoomId]; + record.count--; + } + }); + + cleanStore(store); + } + + /** + * @public + */ + function generateCoordId(coordModel) { + return coordModel.type + '\0_' + coordModel.id; + } + + /** + * Key: coordId, value: {dataZoomInfos: [], count, controller} + * @type {Array.} + */ + function giveStore(api) { + // Mount store on zrender instance, so that we do not + // need to worry about dispose. + var zr = api.getZr(); + return zr[ATTR$1] || (zr[ATTR$1] = {}); + } + + function createController(api, newRecord) { + var controller = new RoamController(api.getZr()); + controller.on('pan', curry$6(onPan, newRecord)); + controller.on('zoom', curry$6(onZoom, newRecord)); + + return controller; + } + + function cleanStore(store) { + each$1(store, function(record, coordId) { + if (!record.count) { + record.controller.dispose(); + delete store[coordId]; + } + }); + } + + function onPan(record, dx, dy, oldX, oldY, newX, newY) { + wrapAndDispatch(record, function(info) { + return info.panGetRange(record.controller, dx, dy, oldX, oldY, newX, newY); + }); + } + + function onZoom(record, scale, mouseX, mouseY) { + wrapAndDispatch(record, function(info) { + return info.zoomGetRange(record.controller, scale, mouseX, mouseY); + }); + } + + function wrapAndDispatch(record, getRange) { + var batch = []; + + each$1(record.dataZoomInfos, function(info) { + var range = getRange(info); + !info.disabled && range && batch.push({ + dataZoomId: info.dataZoomId, + start: range[0], + end: range[1] + }); + }); + + batch.length && record.dispatchAction(batch); + } + + /** + * This action will be throttled. + */ + function dispatchAction$1(api, batch) { + api.dispatchAction({ + type: 'dataZoom', + batch: batch + }); + } + + /** + * Merge roamController settings when multiple dataZooms share one roamController. + */ + function mergeControllerParams(dataZoomInfos) { + var controlType; + var opt = {}; + // DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated + // as string, it is probably revert to reserved word by compress tool. See #7411. + var prefix = 'type_'; + var typePriority = { + 'type_true': 2, + 'type_move': 1, + 'type_false': 0, + 'type_undefined': -1 + }; + each$1(dataZoomInfos, function(dataZoomInfo) { + var oneType = dataZoomInfo.disabled ? false : dataZoomInfo.zoomLock ? 'move' : true; + if (typePriority[prefix + oneType] > typePriority[prefix + controlType]) { + controlType = oneType; + } + // Do not support that different 'shift'/'ctrl'/'alt' setting used in one coord sys. + extend(opt, dataZoomInfo.roamControllerOpt); + }); + + return { + controlType: controlType, + opt: opt + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var bind$5 = bind; + + var InsideZoomView = DataZoomView.extend({ + + type: 'dataZoom.inside', + + /** + * @override + */ + init: function(ecModel, api) { + /** + * 'throttle' is used in this.dispatchAction, so we save range + * to avoid missing some 'pan' info. + * @private + * @type {Array.} + */ + this._range; + }, + + /** + * @override + */ + render: function(dataZoomModel, ecModel, api, payload) { + InsideZoomView.superApply(this, 'render', arguments); + + // Hance the `throttle` util ensures to preserve command order, + // here simply updating range all the time will not cause missing + // any of the the roam change. + this._range = dataZoomModel.getPercentRange(); + + // Reset controllers. + each$1(this.getTargetCoordInfo(), function(coordInfoList, coordSysName) { + + var allCoordIds = map(coordInfoList, function(coordInfo) { + return generateCoordId(coordInfo.model); + }); + + each$1(coordInfoList, function(coordInfo) { + var coordModel = coordInfo.model; + var dataZoomOption = dataZoomModel.option; + + register$2( + api, { + coordId: generateCoordId(coordModel), + allCoordIds: allCoordIds, + containsPoint: function(e, x, y) { + return coordModel.coordinateSystem.containPoint([x, y]); + }, + dataZoomId: dataZoomModel.id, + throttleRate: dataZoomModel.get('throttle', true), + panGetRange: bind$5(this._onPan, this, coordInfo, coordSysName), + zoomGetRange: bind$5(this._onZoom, this, coordInfo, coordSysName), + zoomLock: dataZoomOption.zoomLock, + disabled: dataZoomOption.disabled, + roamControllerOpt: { + zoomOnMouseWheel: dataZoomOption.zoomOnMouseWheel, + moveOnMouseMove: dataZoomOption.moveOnMouseMove, + preventDefaultMouseMove: dataZoomOption.preventDefaultMouseMove + } + } + ); + }, this); + + }, this); + }, + + /** + * @override + */ + dispose: function() { + unregister$1(this.api, this.dataZoomModel.id); + InsideZoomView.superApply(this, 'dispose', arguments); + this._range = null; + }, + + /** + * @private + */ + _onPan: function(coordInfo, coordSysName, controller, dx, dy, oldX, oldY, newX, newY) { + var lastRange = this._range; + var range = lastRange.slice(); + + // Calculate transform by the first axis. + var axisModel = coordInfo.axisModels[0]; + if (!axisModel) { + return; + } + + var directionInfo = getDirectionInfo[coordSysName]( + [oldX, oldY], [newX, newY], axisModel, controller, coordInfo + ); + + var percentDelta = directionInfo.signal * + (range[1] - range[0]) * + directionInfo.pixel / directionInfo.pixelLength; + + sliderMove(percentDelta, range, [0, 100], 'all'); + + this._range = range; + + if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) { + return range; + } + }, + + /** + * @private + */ + _onZoom: function(coordInfo, coordSysName, controller, scale, mouseX, mouseY) { + var lastRange = this._range; + var range = lastRange.slice(); + + // Calculate transform by the first axis. + var axisModel = coordInfo.axisModels[0]; + if (!axisModel) { + return; + } + + var directionInfo = getDirectionInfo[coordSysName]( + null, [mouseX, mouseY], axisModel, controller, coordInfo + ); + var percentPoint = ( + directionInfo.signal > 0 ? + (directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel) : + (directionInfo.pixel - directionInfo.pixelStart) + ) / directionInfo.pixelLength * (range[1] - range[0]) + range[0]; + + scale = Math.max(1 / scale, 0); + range[0] = (range[0] - percentPoint) * scale + percentPoint; + range[1] = (range[1] - percentPoint) * scale + percentPoint; + + // Restrict range. + var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan(); + + sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan); + + this._range = range; + + if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) { + return range; + } + } + + }); + + var getDirectionInfo = { + + grid: function(oldPoint, newPoint, axisModel, controller, coordInfo) { + var axis = axisModel.axis; + var ret = {}; + var rect = coordInfo.model.coordinateSystem.getRect(); + oldPoint = oldPoint || [0, 0]; + + if (axis.dim === 'x') { + ret.pixel = newPoint[0] - oldPoint[0]; + ret.pixelLength = rect.width; + ret.pixelStart = rect.x; + ret.signal = axis.inverse ? 1 : -1; + } else { // axis.dim === 'y' + ret.pixel = newPoint[1] - oldPoint[1]; + ret.pixelLength = rect.height; + ret.pixelStart = rect.y; + ret.signal = axis.inverse ? -1 : 1; + } + + return ret; + }, + + polar: function(oldPoint, newPoint, axisModel, controller, coordInfo) { + var axis = axisModel.axis; + var ret = {}; + var polar = coordInfo.model.coordinateSystem; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var angleExtent = polar.getAngleAxis().getExtent(); + + oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0]; + newPoint = polar.pointToCoord(newPoint); + + if (axisModel.mainType === 'radiusAxis') { + ret.pixel = newPoint[0] - oldPoint[0]; + // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]); + // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]); + ret.pixelLength = radiusExtent[1] - radiusExtent[0]; + ret.pixelStart = radiusExtent[0]; + ret.signal = axis.inverse ? 1 : -1; + } else { // 'angleAxis' + ret.pixel = newPoint[1] - oldPoint[1]; + // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]); + // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]); + ret.pixelLength = angleExtent[1] - angleExtent[0]; + ret.pixelStart = angleExtent[0]; + ret.signal = axis.inverse ? -1 : 1; + } + + return ret; + }, + + singleAxis: function(oldPoint, newPoint, axisModel, controller, coordInfo) { + var axis = axisModel.axis; + var rect = coordInfo.model.coordinateSystem.getRect(); + var ret = {}; + + oldPoint = oldPoint || [0, 0]; + + if (axis.orient === 'horizontal') { + ret.pixel = newPoint[0] - oldPoint[0]; + ret.pixelLength = rect.width; + ret.pixelStart = rect.x; + ret.signal = axis.inverse ? 1 : -1; + } else { // 'vertical' + ret.pixel = newPoint[1] - oldPoint[1]; + ret.pixelLength = rect.height; + ret.pixelStart = rect.y; + ret.signal = axis.inverse ? -1 : 1; + } + + return ret; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerProcessor({ + + // `dataZoomProcessor` will only be performed in needed series. Consider if + // there is a line series and a pie series, it is better not to update the + // line series if only pie series is needed to be updated. + getTargetSeries: function(ecModel) { + var seriesModelMap = createHashMap(); + + ecModel.eachComponent('dataZoom', function(dataZoomModel) { + dataZoomModel.eachTargetAxis(function(dimNames, axisIndex, dataZoomModel) { + var axisProxy = dataZoomModel.getAxisProxy(dimNames.name, axisIndex); + each$1(axisProxy.getTargetSeriesModels(), function(seriesModel) { + seriesModelMap.set(seriesModel.uid, seriesModel); + }); + }); + }); + + return seriesModelMap; + }, + + modifyOutputEnd: true, + + // Consider appendData, where filter should be performed. Because data process is + // in block mode currently, it is not need to worry about that the overallProgress + // execute every frame. + overallReset: function(ecModel, api) { + + ecModel.eachComponent('dataZoom', function(dataZoomModel) { + // We calculate window and reset axis here but not in model + // init stage and not after action dispatch handler, because + // reset should be called after seriesData.restoreData. + dataZoomModel.eachTargetAxis(function(dimNames, axisIndex, dataZoomModel) { + dataZoomModel.getAxisProxy(dimNames.name, axisIndex).reset(dataZoomModel, api); + }); + + // Caution: data zoom filtering is order sensitive when using + // percent range and no min/max/scale set on axis. + // For example, we have dataZoom definition: + // [ + // {xAxisIndex: 0, start: 30, end: 70}, + // {yAxisIndex: 0, start: 20, end: 80} + // ] + // In this case, [20, 80] of y-dataZoom should be based on data + // that have filtered by x-dataZoom using range of [30, 70], + // but should not be based on full raw data. Thus sliding + // x-dataZoom will change both ranges of xAxis and yAxis, + // while sliding y-dataZoom will only change the range of yAxis. + // So we should filter x-axis after reset x-axis immediately, + // and then reset y-axis and filter y-axis. + dataZoomModel.eachTargetAxis(function(dimNames, axisIndex, dataZoomModel) { + dataZoomModel.getAxisProxy(dimNames.name, axisIndex).filterData(dataZoomModel, api); + }); + }); + + ecModel.eachComponent('dataZoom', function(dataZoomModel) { + // Fullfill all of the range props so that user + // is able to get them from chart.getOption(). + var axisProxy = dataZoomModel.findRepresentativeAxisProxy(); + var percentRange = axisProxy.getDataPercentWindow(); + var valueRange = axisProxy.getDataValueWindow(); + + dataZoomModel.setRawRange({ + start: percentRange[0], + end: percentRange[1], + startValue: valueRange[0], + endValue: valueRange[1] + }, true); + }); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerAction('dataZoom', function(payload, ecModel) { + + var linkedNodesFinder = createLinkedNodesFinder( + bind(ecModel.eachComponent, ecModel, 'dataZoom'), + eachAxisDim$1, + function(model, dimNames) { + return model.get(dimNames.axisIndex); + } + ); + + var effectedModels = []; + + ecModel.eachComponent({ + mainType: 'dataZoom', + query: payload + }, + function(model, index) { + effectedModels.push.apply( + effectedModels, linkedNodesFinder(model).nodes + ); + } + ); + + each$1(effectedModels, function(dataZoomModel, index) { + dataZoomModel.setRawRange({ + start: payload.start, + end: payload.end, + startValue: payload.startValue, + endValue: payload.endValue + }); + }); + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * DataZoom component entry + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$24 = each$1; + + var preprocessor$2 = function(option) { + var visualMap = option && option.visualMap; + + if (!isArray(visualMap)) { + visualMap = visualMap ? [visualMap] : []; + } + + each$24(visualMap, function(opt) { + if (!opt) { + return; + } + + // rename splitList to pieces + if (has$1(opt, 'splitList') && !has$1(opt, 'pieces')) { + opt.pieces = opt.splitList; + delete opt.splitList; + } + + var pieces = opt.pieces; + if (pieces && isArray(pieces)) { + each$24(pieces, function(piece) { + if (isObject$1(piece)) { + if (has$1(piece, 'start') && !has$1(piece, 'min')) { + piece.min = piece.start; + } + if (has$1(piece, 'end') && !has$1(piece, 'max')) { + piece.max = piece.end; + } + } + }); + } + }); + }; + + function has$1(obj, name) { + return obj && obj.hasOwnProperty && obj.hasOwnProperty(name); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + ComponentModel.registerSubTypeDefaulter('visualMap', function(option) { + // Compatible with ec2, when splitNumber === 0, continuous visualMap will be used. + return ( + !option.categories && + ( + !( + option.pieces ? + option.pieces.length > 0 : + option.splitNumber > 0 + ) || + option.calculable + ) + ) ? + 'continuous' : 'piecewise'; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var VISUAL_PRIORITY = PRIORITY.VISUAL.COMPONENT; + + registerVisual(VISUAL_PRIORITY, { + createOnAllSeries: true, + reset: function(seriesModel, ecModel) { + var resetDefines = []; + ecModel.eachComponent('visualMap', function(visualMapModel) { + var pipelineContext = seriesModel.pipelineContext; + if (!visualMapModel.isTargetSeries(seriesModel) || + (pipelineContext && pipelineContext.large) + ) { + return; + } + + resetDefines.push(incrementalApplyVisual( + visualMapModel.stateList, + visualMapModel.targetVisuals, + bind(visualMapModel.getValueState, visualMapModel), + visualMapModel.getDataDimension(seriesModel.getData()) + )); + }); + + return resetDefines; + } + }); + + // Only support color. + registerVisual(VISUAL_PRIORITY, { + createOnAllSeries: true, + reset: function(seriesModel, ecModel) { + var data = seriesModel.getData(); + var visualMetaList = []; + + ecModel.eachComponent('visualMap', function(visualMapModel) { + if (visualMapModel.isTargetSeries(seriesModel)) { + var visualMeta = visualMapModel.getVisualMeta( + bind(getColorVisual, null, seriesModel, visualMapModel) + ) || { + stops: [], + outerColors: [] + }; + + var concreteDim = visualMapModel.getDataDimension(data); + var dimInfo = data.getDimensionInfo(concreteDim); + if (dimInfo != null) { + // visualMeta.dimension should be dimension index, but not concrete dimension. + visualMeta.dimension = dimInfo.index; + visualMetaList.push(visualMeta); + } + } + }); + + // console.log(JSON.stringify(visualMetaList.map(a => a.stops))); + seriesModel.getData().setVisual('visualMeta', visualMetaList); + } + }); + + // FIXME + // performance and export for heatmap? + // value can be Infinity or -Infinity + function getColorVisual(seriesModel, visualMapModel, value, valueState) { + var mappings = visualMapModel.targetVisuals[valueState]; + var visualTypes = VisualMapping.prepareVisualTypes(mappings); + var resultVisual = { + color: seriesModel.getData().getVisual('color') // default color. + }; + + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + var mapping = mappings[ + type === 'opacity' ? '__alphaForOpacity' : type + ]; + mapping && mapping.applyVisual(value, getVisual, setVisual); + } + + return resultVisual.color; + + function getVisual(key) { + return resultVisual[key]; + } + + function setVisual(key, value) { + resultVisual[key] = value; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @file Visual mapping. + */ + + var visualDefault = { + + /** + * @public + */ + get: function(visualType, key, isCategory) { + var value = clone( + (defaultOption$3[visualType] || {})[key] + ); + + return isCategory ? + (isArray(value) ? value[value.length - 1] : value) : + value; + } + + }; + + var defaultOption$3 = { + + color: { + active: ['#006edd', '#e0ffff'], + inactive: ['rgba(0,0,0,0)'] + }, + + colorHue: { + active: [0, 360], + inactive: [0, 0] + }, + + colorSaturation: { + active: [0.3, 1], + inactive: [0, 0] + }, + + colorLightness: { + active: [0.9, 0.5], + inactive: [0, 0] + }, + + colorAlpha: { + active: [0.3, 1], + inactive: [0, 0] + }, + + opacity: { + active: [0.3, 1], + inactive: [0, 0] + }, + + symbol: { + active: ['circle', 'roundRect', 'diamond'], + inactive: ['none'] + }, + + symbolSize: { + active: [10, 50], + inactive: [0, 0] + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var mapVisual$2 = VisualMapping.mapVisual; + var eachVisual = VisualMapping.eachVisual; + var isArray$3 = isArray; + var each$25 = each$1; + var asc$3 = asc; + var linearMap$2 = linearMap; + var noop$2 = noop; + + var VisualMapModel = extendComponentModel({ + + type: 'visualMap', + + dependencies: ['series'], + + /** + * @readOnly + * @type {Array.} + */ + stateList: ['inRange', 'outOfRange'], + + /** + * @readOnly + * @type {Array.} + */ + replacableOptionKeys: [ + 'inRange', 'outOfRange', 'target', 'controller', 'color' + ], + + /** + * [lowerBound, upperBound] + * + * @readOnly + * @type {Array.} + */ + dataBound: [-Infinity, Infinity], + + /** + * @readOnly + * @type {string|Object} + */ + layoutMode: { + type: 'box', + ignoreSize: true + }, + + /** + * @protected + */ + defaultOption: { + show: true, + + zlevel: 0, + z: 4, + + seriesIndex: 'all', // 'all' or null/undefined: all series. + // A number or an array of number: the specified series. + + // set min: 0, max: 200, only for campatible with ec2. + // In fact min max should not have default value. + min: 0, // min value, must specified if pieces is not specified. + max: 200, // max value, must specified if pieces is not specified. + + dimension: null, + inRange: null, // 'color', 'colorHue', 'colorSaturation', 'colorLightness', 'colorAlpha', + // 'symbol', 'symbolSize' + outOfRange: null, // 'color', 'colorHue', 'colorSaturation', + // 'colorLightness', 'colorAlpha', + // 'symbol', 'symbolSize' + + left: 0, // 'center' ¦ 'left' ¦ 'right' ¦ {number} (px) + right: null, // The same as left. + top: null, // 'top' ¦ 'bottom' ¦ 'center' ¦ {number} (px) + bottom: 0, // The same as top. + + itemWidth: null, + itemHeight: null, + inverse: false, + orient: 'vertical', // 'horizontal' ¦ 'vertical' + + backgroundColor: 'rgba(0,0,0,0)', + borderColor: '#ccc', // 值域边框颜色 + contentColor: '#5793f3', + inactiveColor: '#aaa', + borderWidth: 0, // 值域边框线宽,单位px,默认为0(无边框) + padding: 5, // 值域内边距,单位px,默认各方向内边距为5, + // 接受数组分别设定上右下左边距,同css + textGap: 10, // + precision: 0, // 小数精度,默认为0,无小数点 + color: null, //颜色(deprecated,兼容ec2,顺序同pieces,不同于inRange/outOfRange) + + formatter: null, + text: null, // 文本,如['高', '低'],兼容ec2,text[0]对应高值,text[1]对应低值 + textStyle: { + color: '#333' // 值域文字颜色 + } + }, + + /** + * @protected + */ + init: function(option, parentModel, ecModel) { + + /** + * @private + * @type {Array.} + */ + this._dataExtent; + + /** + * @readOnly + */ + this.targetVisuals = {}; + + /** + * @readOnly + */ + this.controllerVisuals = {}; + + /** + * @readOnly + */ + this.textStyleModel; + + /** + * [width, height] + * @readOnly + * @type {Array.} + */ + this.itemSize; + + this.mergeDefaultAndTheme(option, ecModel); + }, + + /** + * @protected + */ + optionUpdated: function(newOption, isInit) { + var thisOption = this.option; + + // FIXME + // necessary? + // Disable realtime view update if canvas is not supported. + if (!env$1.canvasSupported) { + thisOption.realtime = false; + } + + !isInit && replaceVisualOption( + thisOption, newOption, this.replacableOptionKeys + ); + + this.textStyleModel = this.getModel('textStyle'); + + this.resetItemSize(); + + this.completeVisualOption(); + }, + + /** + * @protected + */ + resetVisual: function(supplementVisualOption) { + var stateList = this.stateList; + supplementVisualOption = bind(supplementVisualOption, this); + + this.controllerVisuals = createVisualMappings( + this.option.controller, stateList, supplementVisualOption + ); + this.targetVisuals = createVisualMappings( + this.option.target, stateList, supplementVisualOption + ); + }, + + /** + * @protected + * @return {Array.} An array of series indices. + */ + getTargetSeriesIndices: function() { + var optionSeriesIndex = this.option.seriesIndex; + var seriesIndices = []; + + if (optionSeriesIndex == null || optionSeriesIndex === 'all') { + this.ecModel.eachSeries(function(seriesModel, index) { + seriesIndices.push(index); + }); + } else { + seriesIndices = normalizeToArray(optionSeriesIndex); + } + + return seriesIndices; + }, + + /** + * @public + */ + eachTargetSeries: function(callback, context) { + each$1(this.getTargetSeriesIndices(), function(seriesIndex) { + callback.call(context, this.ecModel.getSeriesByIndex(seriesIndex)); + }, this); + }, + + /** + * @pubilc + */ + isTargetSeries: function(seriesModel) { + var is = false; + this.eachTargetSeries(function(model) { + model === seriesModel && (is = true); + }); + return is; + }, + + /** + * @example + * this.formatValueText(someVal); // format single numeric value to text. + * this.formatValueText(someVal, true); // format single category value to text. + * this.formatValueText([min, max]); // format numeric min-max to text. + * this.formatValueText([this.dataBound[0], max]); // using data lower bound. + * this.formatValueText([min, this.dataBound[1]]); // using data upper bound. + * + * @param {number|Array.} value Real value, or this.dataBound[0 or 1]. + * @param {boolean} [isCategory=false] Only available when value is number. + * @param {Array.} edgeSymbols Open-close symbol when value is interval. + * @return {string} + * @protected + */ + formatValueText: function(value, isCategory, edgeSymbols) { + var option = this.option; + var precision = option.precision; + var dataBound = this.dataBound; + var formatter = option.formatter; + var isMinMax; + var textValue; + edgeSymbols = edgeSymbols || ['<', '>']; + + if (isArray(value)) { + value = value.slice(); + isMinMax = true; + } + + textValue = isCategory ? + value : + (isMinMax ? + [toFixed(value[0]), toFixed(value[1])] : + toFixed(value) + ); + + if (isString(formatter)) { + return formatter + .replace('{value}', isMinMax ? textValue[0] : textValue) + .replace('{value2}', isMinMax ? textValue[1] : textValue); + } else if (isFunction$1(formatter)) { + return isMinMax ? + formatter(value[0], value[1]) : + formatter(value); + } + + if (isMinMax) { + if (value[0] === dataBound[0]) { + return edgeSymbols[0] + ' ' + textValue[1]; + } else if (value[1] === dataBound[1]) { + return edgeSymbols[1] + ' ' + textValue[0]; + } else { + return textValue[0] + ' - ' + textValue[1]; + } + } else { // Format single value (includes category case). + return textValue; + } + + function toFixed(val) { + return val === dataBound[0] ? + 'min' : + val === dataBound[1] ? + 'max' : + (+val).toFixed(Math.min(precision, 20)); + } + }, + + /** + * @protected + */ + resetExtent: function() { + var thisOption = this.option; + + // Can not calculate data extent by data here. + // Because series and data may be modified in processing stage. + // So we do not support the feature "auto min/max". + + var extent = asc$3([thisOption.min, thisOption.max]); + + this._dataExtent = extent; + }, + + /** + * @public + * @param {module:echarts/data/List} list + * @return {string} Concrete dimention. If return null/undefined, + * no dimension used. + */ + getDataDimension: function(list) { + var optDim = this.option.dimension; + var listDimensions = list.dimensions; + if (optDim == null && !listDimensions.length) { + return; + } + + if (optDim != null) { + return list.getDimension(optDim); + } + + var dimNames = list.dimensions; + for (var i = dimNames.length - 1; i >= 0; i--) { + var dimName = dimNames[i]; + var dimInfo = list.getDimensionInfo(dimName); + if (!dimInfo.isCalculationCoord) { + return dimName; + } + } + }, + + /** + * @public + * @override + */ + getExtent: function() { + return this._dataExtent.slice(); + }, + + /** + * @protected + */ + completeVisualOption: function() { + var ecModel = this.ecModel; + var thisOption = this.option; + var base = { + inRange: thisOption.inRange, + outOfRange: thisOption.outOfRange + }; + + var target = thisOption.target || (thisOption.target = {}); + var controller = thisOption.controller || (thisOption.controller = {}); + + merge(target, base); // Do not override + merge(controller, base); // Do not override + + var isCategory = this.isCategory(); + + completeSingle.call(this, target); + completeSingle.call(this, controller); + completeInactive.call(this, target, 'inRange', 'outOfRange'); + // completeInactive.call(this, target, 'outOfRange', 'inRange'); + completeController.call(this, controller); + + function completeSingle(base) { + // Compatible with ec2 dataRange.color. + // The mapping order of dataRange.color is: [high value, ..., low value] + // whereas inRange.color and outOfRange.color is [low value, ..., high value] + // Notice: ec2 has no inverse. + if (isArray$3(thisOption.color) + // If there has been inRange: {symbol: ...}, adding color is a mistake. + // So adding color only when no inRange defined. + && + !base.inRange + ) { + base.inRange = { + color: thisOption.color.slice().reverse() + }; + } + + // Compatible with previous logic, always give a defautl color, otherwise + // simple config with no inRange and outOfRange will not work. + // Originally we use visualMap.color as the default color, but setOption at + // the second time the default color will be erased. So we change to use + // constant DEFAULT_COLOR. + // If user do not want the defualt color, set inRange: {color: null}. + base.inRange = base.inRange || { + color: ecModel.get('gradientColor') + }; + + // If using shortcut like: {inRange: 'symbol'}, complete default value. + each$25(this.stateList, function(state) { + var visualType = base[state]; + + if (isString(visualType)) { + var defa = visualDefault.get(visualType, 'active', isCategory); + if (defa) { + base[state] = {}; + base[state][visualType] = defa; + } else { + // Mark as not specified. + delete base[state]; + } + } + }, this); + } + + function completeInactive(base, stateExist, stateAbsent) { + var optExist = base[stateExist]; + var optAbsent = base[stateAbsent]; + + if (optExist && !optAbsent) { + optAbsent = base[stateAbsent] = {}; + each$25(optExist, function(visualData, visualType) { + if (!VisualMapping.isValidType(visualType)) { + return; + } + + var defa = visualDefault.get(visualType, 'inactive', isCategory); + + if (defa != null) { + optAbsent[visualType] = defa; + + // Compatibable with ec2: + // Only inactive color to rgba(0,0,0,0) can not + // make label transparent, so use opacity also. + if (visualType === 'color' && + !optAbsent.hasOwnProperty('opacity') && + !optAbsent.hasOwnProperty('colorAlpha') + ) { + optAbsent.opacity = [0, 0]; + } + } + }); + } + } + + function completeController(controller) { + var symbolExists = (controller.inRange || {}).symbol || + (controller.outOfRange || {}).symbol; + var symbolSizeExists = (controller.inRange || {}).symbolSize || + (controller.outOfRange || {}).symbolSize; + var inactiveColor = this.get('inactiveColor'); + + each$25(this.stateList, function(state) { + + var itemSize = this.itemSize; + var visuals = controller[state]; + + // Set inactive color for controller if no other color + // attr (like colorAlpha) specified. + if (!visuals) { + visuals = controller[state] = { + color: isCategory ? inactiveColor : [inactiveColor] + }; + } + + // Consistent symbol and symbolSize if not specified. + if (visuals.symbol == null) { + visuals.symbol = symbolExists && + clone(symbolExists) || + (isCategory ? 'roundRect' : ['roundRect']); + } + if (visuals.symbolSize == null) { + visuals.symbolSize = symbolSizeExists && + clone(symbolSizeExists) || + (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]); + } + + // Filter square and none. + visuals.symbol = mapVisual$2(visuals.symbol, function(symbol) { + return (symbol === 'none' || symbol === 'square') ? 'roundRect' : symbol; + }); + + // Normalize symbolSize + var symbolSize = visuals.symbolSize; + + if (symbolSize != null) { + var max = -Infinity; + // symbolSize can be object when categories defined. + eachVisual(symbolSize, function(value) { + value > max && (max = value); + }); + visuals.symbolSize = mapVisual$2(symbolSize, function(value) { + return linearMap$2(value, [0, max], [0, itemSize[0]], true); + }); + } + + }, this); + } + }, + + /** + * @protected + */ + resetItemSize: function() { + this.itemSize = [ + parseFloat(this.get('itemWidth')), + parseFloat(this.get('itemHeight')) + ]; + }, + + /** + * @public + */ + isCategory: function() { + return !!this.option.categories; + }, + + /** + * @public + * @abstract + */ + setSelected: noop$2, + + /** + * @public + * @abstract + * @param {*|module:echarts/data/List} valueOrData + * @param {number} dataIndex + * @return {string} state See this.stateList + */ + getValueState: noop$2, + + /** + * FIXME + * Do not publish to thirt-part-dev temporarily + * util the interface is stable. (Should it return + * a function but not visual meta?) + * + * @pubilc + * @abstract + * @param {Function} getColorVisual + * params: value, valueState + * return: color + * @return {Object} visualMeta + * should includes {stops, outerColors} + * outerColor means [colorBeyondMinValue, colorBeyondMaxValue] + */ + getVisualMeta: noop$2 + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Constant + var DEFAULT_BAR_BOUND = [20, 140]; + + var ContinuousModel = VisualMapModel.extend({ + + type: 'visualMap.continuous', + + /** + * @protected + */ + defaultOption: { + align: 'auto', // 'auto', 'left', 'right', 'top', 'bottom' + calculable: false, // This prop effect default component type determine, + // See echarts/component/visualMap/typeDefaulter. + range: null, // selected range. In default case `range` is [min, max] + // and can auto change along with modification of min max, + // util use specifid a range. + realtime: true, // Whether realtime update. + itemHeight: null, // The length of the range control edge. + itemWidth: null, // The length of the other side. + hoverLink: true, // Enable hover highlight. + hoverLinkDataSize: null, // The size of hovered data. + hoverLinkOnHandle: null // Whether trigger hoverLink when hover handle. + // If not specified, follow the value of `realtime`. + }, + + /** + * @override + */ + optionUpdated: function(newOption, isInit) { + ContinuousModel.superApply(this, 'optionUpdated', arguments); + + this.resetExtent(); + + this.resetVisual(function(mappingOption) { + mappingOption.mappingMethod = 'linear'; + mappingOption.dataExtent = this.getExtent(); + }); + + this._resetRange(); + }, + + /** + * @protected + * @override + */ + resetItemSize: function() { + ContinuousModel.superApply(this, 'resetItemSize', arguments); + + var itemSize = this.itemSize; + + this._orient === 'horizontal' && itemSize.reverse(); + + (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]); + (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]); + }, + + /** + * @private + */ + _resetRange: function() { + var dataExtent = this.getExtent(); + var range = this.option.range; + + if (!range || range.auto) { + // `range` should always be array (so we dont use other + // value like 'auto') for user-friend. (consider getOption). + dataExtent.auto = 1; + this.option.range = dataExtent; + } else if (isArray(range)) { + if (range[0] > range[1]) { + range.reverse(); + } + range[0] = Math.max(range[0], dataExtent[0]); + range[1] = Math.min(range[1], dataExtent[1]); + } + }, + + /** + * @protected + * @override + */ + completeVisualOption: function() { + VisualMapModel.prototype.completeVisualOption.apply(this, arguments); + + each$1(this.stateList, function(state) { + var symbolSize = this.option.controller[state].symbolSize; + if (symbolSize && symbolSize[0] !== symbolSize[1]) { + symbolSize[0] = 0; // For good looking. + } + }, this); + }, + + /** + * @override + */ + setSelected: function(selected) { + this.option.range = selected.slice(); + this._resetRange(); + }, + + /** + * @public + */ + getSelected: function() { + var dataExtent = this.getExtent(); + + var dataInterval = asc( + (this.get('range') || []).slice() + ); + + // Clamp + dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]); + dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]); + dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]); + dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]); + + return dataInterval; + }, + + /** + * @override + */ + getValueState: function(value) { + var range = this.option.range; + var dataExtent = this.getExtent(); + + // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'. + // range[1] is processed likewise. + return ( + (range[0] <= dataExtent[0] || range[0] <= value) && + (range[1] >= dataExtent[1] || value <= range[1]) + ) ? 'inRange' : 'outOfRange'; + }, + + /** + * @params {Array.} range target value: range[0] <= value && value <= range[1] + * @return {Array.} [{seriesId, dataIndices: >}, ...] + */ + findTargetDataIndices: function(range) { + var result = []; + + this.eachTargetSeries(function(seriesModel) { + var dataIndices = []; + var data = seriesModel.getData(); + + data.each(this.getDataDimension(data), function(value, dataIndex) { + range[0] <= value && value <= range[1] && dataIndices.push(dataIndex); + }, this); + + result.push({ + seriesId: seriesModel.id, + dataIndex: dataIndices + }); + }, this); + + return result; + }, + + /** + * @implement + */ + getVisualMeta: function(getColorVisual) { + var oVals = getColorStopValues(this, 'outOfRange', this.getExtent()); + var iVals = getColorStopValues(this, 'inRange', this.option.range.slice()); + var stops = []; + + function setStop(value, valueState) { + stops.push({ + value: value, + color: getColorVisual(value, valueState) + }); + } + + // Format to: outOfRange -- inRange -- outOfRange. + var iIdx = 0; + var oIdx = 0; + var iLen = iVals.length; + var oLen = oVals.length; + + for (; oIdx < oLen && (!iVals.length || oVals[oIdx] <= iVals[0]); oIdx++) { + // If oVal[oIdx] === iVals[iIdx], oVal[oIdx] should be ignored. + if (oVals[oIdx] < iVals[iIdx]) { + setStop(oVals[oIdx], 'outOfRange'); + } + } + for (var first = 1; iIdx < iLen; iIdx++, first = 0) { + // If range is full, value beyond min, max will be clamped. + // make a singularity + first && stops.length && setStop(iVals[iIdx], 'outOfRange'); + setStop(iVals[iIdx], 'inRange'); + } + for (var first = 1; oIdx < oLen; oIdx++) { + if (!iVals.length || iVals[iVals.length - 1] < oVals[oIdx]) { + // make a singularity + if (first) { + stops.length && setStop(stops[stops.length - 1].value, 'outOfRange'); + first = 0; + } + setStop(oVals[oIdx], 'outOfRange'); + } + } + + var stopsLen = stops.length; + + return { + stops: stops, + outerColors: [ + stopsLen ? stops[0].color : 'transparent', + stopsLen ? stops[stopsLen - 1].color : 'transparent' + ] + }; + } + + }); + + function getColorStopValues(visualMapModel, valueState, dataExtent) { + if (dataExtent[0] === dataExtent[1]) { + return dataExtent.slice(); + } + + // When using colorHue mapping, it is not linear color any more. + // Moreover, canvas gradient seems not to be accurate linear. + // FIXME + // Should be arbitrary value 100? or based on pixel size? + var count = 200; + var step = (dataExtent[1] - dataExtent[0]) / count; + + var value = dataExtent[0]; + var stopValues = []; + for (var i = 0; i <= count && value < dataExtent[1]; i++) { + stopValues.push(value); + value += step; + } + stopValues.push(dataExtent[1]); + + return stopValues; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var VisualMapView = extendComponentView({ + + type: 'visualMap', + + /** + * @readOnly + * @type {Object} + */ + autoPositionValues: { + left: 1, + right: 1, + top: 1, + bottom: 1 + }, + + init: function(ecModel, api) { + /** + * @readOnly + * @type {module:echarts/model/Global} + */ + this.ecModel = ecModel; + + /** + * @readOnly + * @type {module:echarts/ExtensionAPI} + */ + this.api = api; + + /** + * @readOnly + * @type {module:echarts/component/visualMap/visualMapModel} + */ + this.visualMapModel; + }, + + /** + * @protected + */ + render: function(visualMapModel, ecModel, api, payload) { + this.visualMapModel = visualMapModel; + + if (visualMapModel.get('show') === false) { + this.group.removeAll(); + return; + } + + this.doRender.apply(this, arguments); + }, + + /** + * @protected + */ + renderBackground: function(group) { + var visualMapModel = this.visualMapModel; + var padding = normalizeCssArray$1(visualMapModel.get('padding') || 0); + var rect = group.getBoundingRect(); + + group.add(new Rect({ + z2: -1, // Lay background rect on the lowest layer. + silent: true, + shape: { + x: rect.x - padding[3], + y: rect.y - padding[0], + width: rect.width + padding[3] + padding[1], + height: rect.height + padding[0] + padding[2] + }, + style: { + fill: visualMapModel.get('backgroundColor'), + stroke: visualMapModel.get('borderColor'), + lineWidth: visualMapModel.get('borderWidth') + } + })); + }, + + /** + * @protected + * @param {number} targetValue can be Infinity or -Infinity + * @param {string=} visualCluster Only can be 'color' 'opacity' 'symbol' 'symbolSize' + * @param {Object} [opts] + * @param {string=} [opts.forceState] Specify state, instead of using getValueState method. + * @param {string=} [opts.convertOpacityToAlpha=false] For color gradient in controller widget. + * @return {*} Visual value. + */ + getControllerVisual: function(targetValue, visualCluster, opts) { + opts = opts || {}; + + var forceState = opts.forceState; + var visualMapModel = this.visualMapModel; + var visualObj = {}; + + // Default values. + if (visualCluster === 'symbol') { + visualObj.symbol = visualMapModel.get('itemSymbol'); + } + if (visualCluster === 'color') { + var defaultColor = visualMapModel.get('contentColor'); + visualObj.color = defaultColor; + } + + function getter(key) { + return visualObj[key]; + } + + function setter(key, value) { + visualObj[key] = value; + } + + var mappings = visualMapModel.controllerVisuals[ + forceState || visualMapModel.getValueState(targetValue) + ]; + var visualTypes = VisualMapping.prepareVisualTypes(mappings); + + each$1(visualTypes, function(type) { + var visualMapping = mappings[type]; + if (opts.convertOpacityToAlpha && type === 'opacity') { + type = 'colorAlpha'; + visualMapping = mappings.__alphaForOpacity; + } + if (VisualMapping.dependsOn(type, visualCluster)) { + visualMapping && visualMapping.applyVisual( + targetValue, getter, setter + ); + } + }); + + return visualObj[visualCluster]; + }, + + /** + * @protected + */ + positionGroup: function(group) { + var model = this.visualMapModel; + var api = this.api; + + positionElement( + group, + model.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + } + ); + }, + + /** + * @protected + * @abstract + */ + doRender: noop + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * @param {module:echarts/component/visualMap/VisualMapModel} visualMapModel\ + * @param {module:echarts/ExtensionAPI} api + * @param {Array.} itemSize always [short, long] + * @return {string} 'left' or 'right' or 'top' or 'bottom' + */ + function getItemAlign(visualMapModel, api, itemSize) { + var modelOption = visualMapModel.option; + var itemAlign = modelOption.align; + + if (itemAlign != null && itemAlign !== 'auto') { + return itemAlign; + } + + // Auto decision align. + var ecSize = { + width: api.getWidth(), + height: api.getHeight() + }; + var realIndex = modelOption.orient === 'horizontal' ? 1 : 0; + + var paramsSet = [ + ['left', 'right', 'width'], + ['top', 'bottom', 'height'] + ]; + var reals = paramsSet[realIndex]; + var fakeValue = [0, null, 10]; + + var layoutInput = {}; + for (var i = 0; i < 3; i++) { + layoutInput[paramsSet[1 - realIndex][i]] = fakeValue[i]; + layoutInput[reals[i]] = i === 2 ? itemSize[0] : modelOption[reals[i]]; + } + + var rParam = [ + ['x', 'width', 3], + ['y', 'height', 0] + ][realIndex]; + var rect = getLayoutRect(layoutInput, ecSize, modelOption.padding); + + return reals[ + (rect.margin[rParam[2]] || 0) + rect[rParam[0]] + rect[rParam[1]] * 0.5 < + ecSize[rParam[1]] * 0.5 ? 0 : 1 + ]; + } + + /** + * Prepare dataIndex for outside usage, where dataIndex means rawIndex, and + * dataIndexInside means filtered index. + */ + function convertDataIndex(batch) { + each$1(batch || [], function(batchItem) { + if (batch.dataIndex != null) { + batch.dataIndexInside = batch.dataIndex; + batch.dataIndex = null; + } + }); + return batch; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var linearMap$3 = linearMap; + var each$26 = each$1; + var mathMin$7 = Math.min; + var mathMax$7 = Math.max; + + // Arbitrary value + var HOVER_LINK_SIZE = 12; + var HOVER_LINK_OUT = 6; + + // Notice: + // Any "interval" should be by the order of [low, high]. + // "handle0" (handleIndex === 0) maps to + // low data value: this._dataInterval[0] and has low coord. + // "handle1" (handleIndex === 1) maps to + // high data value: this._dataInterval[1] and has high coord. + // The logic of transform is implemented in this._createBarGroup. + + var ContinuousView = VisualMapView.extend({ + + type: 'visualMap.continuous', + + /** + * @override + */ + init: function() { + + ContinuousView.superApply(this, 'init', arguments); + + /** + * @private + */ + this._shapes = {}; + + /** + * @private + */ + this._dataInterval = []; + + /** + * @private + */ + this._handleEnds = []; + + /** + * @private + */ + this._orient; + + /** + * @private + */ + this._useHandle; + + /** + * @private + */ + this._hoverLinkDataIndices = []; + + /** + * @private + */ + this._dragging; + + /** + * @private + */ + this._hovering; + }, + + /** + * @protected + * @override + */ + doRender: function(visualMapModel, ecModel, api, payload) { + if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) { + this._buildView(); + } + }, + + /** + * @private + */ + _buildView: function() { + this.group.removeAll(); + + var visualMapModel = this.visualMapModel; + var thisGroup = this.group; + + this._orient = visualMapModel.get('orient'); + this._useHandle = visualMapModel.get('calculable'); + + this._resetInterval(); + + this._renderBar(thisGroup); + + var dataRangeText = visualMapModel.get('text'); + this._renderEndsText(thisGroup, dataRangeText, 0); + this._renderEndsText(thisGroup, dataRangeText, 1); + + // Do this for background size calculation. + this._updateView(true); + + // After updating view, inner shapes is built completely, + // and then background can be rendered. + this.renderBackground(thisGroup); + + // Real update view + this._updateView(); + + this._enableHoverLinkToSeries(); + this._enableHoverLinkFromSeries(); + + this.positionGroup(thisGroup); + }, + + /** + * @private + */ + _renderEndsText: function(group, dataRangeText, endsIndex) { + if (!dataRangeText) { + return; + } + + // Compatible with ec2, text[0] map to high value, text[1] map low value. + var text = dataRangeText[1 - endsIndex]; + text = text != null ? text + '' : ''; + + var visualMapModel = this.visualMapModel; + var textGap = visualMapModel.get('textGap'); + var itemSize = visualMapModel.itemSize; + + var barGroup = this._shapes.barGroup; + var position = this._applyTransform( + [ + itemSize[0] / 2, + endsIndex === 0 ? -textGap : itemSize[1] + textGap + ], + barGroup + ); + var align = this._applyTransform( + endsIndex === 0 ? 'bottom' : 'top', + barGroup + ); + var orient = this._orient; + var textStyleModel = this.visualMapModel.textStyleModel; + + this.group.add(new Text({ + style: { + x: position[0], + y: position[1], + textVerticalAlign: orient === 'horizontal' ? 'middle' : align, + textAlign: orient === 'horizontal' ? align : 'center', + text: text, + textFont: textStyleModel.getFont(), + textFill: textStyleModel.getTextColor() + } + })); + }, + + /** + * @private + */ + _renderBar: function(targetGroup) { + var visualMapModel = this.visualMapModel; + var shapes = this._shapes; + var itemSize = visualMapModel.itemSize; + var orient = this._orient; + var useHandle = this._useHandle; + var itemAlign = getItemAlign(visualMapModel, this.api, itemSize); + var barGroup = shapes.barGroup = this._createBarGroup(itemAlign); + + // Bar + barGroup.add(shapes.outOfRange = createPolygon()); + barGroup.add(shapes.inRange = createPolygon( + null, + useHandle ? getCursor$1(this._orient) : null, + bind(this._dragHandle, this, 'all', false), + bind(this._dragHandle, this, 'all', true) + )); + + var textRect = visualMapModel.textStyleModel.getTextRect('国'); + var textSize = mathMax$7(textRect.width, textRect.height); + + // Handle + if (useHandle) { + shapes.handleThumbs = []; + shapes.handleLabels = []; + shapes.handleLabelPoints = []; + + this._createHandle(barGroup, 0, itemSize, textSize, orient, itemAlign); + this._createHandle(barGroup, 1, itemSize, textSize, orient, itemAlign); + } + + this._createIndicator(barGroup, itemSize, textSize, orient); + + targetGroup.add(barGroup); + }, + + /** + * @private + */ + _createHandle: function(barGroup, handleIndex, itemSize, textSize, orient) { + var onDrift = bind(this._dragHandle, this, handleIndex, false); + var onDragEnd = bind(this._dragHandle, this, handleIndex, true); + var handleThumb = createPolygon( + createHandlePoints(handleIndex, textSize), + getCursor$1(this._orient), + onDrift, + onDragEnd + ); + handleThumb.position[0] = itemSize[0]; + barGroup.add(handleThumb); + + // Text is always horizontal layout but should not be effected by + // transform (orient/inverse). So label is built separately but not + // use zrender/graphic/helper/RectText, and is located based on view + // group (according to handleLabelPoint) but not barGroup. + var textStyleModel = this.visualMapModel.textStyleModel; + var handleLabel = new Text({ + draggable: true, + drift: onDrift, + onmousemove: function(e) { + // Fot mobile devicem, prevent screen slider on the button. + stop(e.event); + }, + ondragend: onDragEnd, + style: { + x: 0, + y: 0, + text: '', + textFont: textStyleModel.getFont(), + textFill: textStyleModel.getTextColor() + } + }); + this.group.add(handleLabel); + + var handleLabelPoint = [ + orient === 'horizontal' ? + textSize / 2 : + textSize * 1.5, + orient === 'horizontal' ? + (handleIndex === 0 ? -(textSize * 1.5) : (textSize * 1.5)) : + (handleIndex === 0 ? -textSize / 2 : textSize / 2) + ]; + + var shapes = this._shapes; + shapes.handleThumbs[handleIndex] = handleThumb; + shapes.handleLabelPoints[handleIndex] = handleLabelPoint; + shapes.handleLabels[handleIndex] = handleLabel; + }, + + /** + * @private + */ + _createIndicator: function(barGroup, itemSize, textSize, orient) { + var indicator = createPolygon([ + [0, 0] + ], 'move'); + indicator.position[0] = itemSize[0]; + indicator.attr({ + invisible: true, + silent: true + }); + barGroup.add(indicator); + + var textStyleModel = this.visualMapModel.textStyleModel; + var indicatorLabel = new Text({ + silent: true, + invisible: true, + style: { + x: 0, + y: 0, + text: '', + textFont: textStyleModel.getFont(), + textFill: textStyleModel.getTextColor() + } + }); + this.group.add(indicatorLabel); + + var indicatorLabelPoint = [ + orient === 'horizontal' ? textSize / 2 : HOVER_LINK_OUT + 3, + 0 + ]; + + var shapes = this._shapes; + shapes.indicator = indicator; + shapes.indicatorLabel = indicatorLabel; + shapes.indicatorLabelPoint = indicatorLabelPoint; + }, + + /** + * @private + */ + _dragHandle: function(handleIndex, isEnd, dx, dy) { + if (!this._useHandle) { + return; + } + + this._dragging = !isEnd; + + if (!isEnd) { + // Transform dx, dy to bar coordination. + var vertex = this._applyTransform([dx, dy], this._shapes.barGroup, true); + this._updateInterval(handleIndex, vertex[1]); + + // Considering realtime, update view should be executed + // before dispatch action. + this._updateView(); + } + + // dragEnd do not dispatch action when realtime. + if (isEnd === !this.visualMapModel.get('realtime')) { // jshint ignore:line + this.api.dispatchAction({ + type: 'selectDataRange', + from: this.uid, + visualMapId: this.visualMapModel.id, + selected: this._dataInterval.slice() + }); + } + + if (isEnd) { + !this._hovering && this._clearHoverLinkToSeries(); + } else if (useHoverLinkOnHandle(this.visualMapModel)) { + this._doHoverLinkToSeries(this._handleEnds[handleIndex], false); + } + }, + + /** + * @private + */ + _resetInterval: function() { + var visualMapModel = this.visualMapModel; + + var dataInterval = this._dataInterval = visualMapModel.getSelected(); + var dataExtent = visualMapModel.getExtent(); + var sizeExtent = [0, visualMapModel.itemSize[1]]; + + this._handleEnds = [ + linearMap$3(dataInterval[0], dataExtent, sizeExtent, true), + linearMap$3(dataInterval[1], dataExtent, sizeExtent, true) + ]; + }, + + /** + * @private + * @param {(number|string)} handleIndex 0 or 1 or 'all' + * @param {number} dx + * @param {number} dy + */ + _updateInterval: function(handleIndex, delta) { + delta = delta || 0; + var visualMapModel = this.visualMapModel; + var handleEnds = this._handleEnds; + var sizeExtent = [0, visualMapModel.itemSize[1]]; + + sliderMove( + delta, + handleEnds, + sizeExtent, + handleIndex, + // cross is forbiden + 0 + ); + + var dataExtent = visualMapModel.getExtent(); + // Update data interval. + this._dataInterval = [ + linearMap$3(handleEnds[0], sizeExtent, dataExtent, true), + linearMap$3(handleEnds[1], sizeExtent, dataExtent, true) + ]; + }, + + /** + * @private + */ + _updateView: function(forSketch) { + var visualMapModel = this.visualMapModel; + var dataExtent = visualMapModel.getExtent(); + var shapes = this._shapes; + + var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]]; + var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds; + + var visualInRange = this._createBarVisual( + this._dataInterval, dataExtent, inRangeHandleEnds, 'inRange' + ); + var visualOutOfRange = this._createBarVisual( + dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange' + ); + + shapes.inRange + .setStyle({ + fill: visualInRange.barColor, + opacity: visualInRange.opacity + }) + .setShape('points', visualInRange.barPoints); + shapes.outOfRange + .setStyle({ + fill: visualOutOfRange.barColor, + opacity: visualOutOfRange.opacity + }) + .setShape('points', visualOutOfRange.barPoints); + + this._updateHandle(inRangeHandleEnds, visualInRange); + }, + + /** + * @private + */ + _createBarVisual: function(dataInterval, dataExtent, handleEnds, forceState) { + var opts = { + forceState: forceState, + convertOpacityToAlpha: true + }; + var colorStops = this._makeColorGradient(dataInterval, opts); + + var symbolSizes = [ + this.getControllerVisual(dataInterval[0], 'symbolSize', opts), + this.getControllerVisual(dataInterval[1], 'symbolSize', opts) + ]; + var barPoints = this._createBarPoints(handleEnds, symbolSizes); + + return { + barColor: new LinearGradient(0, 0, 0, 1, colorStops), + barPoints: barPoints, + handlesColor: [ + colorStops[0].color, + colorStops[colorStops.length - 1].color + ] + }; + }, + + /** + * @private + */ + _makeColorGradient: function(dataInterval, opts) { + // Considering colorHue, which is not linear, so we have to sample + // to calculate gradient color stops, but not only caculate head + // and tail. + var sampleNumber = 100; // Arbitrary value. + var colorStops = []; + var step = (dataInterval[1] - dataInterval[0]) / sampleNumber; + + colorStops.push({ + color: this.getControllerVisual(dataInterval[0], 'color', opts), + offset: 0 + }); + + for (var i = 1; i < sampleNumber; i++) { + var currValue = dataInterval[0] + step * i; + if (currValue > dataInterval[1]) { + break; + } + colorStops.push({ + color: this.getControllerVisual(currValue, 'color', opts), + offset: i / sampleNumber + }); + } + + colorStops.push({ + color: this.getControllerVisual(dataInterval[1], 'color', opts), + offset: 1 + }); + + return colorStops; + }, + + /** + * @private + */ + _createBarPoints: function(handleEnds, symbolSizes) { + var itemSize = this.visualMapModel.itemSize; + + return [ + [itemSize[0] - symbolSizes[0], handleEnds[0]], + [itemSize[0], handleEnds[0]], + [itemSize[0], handleEnds[1]], + [itemSize[0] - symbolSizes[1], handleEnds[1]] + ]; + }, + + /** + * @private + */ + _createBarGroup: function(itemAlign) { + var orient = this._orient; + var inverse = this.visualMapModel.get('inverse'); + + return new Group( + (orient === 'horizontal' && !inverse) ? + { + scale: itemAlign === 'bottom' ? [1, 1] : [-1, 1], + rotation: Math.PI / 2 + } : + (orient === 'horizontal' && inverse) ? + { + scale: itemAlign === 'bottom' ? [-1, 1] : [1, 1], + rotation: -Math.PI / 2 + } : + (orient === 'vertical' && !inverse) ? + { + scale: itemAlign === 'left' ? [1, -1] : [-1, -1] + } : + { + scale: itemAlign === 'left' ? [1, 1] : [-1, 1] + } + ); + }, + + /** + * @private + */ + _updateHandle: function(handleEnds, visualInRange) { + if (!this._useHandle) { + return; + } + + var shapes = this._shapes; + var visualMapModel = this.visualMapModel; + var handleThumbs = shapes.handleThumbs; + var handleLabels = shapes.handleLabels; + + each$26([0, 1], function(handleIndex) { + var handleThumb = handleThumbs[handleIndex]; + handleThumb.setStyle('fill', visualInRange.handlesColor[handleIndex]); + handleThumb.position[1] = handleEnds[handleIndex]; + + // Update handle label position. + var textPoint = applyTransform$1( + shapes.handleLabelPoints[handleIndex], + getTransform(handleThumb, this.group) + ); + handleLabels[handleIndex].setStyle({ + x: textPoint[0], + y: textPoint[1], + text: visualMapModel.formatValueText(this._dataInterval[handleIndex]), + textVerticalAlign: 'middle', + textAlign: this._applyTransform( + this._orient === 'horizontal' ? + (handleIndex === 0 ? 'bottom' : 'top') : + 'left', + shapes.barGroup + ) + }); + }, this); + }, + + /** + * @private + * @param {number} cursorValue + * @param {number} textValue + * @param {string} [rangeSymbol] + * @param {number} [halfHoverLinkSize] + */ + _showIndicator: function(cursorValue, textValue, rangeSymbol, halfHoverLinkSize) { + var visualMapModel = this.visualMapModel; + var dataExtent = visualMapModel.getExtent(); + var itemSize = visualMapModel.itemSize; + var sizeExtent = [0, itemSize[1]]; + var pos = linearMap$3(cursorValue, dataExtent, sizeExtent, true); + + var shapes = this._shapes; + var indicator = shapes.indicator; + if (!indicator) { + return; + } + + indicator.position[1] = pos; + indicator.attr('invisible', false); + indicator.setShape('points', createIndicatorPoints( + !!rangeSymbol, halfHoverLinkSize, pos, itemSize[1] + )); + + var opts = { + convertOpacityToAlpha: true + }; + var color = this.getControllerVisual(cursorValue, 'color', opts); + indicator.setStyle('fill', color); + + // Update handle label position. + var textPoint = applyTransform$1( + shapes.indicatorLabelPoint, + getTransform(indicator, this.group) + ); + + var indicatorLabel = shapes.indicatorLabel; + indicatorLabel.attr('invisible', false); + var align = this._applyTransform('left', shapes.barGroup); + var orient = this._orient; + indicatorLabel.setStyle({ + text: (rangeSymbol ? rangeSymbol : '') + visualMapModel.formatValueText(textValue), + textVerticalAlign: orient === 'horizontal' ? align : 'middle', + textAlign: orient === 'horizontal' ? 'center' : align, + x: textPoint[0], + y: textPoint[1] + }); + }, + + /** + * @private + */ + _enableHoverLinkToSeries: function() { + var self = this; + this._shapes.barGroup + + .on('mousemove', function(e) { + self._hovering = true; + + if (!self._dragging) { + var itemSize = self.visualMapModel.itemSize; + var pos = self._applyTransform( + [e.offsetX, e.offsetY], self._shapes.barGroup, true, true + ); + // For hover link show when hover handle, which might be + // below or upper than sizeExtent. + pos[1] = mathMin$7(mathMax$7(0, pos[1]), itemSize[1]); + self._doHoverLinkToSeries( + pos[1], + 0 <= pos[0] && pos[0] <= itemSize[0] + ); + } + }) + + .on('mouseout', function() { + // When mouse is out of handle, hoverLink still need + // to be displayed when realtime is set as false. + self._hovering = false; + !self._dragging && self._clearHoverLinkToSeries(); + }); + }, + + /** + * @private + */ + _enableHoverLinkFromSeries: function() { + var zr = this.api.getZr(); + + if (this.visualMapModel.option.hoverLink) { + zr.on('mouseover', this._hoverLinkFromSeriesMouseOver, this); + zr.on('mouseout', this._hideIndicator, this); + } else { + this._clearHoverLinkFromSeries(); + } + }, + + /** + * @private + */ + _doHoverLinkToSeries: function(cursorPos, hoverOnBar) { + var visualMapModel = this.visualMapModel; + var itemSize = visualMapModel.itemSize; + + if (!visualMapModel.option.hoverLink) { + return; + } + + var sizeExtent = [0, itemSize[1]]; + var dataExtent = visualMapModel.getExtent(); + + // For hover link show when hover handle, which might be below or upper than sizeExtent. + cursorPos = mathMin$7(mathMax$7(sizeExtent[0], cursorPos), sizeExtent[1]); + + var halfHoverLinkSize = getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent); + var hoverRange = [cursorPos - halfHoverLinkSize, cursorPos + halfHoverLinkSize]; + var cursorValue = linearMap$3(cursorPos, sizeExtent, dataExtent, true); + var valueRange = [ + linearMap$3(hoverRange[0], sizeExtent, dataExtent, true), + linearMap$3(hoverRange[1], sizeExtent, dataExtent, true) + ]; + // Consider data range is out of visualMap range, see test/visualMap-continuous.html, + // where china and india has very large population. + hoverRange[0] < sizeExtent[0] && (valueRange[0] = -Infinity); + hoverRange[1] > sizeExtent[1] && (valueRange[1] = Infinity); + + // Do not show indicator when mouse is over handle, + // otherwise labels overlap, especially when dragging. + if (hoverOnBar) { + if (valueRange[0] === -Infinity) { + this._showIndicator(cursorValue, valueRange[1], '< ', halfHoverLinkSize); + } else if (valueRange[1] === Infinity) { + this._showIndicator(cursorValue, valueRange[0], '> ', halfHoverLinkSize); + } else { + this._showIndicator(cursorValue, cursorValue, '≈ ', halfHoverLinkSize); + } + } + + // When realtime is set as false, handles, which are in barGroup, + // also trigger hoverLink, which help user to realize where they + // focus on when dragging. (see test/heatmap-large.html) + // When realtime is set as true, highlight will not show when hover + // handle, because the label on handle, which displays a exact value + // but not range, might mislead users. + var oldBatch = this._hoverLinkDataIndices; + var newBatch = []; + if (hoverOnBar || useHoverLinkOnHandle(visualMapModel)) { + newBatch = this._hoverLinkDataIndices = visualMapModel.findTargetDataIndices(valueRange); + } + + var resultBatches = compressBatches(oldBatch, newBatch); + + this._dispatchHighDown('downplay', convertDataIndex(resultBatches[0])); + this._dispatchHighDown('highlight', convertDataIndex(resultBatches[1])); + }, + + /** + * @private + */ + _hoverLinkFromSeriesMouseOver: function(e) { + var el = e.target; + var visualMapModel = this.visualMapModel; + + if (!el || el.dataIndex == null) { + return; + } + + var dataModel = this.ecModel.getSeriesByIndex(el.seriesIndex); + + if (!visualMapModel.isTargetSeries(dataModel)) { + return; + } + + var data = dataModel.getData(el.dataType); + var value = data.get(visualMapModel.getDataDimension(data), el.dataIndex, true); + + if (!isNaN(value)) { + this._showIndicator(value, value); + } + }, + + /** + * @private + */ + _hideIndicator: function() { + var shapes = this._shapes; + shapes.indicator && shapes.indicator.attr('invisible', true); + shapes.indicatorLabel && shapes.indicatorLabel.attr('invisible', true); + }, + + /** + * @private + */ + _clearHoverLinkToSeries: function() { + this._hideIndicator(); + + var indices = this._hoverLinkDataIndices; + this._dispatchHighDown('downplay', convertDataIndex(indices)); + + indices.length = 0; + }, + + /** + * @private + */ + _clearHoverLinkFromSeries: function() { + this._hideIndicator(); + + var zr = this.api.getZr(); + zr.off('mouseover', this._hoverLinkFromSeriesMouseOver); + zr.off('mouseout', this._hideIndicator); + }, + + /** + * @private + */ + _applyTransform: function(vertex, element, inverse, global) { + var transform = getTransform(element, global ? null : this.group); + + return graphic[ + isArray(vertex) ? 'applyTransform' : 'transformDirection' + ](vertex, transform, inverse); + }, + + /** + * @private + */ + _dispatchHighDown: function(type, batch) { + batch && batch.length && this.api.dispatchAction({ + type: type, + batch: batch + }); + }, + + /** + * @override + */ + dispose: function() { + this._clearHoverLinkFromSeries(); + this._clearHoverLinkToSeries(); + }, + + /** + * @override + */ + remove: function() { + this._clearHoverLinkFromSeries(); + this._clearHoverLinkToSeries(); + } + + }); + + function createPolygon(points, cursor, onDrift, onDragEnd) { + return new Polygon({ + shape: { + points: points + }, + draggable: !!onDrift, + cursor: cursor, + drift: onDrift, + onmousemove: function(e) { + // Fot mobile devicem, prevent screen slider on the button. + stop(e.event); + }, + ondragend: onDragEnd + }); + } + + function createHandlePoints(handleIndex, textSize) { + return handleIndex === 0 ? + [ + [0, 0], + [textSize, 0], + [textSize, -textSize] + ] : + [ + [0, 0], + [textSize, 0], + [textSize, textSize] + ]; + } + + function createIndicatorPoints(isRange, halfHoverLinkSize, pos, extentMax) { + return isRange ? + [ // indicate range + [0, -mathMin$7(halfHoverLinkSize, mathMax$7(pos, 0))], + [HOVER_LINK_OUT, 0], + [0, mathMin$7(halfHoverLinkSize, mathMax$7(extentMax - pos, 0))] + ] : + [ // indicate single value + [0, 0], + [5, -5], + [5, 5] + ]; + } + + function getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent) { + var halfHoverLinkSize = HOVER_LINK_SIZE / 2; + var hoverLinkDataSize = visualMapModel.get('hoverLinkDataSize'); + if (hoverLinkDataSize) { + halfHoverLinkSize = linearMap$3(hoverLinkDataSize, dataExtent, sizeExtent, true) / 2; + } + return halfHoverLinkSize; + } + + function useHoverLinkOnHandle(visualMapModel) { + var hoverLinkOnHandle = visualMapModel.get('hoverLinkOnHandle'); + return !!(hoverLinkOnHandle == null ? visualMapModel.get('realtime') : hoverLinkOnHandle); + } + + function getCursor$1(orient) { + return orient === 'vertical' ? 'ns-resize' : 'ew-resize'; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var actionInfo$2 = { + type: 'selectDataRange', + event: 'dataRangeSelected', + // FIXME use updateView appears wrong + update: 'update' + }; + + registerAction(actionInfo$2, function(payload, ecModel) { + + ecModel.eachComponent({ + mainType: 'visualMap', + query: payload + }, function(model) { + model.setSelected(payload.selected); + }); + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * DataZoom component entry + */ + + registerPreprocessor(preprocessor$2); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PiecewiseModel = VisualMapModel.extend({ + + type: 'visualMap.piecewise', + + /** + * Order Rule: + * + * option.categories / option.pieces / option.text / option.selected: + * If !option.inverse, + * Order when vertical: ['top', ..., 'bottom']. + * Order when horizontal: ['left', ..., 'right']. + * If option.inverse, the meaning of + * the order should be reversed. + * + * this._pieceList: + * The order is always [low, ..., high]. + * + * Mapping from location to low-high: + * If !option.inverse + * When vertical, top is high. + * When horizontal, right is high. + * If option.inverse, reverse. + */ + + /** + * @protected + */ + defaultOption: { + selected: null, // Object. If not specified, means selected. + // When pieces and splitNumber: {'0': true, '5': true} + // When categories: {'cate1': false, 'cate3': true} + // When selected === false, means all unselected. + + minOpen: false, // Whether include values that smaller than `min`. + maxOpen: false, // Whether include values that bigger than `max`. + + align: 'auto', // 'auto', 'left', 'right' + itemWidth: 20, // When put the controller vertically, it is the length of + // horizontal side of each item. Otherwise, vertical side. + itemHeight: 14, // When put the controller vertically, it is the length of + // vertical side of each item. Otherwise, horizontal side. + itemSymbol: 'roundRect', + pieceList: null, // Each item is Object, with some of those attrs: + // {min, max, lt, gt, lte, gte, value, + // color, colorSaturation, colorAlpha, opacity, + // symbol, symbolSize}, which customize the range or visual + // coding of the certain piece. Besides, see "Order Rule". + categories: null, // category names, like: ['some1', 'some2', 'some3']. + // Attr min/max are ignored when categories set. See "Order Rule" + splitNumber: 5, // If set to 5, auto split five pieces equally. + // If set to 0 and component type not set, component type will be + // determined as "continuous". (It is less reasonable but for ec2 + // compatibility, see echarts/component/visualMap/typeDefaulter) + selectedMode: 'multiple', // Can be 'multiple' or 'single'. + itemGap: 10, // The gap between two items, in px. + hoverLink: true, // Enable hover highlight. + + showLabel: null // By default, when text is used, label will hide (the logic + // is remained for compatibility reason) + }, + + /** + * @override + */ + optionUpdated: function(newOption, isInit) { + PiecewiseModel.superApply(this, 'optionUpdated', arguments); + + /** + * The order is always [low, ..., high]. + * [{text: string, interval: Array.}, ...] + * @private + * @type {Array.} + */ + this._pieceList = []; + + this.resetExtent(); + + /** + * 'pieces', 'categories', 'splitNumber' + * @type {string} + */ + var mode = this._mode = this._determineMode(); + + resetMethods[this._mode].call(this); + + this._resetSelected(newOption, isInit); + + var categories = this.option.categories; + + this.resetVisual(function(mappingOption, state) { + if (mode === 'categories') { + mappingOption.mappingMethod = 'category'; + mappingOption.categories = clone(categories); + } else { + mappingOption.dataExtent = this.getExtent(); + mappingOption.mappingMethod = 'piecewise'; + mappingOption.pieceList = map(this._pieceList, function(piece) { + var piece = clone(piece); + if (state !== 'inRange') { + // FIXME + // outOfRange do not support special visual in pieces. + piece.visual = null; + } + return piece; + }); + } + }); + }, + + /** + * @protected + * @override + */ + completeVisualOption: function() { + // Consider this case: + // visualMap: { + // pieces: [{symbol: 'circle', lt: 0}, {symbol: 'rect', gte: 0}] + // } + // where no inRange/outOfRange set but only pieces. So we should make + // default inRange/outOfRange for this case, otherwise visuals that only + // appear in `pieces` will not be taken into account in visual encoding. + + var option = this.option; + var visualTypesInPieces = {}; + var visualTypes = VisualMapping.listVisualTypes(); + var isCategory = this.isCategory(); + + each$1(option.pieces, function(piece) { + each$1(visualTypes, function(visualType) { + if (piece.hasOwnProperty(visualType)) { + visualTypesInPieces[visualType] = 1; + } + }); + }); + + each$1(visualTypesInPieces, function(v, visualType) { + var exists = 0; + each$1(this.stateList, function(state) { + exists |= has(option, state, visualType) || + has(option.target, state, visualType); + }, this); + + !exists && each$1(this.stateList, function(state) { + (option[state] || (option[state] = {}))[visualType] = visualDefault.get( + visualType, state === 'inRange' ? 'active' : 'inactive', isCategory + ); + }); + }, this); + + function has(obj, state, visualType) { + return obj && obj[state] && ( + isObject$1(obj[state]) ? + obj[state].hasOwnProperty(visualType) : + obj[state] === visualType // e.g., inRange: 'symbol' + ); + } + + VisualMapModel.prototype.completeVisualOption.apply(this, arguments); + }, + + _resetSelected: function(newOption, isInit) { + var thisOption = this.option; + var pieceList = this._pieceList; + + // Selected do not merge but all override. + var selected = (isInit ? thisOption : newOption).selected || {}; + thisOption.selected = selected; + + // Consider 'not specified' means true. + each$1(pieceList, function(piece, index) { + var key = this.getSelectedMapKey(piece); + if (!selected.hasOwnProperty(key)) { + selected[key] = true; + } + }, this); + + if (thisOption.selectedMode === 'single') { + // Ensure there is only one selected. + var hasSel = false; + + each$1(pieceList, function(piece, index) { + var key = this.getSelectedMapKey(piece); + if (selected[key]) { + hasSel + ? + (selected[key] = false) : + (hasSel = true); + } + }, this); + } + // thisOption.selectedMode === 'multiple', default: all selected. + }, + + /** + * @public + */ + getSelectedMapKey: function(piece) { + return this._mode === 'categories' ? + piece.value + '' : piece.index + ''; + }, + + /** + * @public + */ + getPieceList: function() { + return this._pieceList; + }, + + /** + * @private + * @return {string} + */ + _determineMode: function() { + var option = this.option; + + return option.pieces && option.pieces.length > 0 ? + 'pieces' : + this.option.categories ? + 'categories' : + 'splitNumber'; + }, + + /** + * @public + * @override + */ + setSelected: function(selected) { + this.option.selected = clone(selected); + }, + + /** + * @public + * @override + */ + getValueState: function(value) { + var index = VisualMapping.findPieceIndex(value, this._pieceList); + + return index != null ? + (this.option.selected[this.getSelectedMapKey(this._pieceList[index])] ? + 'inRange' : 'outOfRange' + ) : + 'outOfRange'; + }, + + /** + * @public + * @params {number} pieceIndex piece index in visualMapModel.getPieceList() + * @return {Array.} [{seriesId, dataIndices: >}, ...] + */ + findTargetDataIndices: function(pieceIndex) { + var result = []; + + this.eachTargetSeries(function(seriesModel) { + var dataIndices = []; + var data = seriesModel.getData(); + + data.each(this.getDataDimension(data), function(value, dataIndex) { + // Should always base on model pieceList, because it is order sensitive. + var pIdx = VisualMapping.findPieceIndex(value, this._pieceList); + pIdx === pieceIndex && dataIndices.push(dataIndex); + }, this); + + result.push({ + seriesId: seriesModel.id, + dataIndex: dataIndices + }); + }, this); + + return result; + }, + + /** + * @private + * @param {Object} piece piece.value or piece.interval is required. + * @return {number} Can be Infinity or -Infinity + */ + getRepresentValue: function(piece) { + var representValue; + if (this.isCategory()) { + representValue = piece.value; + } else { + if (piece.value != null) { + representValue = piece.value; + } else { + var pieceInterval = piece.interval || []; + representValue = (pieceInterval[0] === -Infinity && pieceInterval[1] === Infinity) ? + 0 : + (pieceInterval[0] + pieceInterval[1]) / 2; + } + } + return representValue; + }, + + getVisualMeta: function(getColorVisual) { + // Do not support category. (category axis is ordinal, numerical) + if (this.isCategory()) { + return; + } + + var stops = []; + var outerColors = []; + var visualMapModel = this; + + function setStop(interval, valueState) { + var representValue = visualMapModel.getRepresentValue({ + interval: interval + }); + if (!valueState) { + valueState = visualMapModel.getValueState(representValue); + } + var color = getColorVisual(representValue, valueState); + if (interval[0] === -Infinity) { + outerColors[0] = color; + } else if (interval[1] === Infinity) { + outerColors[1] = color; + } else { + stops.push({ + value: interval[0], + color: color + }, { + value: interval[1], + color: color + }); + } + } + + // Suplement + var pieceList = this._pieceList.slice(); + if (!pieceList.length) { + pieceList.push({ + interval: [-Infinity, Infinity] + }); + } else { + var edge = pieceList[0].interval[0]; + edge !== -Infinity && pieceList.unshift({ + interval: [-Infinity, edge] + }); + edge = pieceList[pieceList.length - 1].interval[1]; + edge !== Infinity && pieceList.push({ + interval: [edge, Infinity] + }); + } + + var curr = -Infinity; + each$1(pieceList, function(piece) { + var interval = piece.interval; + if (interval) { + // Fulfill gap. + interval[0] > curr && setStop([curr, interval[0]], 'outOfRange'); + setStop(interval.slice()); + curr = interval[1]; + } + }, this); + + return { + stops: stops, + outerColors: outerColors + }; + } + + }); + + /** + * Key is this._mode + * @type {Object} + * @this {module:echarts/component/viusalMap/PiecewiseMode} + */ + var resetMethods = { + + splitNumber: function() { + var thisOption = this.option; + var pieceList = this._pieceList; + var precision = Math.min(thisOption.precision, 20); + var dataExtent = this.getExtent(); + var splitNumber = thisOption.splitNumber; + splitNumber = Math.max(parseInt(splitNumber, 10), 1); + thisOption.splitNumber = splitNumber; + + var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber; + // Precision auto-adaption + while (+splitStep.toFixed(precision) !== splitStep && precision < 5) { + precision++; + } + thisOption.precision = precision; + splitStep = +splitStep.toFixed(precision); + + var index = 0; + + if (thisOption.minOpen) { + pieceList.push({ + index: index++, + interval: [-Infinity, dataExtent[0]], + close: [0, 0] + }); + } + + for ( + var curr = dataExtent[0], len = index + splitNumber; index < len; curr += splitStep + ) { + var max = index === splitNumber - 1 ? dataExtent[1] : (curr + splitStep); + + pieceList.push({ + index: index++, + interval: [curr, max], + close: [1, 1] + }); + } + + if (thisOption.maxOpen) { + pieceList.push({ + index: index++, + interval: [dataExtent[1], Infinity], + close: [0, 0] + }); + } + + reformIntervals(pieceList); + + each$1(pieceList, function(piece) { + piece.text = this.formatValueText(piece.interval); + }, this); + }, + + categories: function() { + var thisOption = this.option; + each$1(thisOption.categories, function(cate) { + // FIXME category模式也使用pieceList,但在visualMapping中不是使用pieceList。 + // 是否改一致。 + this._pieceList.push({ + text: this.formatValueText(cate, true), + value: cate + }); + }, this); + + // See "Order Rule". + normalizeReverse(thisOption, this._pieceList); + }, + + pieces: function() { + var thisOption = this.option; + var pieceList = this._pieceList; + + each$1(thisOption.pieces, function(pieceListItem, index) { + + if (!isObject$1(pieceListItem)) { + pieceListItem = { + value: pieceListItem + }; + } + + var item = { + text: '', + index: index + }; + + if (pieceListItem.label != null) { + item.text = pieceListItem.label; + } + + if (pieceListItem.hasOwnProperty('value')) { + var value = item.value = pieceListItem.value; + item.interval = [value, value]; + item.close = [1, 1]; + } else { + // `min` `max` is legacy option. + // `lt` `gt` `lte` `gte` is recommanded. + var interval = item.interval = []; + var close = item.close = [0, 0]; + + var closeList = [1, 0, 1]; + var infinityList = [-Infinity, Infinity]; + + var useMinMax = []; + for (var lg = 0; lg < 2; lg++) { + var names = [ + ['gte', 'gt', 'min'], + ['lte', 'lt', 'max'] + ][lg]; + for (var i = 0; i < 3 && interval[lg] == null; i++) { + interval[lg] = pieceListItem[names[i]]; + close[lg] = closeList[i]; + useMinMax[lg] = i === 2; + } + interval[lg] == null && (interval[lg] = infinityList[lg]); + } + useMinMax[0] && interval[1] === Infinity && (close[0] = 0); + useMinMax[1] && interval[0] === -Infinity && (close[1] = 0); + + if (__DEV__) { + if (interval[0] > interval[1]) { + console.warn( + 'Piece ' + index + 'is illegal: ' + interval + + ' lower bound should not greater then uppper bound.' + ); + } + } + + if (interval[0] === interval[1] && close[0] && close[1]) { + // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}], + // we use value to lift the priority when min === max + item.value = interval[0]; + } + } + + item.visual = VisualMapping.retrieveVisuals(pieceListItem); + + pieceList.push(item); + + }, this); + + // See "Order Rule". + normalizeReverse(thisOption, pieceList); + // Only pieces + reformIntervals(pieceList); + + each$1(pieceList, function(piece) { + var close = piece.close; + var edgeSymbols = [ + ['<', '≤'][close[1]], + ['>', '≥'][close[0]] + ]; + piece.text = piece.text || this.formatValueText( + piece.value != null ? piece.value : piece.interval, + false, + edgeSymbols + ); + }, this); + } + }; + + function normalizeReverse(thisOption, pieceList) { + var inverse = thisOption.inverse; + if (thisOption.orient === 'vertical' ? !inverse : inverse) { + pieceList.reverse(); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var PiecewiseVisualMapView = VisualMapView.extend({ + + type: 'visualMap.piecewise', + + /** + * @protected + * @override + */ + doRender: function() { + var thisGroup = this.group; + + thisGroup.removeAll(); + + var visualMapModel = this.visualMapModel; + var textGap = visualMapModel.get('textGap'); + var textStyleModel = visualMapModel.textStyleModel; + var textFont = textStyleModel.getFont(); + var textFill = textStyleModel.getTextColor(); + var itemAlign = this._getItemAlign(); + var itemSize = visualMapModel.itemSize; + var viewData = this._getViewData(); + var endsText = viewData.endsText; + var showLabel = retrieve(visualMapModel.get('showLabel', true), !endsText); + + endsText && this._renderEndsText( + thisGroup, endsText[0], itemSize, showLabel, itemAlign + ); + + each$1(viewData.viewPieceList, renderItem, this); + + endsText && this._renderEndsText( + thisGroup, endsText[1], itemSize, showLabel, itemAlign + ); + + box( + visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap') + ); + + this.renderBackground(thisGroup); + + this.positionGroup(thisGroup); + + function renderItem(item) { + var piece = item.piece; + + var itemGroup = new Group(); + itemGroup.onclick = bind(this._onItemClick, this, piece); + + this._enableHoverLink(itemGroup, item.indexInModelPieceList); + + var representValue = visualMapModel.getRepresentValue(piece); + + this._createItemSymbol( + itemGroup, representValue, [0, 0, itemSize[0], itemSize[1]] + ); + + if (showLabel) { + var visualState = this.visualMapModel.getValueState(representValue); + + itemGroup.add(new Text({ + style: { + x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap, + y: itemSize[1] / 2, + text: piece.text, + textVerticalAlign: 'middle', + textAlign: itemAlign, + textFont: textFont, + textFill: textFill, + opacity: visualState === 'outOfRange' ? 0.5 : 1 + } + })); + } + + thisGroup.add(itemGroup); + } + }, + + /** + * @private + */ + _enableHoverLink: function(itemGroup, pieceIndex) { + itemGroup + .on('mouseover', bind(onHoverLink, this, 'highlight')) + .on('mouseout', bind(onHoverLink, this, 'downplay')); + + function onHoverLink(method) { + var visualMapModel = this.visualMapModel; + + visualMapModel.option.hoverLink && this.api.dispatchAction({ + type: method, + batch: convertDataIndex( + visualMapModel.findTargetDataIndices(pieceIndex) + ) + }); + } + }, + + /** + * @private + */ + _getItemAlign: function() { + var visualMapModel = this.visualMapModel; + var modelOption = visualMapModel.option; + + if (modelOption.orient === 'vertical') { + return getItemAlign( + visualMapModel, this.api, visualMapModel.itemSize + ); + } else { // horizontal, most case left unless specifying right. + var align = modelOption.align; + if (!align || align === 'auto') { + align = 'left'; + } + return align; + } + }, + + /** + * @private + */ + _renderEndsText: function(group, text, itemSize, showLabel, itemAlign) { + if (!text) { + return; + } + + var itemGroup = new Group(); + var textStyleModel = this.visualMapModel.textStyleModel; + + itemGroup.add(new Text({ + style: { + x: showLabel ? (itemAlign === 'right' ? itemSize[0] : 0) : itemSize[0] / 2, + y: itemSize[1] / 2, + textVerticalAlign: 'middle', + textAlign: showLabel ? itemAlign : 'center', + text: text, + textFont: textStyleModel.getFont(), + textFill: textStyleModel.getTextColor() + } + })); + + group.add(itemGroup); + }, + + /** + * @private + * @return {Object} {peiceList, endsText} The order is the same as screen pixel order. + */ + _getViewData: function() { + var visualMapModel = this.visualMapModel; + + var viewPieceList = map(visualMapModel.getPieceList(), function(piece, index) { + return { + piece: piece, + indexInModelPieceList: index + }; + }); + var endsText = visualMapModel.get('text'); + + // Consider orient and inverse. + var orient = visualMapModel.get('orient'); + var inverse = visualMapModel.get('inverse'); + + // Order of model pieceList is always [low, ..., high] + if (orient === 'horizontal' ? inverse : !inverse) { + viewPieceList.reverse(); + } + // Origin order of endsText is [high, low] + else if (endsText) { + endsText = endsText.slice().reverse(); + } + + return { + viewPieceList: viewPieceList, + endsText: endsText + }; + }, + + /** + * @private + */ + _createItemSymbol: function(group, representValue, shapeParam) { + group.add(createSymbol( + this.getControllerVisual(representValue, 'symbol'), + shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3], + this.getControllerVisual(representValue, 'color') + )); + }, + + /** + * @private + */ + _onItemClick: function(piece) { + var visualMapModel = this.visualMapModel; + var option = visualMapModel.option; + var selected = clone(option.selected); + var newKey = visualMapModel.getSelectedMapKey(piece); + + if (option.selectedMode === 'single') { + selected[newKey] = true; + each$1(selected, function(o, key) { + selected[key] = key === newKey; + }); + } else { + selected[newKey] = !selected[newKey]; + } + + this.api.dispatchAction({ + type: 'selectDataRange', + from: this.uid, + visualMapId: this.visualMapModel.id, + selected: selected + }); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * DataZoom component entry + */ + + registerPreprocessor(preprocessor$2); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * visualMap component entry + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var addCommas$1 = addCommas; + var encodeHTML$1 = encodeHTML; + + function fillLabel(opt) { + defaultEmphasis(opt, 'label', ['show']); + } + var MarkerModel = extendComponentModel({ + + type: 'marker', + + dependencies: ['series', 'grid', 'polar', 'geo'], + + /** + * @overrite + */ + init: function(option, parentModel, ecModel, extraOpt) { + + if (__DEV__) { + if (this.type === 'marker') { + throw new Error('Marker component is abstract component. Use markLine, markPoint, markArea instead.'); + } + } + this.mergeDefaultAndTheme(option, ecModel); + this.mergeOption(option, ecModel, extraOpt.createdBySelf, true); + }, + + /** + * @return {boolean} + */ + isAnimationEnabled: function() { + if (env$1.node) { + return false; + } + + var hostSeries = this.__hostSeries; + return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled(); + }, + + mergeOption: function(newOpt, ecModel, createdBySelf, isInit) { + var MarkerModel = this.constructor; + var modelPropName = this.mainType + 'Model'; + if (!createdBySelf) { + ecModel.eachSeries(function(seriesModel) { + + var markerOpt = seriesModel.get(this.mainType, true); + + var markerModel = seriesModel[modelPropName]; + if (!markerOpt || !markerOpt.data) { + seriesModel[modelPropName] = null; + return; + } + if (!markerModel) { + if (isInit) { + // Default label emphasis `position` and `show` + fillLabel(markerOpt); + } + each$1(markerOpt.data, function(item) { + // FIXME Overwrite fillLabel method ? + if (item instanceof Array) { + fillLabel(item[0]); + fillLabel(item[1]); + } else { + fillLabel(item); + } + }); + + markerModel = new MarkerModel( + markerOpt, this, ecModel + ); + + extend(markerModel, { + mainType: this.mainType, + // Use the same series index and name + seriesIndex: seriesModel.seriesIndex, + name: seriesModel.name, + createdBySelf: true + }); + + markerModel.__hostSeries = seriesModel; + } else { + markerModel.mergeOption(markerOpt, ecModel, true); + } + seriesModel[modelPropName] = markerModel; + }, this); + } + }, + + formatTooltip: function(dataIndex) { + var data = this.getData(); + var value = this.getRawValue(dataIndex); + var formattedValue = isArray(value) ? + map(value, addCommas$1).join(', ') : addCommas$1(value); + var name = data.getName(dataIndex); + var html = encodeHTML$1(this.name); + if (value != null || name) { + html += '
'; + } + if (name) { + html += encodeHTML$1(name); + if (value != null) { + html += ' : '; + } + } + if (value != null) { + html += encodeHTML$1(formattedValue); + } + return html; + }, + + getData: function() { + return this._data; + }, + + setData: function(data) { + this._data = data; + } + }); + + mixin(MarkerModel, dataFormatMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + MarkerModel.extend({ + + type: 'markPoint', + + defaultOption: { + zlevel: 0, + z: 5, + symbol: 'pin', + symbolSize: 50, + //symbolRotate: 0, + //symbolOffset: [0, 0] + tooltip: { + trigger: 'item' + }, + label: { + show: true, + position: 'inside' + }, + itemStyle: { + borderWidth: 2 + }, + emphasis: { + label: { + show: true + } + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var indexOf$2 = indexOf; + + function hasXOrY(item) { + return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y))); + } + + function hasXAndY(item) { + return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y)); + } + + // Make it simple, do not visit all stacked value to count precision. + // function getPrecision(data, valueAxisDim, dataIndex) { + // var precision = -1; + // var stackedDim = data.mapDimension(valueAxisDim); + // do { + // precision = Math.max( + // numberUtil.getPrecision(data.get(stackedDim, dataIndex)), + // precision + // ); + // var stackedOnSeries = data.getCalculationInfo('stackedOnSeries'); + // if (stackedOnSeries) { + // var byValue = data.get(data.getCalculationInfo('stackedByDimension'), dataIndex); + // data = stackedOnSeries.getData(); + // dataIndex = data.indexOf(data.getCalculationInfo('stackedByDimension'), byValue); + // stackedDim = data.getCalculationInfo('stackedDimension'); + // } + // else { + // data = null; + // } + // } while (data); + + // return precision; + // } + + function markerTypeCalculatorWithExtent( + mlType, data, otherDataDim, targetDataDim, otherCoordIndex, targetCoordIndex + ) { + var coordArr = []; + + var stacked = isDimensionStacked(data, targetDataDim /*, otherDataDim*/ ); + var calcDataDim = stacked ? + data.getCalculationInfo('stackResultDimension') : + targetDataDim; + + var value = numCalculate(data, calcDataDim, mlType); + + var dataIndex = data.indicesOfNearest(calcDataDim, value)[0]; + coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex); + coordArr[targetCoordIndex] = data.get(targetDataDim, dataIndex); + + // Make it simple, do not visit all stacked value to count precision. + var precision = getPrecision(data.get(targetDataDim, dataIndex)); + precision = Math.min(precision, 20); + if (precision >= 0) { + coordArr[targetCoordIndex] = +coordArr[targetCoordIndex].toFixed(precision); + } + + return coordArr; + } + + var curry$7 = curry; + // TODO Specified percent + var markerTypeCalculator = { + /** + * @method + * @param {module:echarts/data/List} data + * @param {string} baseAxisDim + * @param {string} valueAxisDim + */ + min: curry$7(markerTypeCalculatorWithExtent, 'min'), + /** + * @method + * @param {module:echarts/data/List} data + * @param {string} baseAxisDim + * @param {string} valueAxisDim + */ + max: curry$7(markerTypeCalculatorWithExtent, 'max'), + + /** + * @method + * @param {module:echarts/data/List} data + * @param {string} baseAxisDim + * @param {string} valueAxisDim + */ + average: curry$7(markerTypeCalculatorWithExtent, 'average') + }; + + /** + * Transform markPoint data item to format used in List by do the following + * 1. Calculate statistic like `max`, `min`, `average` + * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/coord/*} [coordSys] + * @param {Object} item + * @return {Object} + */ + function dataTransform(seriesModel, item) { + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + + // 1. If not specify the position with pixel directly + // 2. If `coord` is not a data array. Which uses `xAxis`, + // `yAxis` to specify the coord on each dimension + + // parseFloat first because item.x and item.y can be percent string like '20%' + if (item && !hasXAndY(item) && !isArray(item.coord) && coordSys) { + var dims = coordSys.dimensions; + var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); + + // Clone the option + // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value + item = clone(item); + + if (item.type && + markerTypeCalculator[item.type] && + axisInfo.baseAxis && axisInfo.valueAxis + ) { + var otherCoordIndex = indexOf$2(dims, axisInfo.baseAxis.dim); + var targetCoordIndex = indexOf$2(dims, axisInfo.valueAxis.dim); + + item.coord = markerTypeCalculator[item.type]( + data, axisInfo.baseDataDim, axisInfo.valueDataDim, + otherCoordIndex, targetCoordIndex + ); + // Force to use the value of calculated value. + item.value = item.coord[targetCoordIndex]; + } else { + // FIXME Only has one of xAxis and yAxis. + var coord = [ + item.xAxis != null ? item.xAxis : item.radiusAxis, + item.yAxis != null ? item.yAxis : item.angleAxis + ]; + // Each coord support max, min, average + for (var i = 0; i < 2; i++) { + if (markerTypeCalculator[coord[i]]) { + coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]); + } + } + item.coord = coord; + } + } + return item; + } + + function getAxisInfo$1(item, data, coordSys, seriesModel) { + var ret = {}; + + if (item.valueIndex != null || item.valueDim != null) { + ret.valueDataDim = item.valueIndex != null ? + data.getDimension(item.valueIndex) : item.valueDim; + ret.valueAxis = coordSys.getAxis(dataDimToCoordDim(seriesModel, ret.valueDataDim)); + ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis); + ret.baseDataDim = data.mapDimension(ret.baseAxis.dim); + } else { + ret.baseAxis = seriesModel.getBaseAxis(); + ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis); + ret.baseDataDim = data.mapDimension(ret.baseAxis.dim); + ret.valueDataDim = data.mapDimension(ret.valueAxis.dim); + } + + return ret; + } + + function dataDimToCoordDim(seriesModel, dataDim) { + var data = seriesModel.getData(); + var dimensions = data.dimensions; + dataDim = data.getDimension(dataDim); + for (var i = 0; i < dimensions.length; i++) { + var dimItem = data.getDimensionInfo(dimensions[i]); + if (dimItem.name === dataDim) { + return dimItem.coordDim; + } + } + } + + /** + * Filter data which is out of coordinateSystem range + * [dataFilter description] + * @param {module:echarts/coord/*} [coordSys] + * @param {Object} item + * @return {boolean} + */ + function dataFilter$1(coordSys, item) { + // Alwalys return true if there is no coordSys + return (coordSys && coordSys.containData && item.coord && !hasXOrY(item)) ? + coordSys.containData(item.coord) : true; + } + + function dimValueGetter(item, dimName, dataIndex, dimIndex) { + // x, y, radius, angle + if (dimIndex < 2) { + return item.coord && item.coord[dimIndex]; + } + return item.value; + } + + function numCalculate(data, valueDataDim, type) { + if (type === 'average') { + var sum = 0; + var count = 0; + data.each(valueDataDim, function(val, idx) { + if (!isNaN(val)) { + sum += val; + count++; + } + }); + return sum / count; + } else if (type === 'median') { + return data.getMedian(valueDataDim); + } else { + // max & min + return data.getDataExtent(valueDataDim, true)[type === 'max' ? 1 : 0]; + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var MarkerView = extendComponentView({ + + type: 'marker', + + init: function() { + /** + * Markline grouped by series + * @private + * @type {module:zrender/core/util.HashMap} + */ + this.markerGroupMap = createHashMap(); + }, + + render: function(markerModel, ecModel, api) { + var markerGroupMap = this.markerGroupMap; + markerGroupMap.each(function(item) { + item.__keep = false; + }); + + var markerModelKey = this.type + 'Model'; + ecModel.eachSeries(function(seriesModel) { + var markerModel = seriesModel[markerModelKey]; + markerModel && this.renderSeries(seriesModel, markerModel, ecModel, api); + }, this); + + markerGroupMap.each(function(item) { + !item.__keep && this.group.remove(item.group); + }, this); + }, + + renderSeries: function() {} + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + function updateMarkerLayout(mpData, seriesModel, api) { + var coordSys = seriesModel.coordinateSystem; + mpData.each(function(idx) { + var itemModel = mpData.getItemModel(idx); + var point; + var xPx = parsePercent$1(itemModel.get('x'), api.getWidth()); + var yPx = parsePercent$1(itemModel.get('y'), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } + // Chart like bar may have there own marker positioning logic + else if (seriesModel.getMarkerPosition) { + // Use the getMarkerPoisition + point = seriesModel.getMarkerPosition( + mpData.getValues(mpData.dimensions, idx) + ); + } else if (coordSys) { + var x = mpData.get(coordSys.dimensions[0], idx); + var y = mpData.get(coordSys.dimensions[1], idx); + point = coordSys.dataToPoint([x, y]); + + } + + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + + mpData.setItemLayout(idx, point); + }); + } + + MarkerView.extend({ + + type: 'markPoint', + + // updateLayout: function (markPointModel, ecModel, api) { + // ecModel.eachSeries(function (seriesModel) { + // var mpModel = seriesModel.markPointModel; + // if (mpModel) { + // updateMarkerLayout(mpModel.getData(), seriesModel, api); + // this.markerGroupMap.get(seriesModel.id).updateLayout(mpModel); + // } + // }, this); + // }, + + updateTransform: function(markPointModel, ecModel, api) { + ecModel.eachSeries(function(seriesModel) { + var mpModel = seriesModel.markPointModel; + if (mpModel) { + updateMarkerLayout(mpModel.getData(), seriesModel, api); + this.markerGroupMap.get(seriesModel.id).updateLayout(mpModel); + } + }, this); + }, + + renderSeries: function(seriesModel, mpModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + + var symbolDrawMap = this.markerGroupMap; + var symbolDraw = symbolDrawMap.get(seriesId) || + symbolDrawMap.set(seriesId, new SymbolDraw()); + + var mpData = createList$1(coordSys, seriesModel, mpModel); + + // FIXME + mpModel.setData(mpData); + + updateMarkerLayout(mpModel.getData(), seriesModel, api); + + mpData.each(function(idx) { + var itemModel = mpData.getItemModel(idx); + var symbolSize = itemModel.getShallow('symbolSize'); + if (typeof symbolSize === 'function') { + // FIXME 这里不兼容 ECharts 2.x,2.x 貌似参数是整个数据? + symbolSize = symbolSize( + mpModel.getRawValue(idx), mpModel.getDataParams(idx) + ); + } + mpData.setItemVisual(idx, { + symbolSize: symbolSize, + color: itemModel.get('itemStyle.color') || + seriesData.getVisual('color'), + symbol: itemModel.getShallow('symbol') + }); + }); + + // TODO Text are wrong + symbolDraw.updateData(mpData); + this.group.add(symbolDraw.group); + + // Set host model for tooltip + // FIXME + mpData.eachItemGraphicEl(function(el) { + el.traverse(function(child) { + child.dataModel = mpModel; + }); + }); + + symbolDraw.__keep = true; + + symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent'); + } + }); + + /** + * @inner + * @param {module:echarts/coord/*} [coordSys] + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Model} mpModel + */ + function createList$1(coordSys, seriesModel, mpModel) { + var coordDimsInfos; + if (coordSys) { + coordDimsInfos = map(coordSys && coordSys.dimensions, function(coordDim) { + var info = seriesModel.getData().getDimensionInfo( + seriesModel.getData().mapDimension(coordDim) + ) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return defaults({ + name: coordDim + }, info); + }); + } else { + coordDimsInfos = [{ + name: 'value', + type: 'float' + }]; + } + + var mpData = new List(coordDimsInfos, mpModel); + var dataOpt = map(mpModel.get('data'), curry( + dataTransform, seriesModel + )); + if (coordSys) { + dataOpt = filter( + dataOpt, curry(dataFilter$1, coordSys) + ); + } + + mpData.initData(dataOpt, null, + coordSys ? dimValueGetter : function(item) { + return item.value; + } + ); + + return mpData; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // HINT Markpoint can't be used too much + registerPreprocessor(function(opt) { + // Make sure markPoint component is enabled + opt.markPoint = opt.markPoint || {}; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + MarkerModel.extend({ + + type: 'markLine', + + defaultOption: { + zlevel: 0, + z: 5, + + symbol: ['circle', 'arrow'], + symbolSize: [8, 16], + + //symbolRotate: 0, + + precision: 2, + tooltip: { + trigger: 'item' + }, + label: { + show: true, + position: 'end' + }, + lineStyle: { + type: 'dashed' + }, + emphasis: { + label: { + show: true + }, + lineStyle: { + width: 3 + } + }, + animationEasing: 'linear' + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var markLineTransform = function(seriesModel, coordSys, mlModel, item) { + var data = seriesModel.getData(); + // Special type markLine like 'min', 'max', 'average', 'median' + var mlType = item.type; + + if (!isArray(item) && + ( + mlType === 'min' || mlType === 'max' || mlType === 'average' || mlType === 'median' + // In case + // data: [{ + // yAxis: 10 + // }] + || + (item.xAxis != null || item.yAxis != null) + ) + ) { + var valueAxis; + var valueDataDim; + var value; + + if (item.yAxis != null || item.xAxis != null) { + valueDataDim = item.yAxis != null ? 'y' : 'x'; + valueAxis = coordSys.getAxis(valueDataDim); + + value = retrieve(item.yAxis, item.xAxis); + } else { + var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); + valueDataDim = axisInfo.valueDataDim; + valueAxis = axisInfo.valueAxis; + value = numCalculate(data, valueDataDim, mlType); + } + var valueIndex = valueDataDim === 'x' ? 0 : 1; + var baseIndex = 1 - valueIndex; + + var mlFrom = clone(item); + var mlTo = {}; + + mlFrom.type = null; + + mlFrom.coord = []; + mlTo.coord = []; + mlFrom.coord[baseIndex] = -Infinity; + mlTo.coord[baseIndex] = Infinity; + + var precision = mlModel.get('precision'); + if (precision >= 0 && typeof value === 'number') { + value = +value.toFixed(Math.min(precision, 20)); + } + + mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value; + + item = [mlFrom, mlTo, { // Extra option for tooltip and label + type: mlType, + valueIndex: item.valueIndex, + // Force to use the value of calculated value. + value: value + }]; + } + + item = [ + dataTransform(seriesModel, item[0]), + dataTransform(seriesModel, item[1]), + extend({}, item[2]) + ]; + + // Avoid line data type is extended by from(to) data type + item[2].type = item[2].type || ''; + + // Merge from option and to option into line option + merge(item[2], item[0]); + merge(item[2], item[1]); + + return item; + }; + + function isInifinity(val) { + return !isNaN(val) && !isFinite(val); + } + + // If a markLine has one dim + function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) { + var otherDimIndex = 1 - dimIndex; + var dimName = coordSys.dimensions[dimIndex]; + return isInifinity(fromCoord[otherDimIndex]) && isInifinity(toCoord[otherDimIndex]) && + fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]); + } + + function markLineFilter(coordSys, item) { + if (coordSys.type === 'cartesian2d') { + var fromCoord = item[0].coord; + var toCoord = item[1].coord; + // In case + // { + // markLine: { + // data: [{ yAxis: 2 }] + // } + // } + if ( + fromCoord && toCoord && + (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys) || + ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys)) + ) { + return true; + } + } + return dataFilter$1(coordSys, item[0]) && + dataFilter$1(coordSys, item[1]); + } + + function updateSingleMarkerEndLayout( + data, idx, isFrom, seriesModel, api + ) { + var coordSys = seriesModel.coordinateSystem; + var itemModel = data.getItemModel(idx); + + var point; + var xPx = parsePercent$1(itemModel.get('x'), api.getWidth()); + var yPx = parsePercent$1(itemModel.get('y'), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } else { + // Chart like bar may have there own marker positioning logic + if (seriesModel.getMarkerPosition) { + // Use the getMarkerPoisition + point = seriesModel.getMarkerPosition( + data.getValues(data.dimensions, idx) + ); + } else { + var dims = coordSys.dimensions; + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + point = coordSys.dataToPoint([x, y]); + } + // Expand line to the edge of grid if value on one axis is Inifnity + // In case + // markLine: { + // data: [{ + // yAxis: 2 + // // or + // type: 'average' + // }] + // } + if (coordSys.type === 'cartesian2d') { + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + var dims = coordSys.dimensions; + if (isInifinity(data.get(dims[0], idx))) { + point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]); + } else if (isInifinity(data.get(dims[1], idx))) { + point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]); + } + } + + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + } + + data.setItemLayout(idx, point); + } + + MarkerView.extend({ + + type: 'markLine', + + // updateLayout: function (markLineModel, ecModel, api) { + // ecModel.eachSeries(function (seriesModel) { + // var mlModel = seriesModel.markLineModel; + // if (mlModel) { + // var mlData = mlModel.getData(); + // var fromData = mlModel.__from; + // var toData = mlModel.__to; + // // Update visual and layout of from symbol and to symbol + // fromData.each(function (idx) { + // updateSingleMarkerEndLayout(fromData, idx, true, seriesModel, api); + // updateSingleMarkerEndLayout(toData, idx, false, seriesModel, api); + // }); + // // Update layout of line + // mlData.each(function (idx) { + // mlData.setItemLayout(idx, [ + // fromData.getItemLayout(idx), + // toData.getItemLayout(idx) + // ]); + // }); + + // this.markerGroupMap.get(seriesModel.id).updateLayout(); + + // } + // }, this); + // }, + + updateTransform: function(markLineModel, ecModel, api) { + ecModel.eachSeries(function(seriesModel) { + var mlModel = seriesModel.markLineModel; + if (mlModel) { + var mlData = mlModel.getData(); + var fromData = mlModel.__from; + var toData = mlModel.__to; + // Update visual and layout of from symbol and to symbol + fromData.each(function(idx) { + updateSingleMarkerEndLayout(fromData, idx, true, seriesModel, api); + updateSingleMarkerEndLayout(toData, idx, false, seriesModel, api); + }); + // Update layout of line + mlData.each(function(idx) { + mlData.setItemLayout(idx, [ + fromData.getItemLayout(idx), + toData.getItemLayout(idx) + ]); + }); + + this.markerGroupMap.get(seriesModel.id).updateLayout(); + + } + }, this); + }, + + renderSeries: function(seriesModel, mlModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + + var lineDrawMap = this.markerGroupMap; + var lineDraw = lineDrawMap.get(seriesId) || + lineDrawMap.set(seriesId, new LineDraw()); + this.group.add(lineDraw.group); + + var mlData = createList$2(coordSys, seriesModel, mlModel); + + var fromData = mlData.from; + var toData = mlData.to; + var lineData = mlData.line; + + mlModel.__from = fromData; + mlModel.__to = toData; + // Line data for tooltip and formatter + mlModel.setData(lineData); + + var symbolType = mlModel.get('symbol'); + var symbolSize = mlModel.get('symbolSize'); + if (!isArray(symbolType)) { + symbolType = [symbolType, symbolType]; + } + if (typeof symbolSize === 'number') { + symbolSize = [symbolSize, symbolSize]; + } + + // Update visual and layout of from symbol and to symbol + mlData.from.each(function(idx) { + updateDataVisualAndLayout(fromData, idx, true); + updateDataVisualAndLayout(toData, idx, false); + }); + + // Update visual and layout of line + lineData.each(function(idx) { + var lineColor = lineData.getItemModel(idx).get('lineStyle.color'); + lineData.setItemVisual(idx, { + color: lineColor || fromData.getItemVisual(idx, 'color') + }); + lineData.setItemLayout(idx, [ + fromData.getItemLayout(idx), + toData.getItemLayout(idx) + ]); + + lineData.setItemVisual(idx, { + 'fromSymbolSize': fromData.getItemVisual(idx, 'symbolSize'), + 'fromSymbol': fromData.getItemVisual(idx, 'symbol'), + 'toSymbolSize': toData.getItemVisual(idx, 'symbolSize'), + 'toSymbol': toData.getItemVisual(idx, 'symbol') + }); + }); + + lineDraw.updateData(lineData); + + // Set host model for tooltip + // FIXME + mlData.line.eachItemGraphicEl(function(el, idx) { + el.traverse(function(child) { + child.dataModel = mlModel; + }); + }); + + function updateDataVisualAndLayout(data, idx, isFrom) { + var itemModel = data.getItemModel(idx); + + updateSingleMarkerEndLayout( + data, idx, isFrom, seriesModel, api + ); + + data.setItemVisual(idx, { + symbolSize: itemModel.get('symbolSize') || symbolSize[isFrom ? 0 : 1], + symbol: itemModel.get('symbol', true) || symbolType[isFrom ? 0 : 1], + color: itemModel.get('itemStyle.color') || seriesData.getVisual('color') + }); + } + + lineDraw.__keep = true; + + lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent'); + } + }); + + /** + * @inner + * @param {module:echarts/coord/*} coordSys + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Model} mpModel + */ + function createList$2(coordSys, seriesModel, mlModel) { + + var coordDimsInfos; + if (coordSys) { + coordDimsInfos = map(coordSys && coordSys.dimensions, function(coordDim) { + var info = seriesModel.getData().getDimensionInfo( + seriesModel.getData().mapDimension(coordDim) + ) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return defaults({ + name: coordDim + }, info); + }); + } else { + coordDimsInfos = [{ + name: 'value', + type: 'float' + }]; + } + + var fromData = new List(coordDimsInfos, mlModel); + var toData = new List(coordDimsInfos, mlModel); + // No dimensions + var lineData = new List([], mlModel); + + var optData = map(mlModel.get('data'), curry( + markLineTransform, seriesModel, coordSys, mlModel + )); + if (coordSys) { + optData = filter( + optData, curry(markLineFilter, coordSys) + ); + } + var dimValueGetter$$1 = coordSys ? dimValueGetter : function(item) { + return item.value; + }; + fromData.initData( + map(optData, function(item) { + return item[0]; + }), + null, dimValueGetter$$1 + ); + toData.initData( + map(optData, function(item) { + return item[1]; + }), + null, dimValueGetter$$1 + ); + lineData.initData( + map(optData, function(item) { + return item[2]; + }) + ); + lineData.hasItemOption = true; + + return { + from: fromData, + to: toData, + line: lineData + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerPreprocessor(function(opt) { + // Make sure markLine component is enabled + opt.markLine = opt.markLine || {}; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + MarkerModel.extend({ + + type: 'markArea', + + defaultOption: { + zlevel: 0, + // PENDING + z: 1, + tooltip: { + trigger: 'item' + }, + // markArea should fixed on the coordinate system + animation: false, + label: { + show: true, + position: 'top' + }, + itemStyle: { + // color and borderColor default to use color from series + // color: 'auto' + // borderColor: 'auto' + borderWidth: 0 + }, + + emphasis: { + label: { + show: true, + position: 'top' + } + } + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // TODO Better on polar + + var markAreaTransform = function(seriesModel, coordSys, maModel, item) { + var lt = dataTransform(seriesModel, item[0]); + var rb = dataTransform(seriesModel, item[1]); + var retrieve$$1 = retrieve; + + // FIXME make sure lt is less than rb + var ltCoord = lt.coord; + var rbCoord = rb.coord; + ltCoord[0] = retrieve$$1(ltCoord[0], -Infinity); + ltCoord[1] = retrieve$$1(ltCoord[1], -Infinity); + + rbCoord[0] = retrieve$$1(rbCoord[0], Infinity); + rbCoord[1] = retrieve$$1(rbCoord[1], Infinity); + + // Merge option into one + var result = mergeAll([{}, lt, rb]); + + result.coord = [ + lt.coord, rb.coord + ]; + result.x0 = lt.x; + result.y0 = lt.y; + result.x1 = rb.x; + result.y1 = rb.y; + return result; + }; + + function isInifinity$1(val) { + return !isNaN(val) && !isFinite(val); + } + + // If a markArea has one dim + function ifMarkLineHasOnlyDim$1(dimIndex, fromCoord, toCoord, coordSys) { + var otherDimIndex = 1 - dimIndex; + return isInifinity$1(fromCoord[otherDimIndex]) && isInifinity$1(toCoord[otherDimIndex]); + } + + function markAreaFilter(coordSys, item) { + var fromCoord = item.coord[0]; + var toCoord = item.coord[1]; + if (coordSys.type === 'cartesian2d') { + // In case + // { + // markArea: { + // data: [{ yAxis: 2 }] + // } + // } + if ( + fromCoord && toCoord && + (ifMarkLineHasOnlyDim$1(1, fromCoord, toCoord, coordSys) || + ifMarkLineHasOnlyDim$1(0, fromCoord, toCoord, coordSys)) + ) { + return true; + } + } + return dataFilter$1(coordSys, { + coord: fromCoord, + x: item.x0, + y: item.y0 + }) || + dataFilter$1(coordSys, { + coord: toCoord, + x: item.x1, + y: item.y1 + }); + } + + // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0'] + function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) { + var coordSys = seriesModel.coordinateSystem; + var itemModel = data.getItemModel(idx); + + var point; + var xPx = parsePercent$1(itemModel.get(dims[0]), api.getWidth()); + var yPx = parsePercent$1(itemModel.get(dims[1]), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } else { + // Chart like bar may have there own marker positioning logic + if (seriesModel.getMarkerPosition) { + // Use the getMarkerPoisition + point = seriesModel.getMarkerPosition( + data.getValues(dims, idx) + ); + } else { + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + var pt = [x, y]; + coordSys.clampData && coordSys.clampData(pt, pt); + point = coordSys.dataToPoint(pt, true); + } + if (coordSys.type === 'cartesian2d') { + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + if (isInifinity$1(x)) { + point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]); + } else if (isInifinity$1(y)) { + point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]); + } + } + + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + } + + return point; + } + + var dimPermutations = [ + ['x0', 'y0'], + ['x1', 'y0'], + ['x1', 'y1'], + ['x0', 'y1'] + ]; + + MarkerView.extend({ + + type: 'markArea', + + // updateLayout: function (markAreaModel, ecModel, api) { + // ecModel.eachSeries(function (seriesModel) { + // var maModel = seriesModel.markAreaModel; + // if (maModel) { + // var areaData = maModel.getData(); + // areaData.each(function (idx) { + // var points = zrUtil.map(dimPermutations, function (dim) { + // return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api); + // }); + // // Layout + // areaData.setItemLayout(idx, points); + // var el = areaData.getItemGraphicEl(idx); + // el.setShape('points', points); + // }); + // } + // }, this); + // }, + + updateTransform: function(markAreaModel, ecModel, api) { + ecModel.eachSeries(function(seriesModel) { + var maModel = seriesModel.markAreaModel; + if (maModel) { + var areaData = maModel.getData(); + areaData.each(function(idx) { + var points = map(dimPermutations, function(dim) { + return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api); + }); + // Layout + areaData.setItemLayout(idx, points); + var el = areaData.getItemGraphicEl(idx); + el.setShape('points', points); + }); + } + }, this); + }, + + renderSeries: function(seriesModel, maModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + + var areaGroupMap = this.markerGroupMap; + var polygonGroup = areaGroupMap.get(seriesId) || + areaGroupMap.set(seriesId, { + group: new Group() + }); + + this.group.add(polygonGroup.group); + polygonGroup.__keep = true; + + var areaData = createList$3(coordSys, seriesModel, maModel); + + // Line data for tooltip and formatter + maModel.setData(areaData); + + // Update visual and layout of line + areaData.each(function(idx) { + // Layout + areaData.setItemLayout(idx, map(dimPermutations, function(dim) { + return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api); + })); + + // Visual + areaData.setItemVisual(idx, { + color: seriesData.getVisual('color') + }); + }); + + + areaData.diff(polygonGroup.__data) + .add(function(idx) { + var polygon = new Polygon({ + shape: { + points: areaData.getItemLayout(idx) + } + }); + areaData.setItemGraphicEl(idx, polygon); + polygonGroup.group.add(polygon); + }) + .update(function(newIdx, oldIdx) { + var polygon = polygonGroup.__data.getItemGraphicEl(oldIdx); + updateProps(polygon, { + shape: { + points: areaData.getItemLayout(newIdx) + } + }, maModel, newIdx); + polygonGroup.group.add(polygon); + areaData.setItemGraphicEl(newIdx, polygon); + }) + .remove(function(idx) { + var polygon = polygonGroup.__data.getItemGraphicEl(idx); + polygonGroup.group.remove(polygon); + }) + .execute(); + + areaData.eachItemGraphicEl(function(polygon, idx) { + var itemModel = areaData.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + var labelHoverModel = itemModel.getModel('emphasis.label'); + var color = areaData.getItemVisual(idx, 'color'); + polygon.useStyle( + defaults( + itemModel.getModel('itemStyle').getItemStyle(), { + fill: modifyAlpha(color, 0.4), + stroke: color + } + ) + ); + + polygon.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle(); + + setLabelStyle( + polygon.style, polygon.hoverStyle, labelModel, labelHoverModel, { + labelFetcher: maModel, + labelDataIndex: idx, + defaultText: areaData.getName(idx) || '', + isRectText: true, + autoColor: color + } + ); + + setHoverStyle(polygon, {}); + + polygon.dataModel = maModel; + }); + + polygonGroup.__data = areaData; + + polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent'); + } + }); + + /** + * @inner + * @param {module:echarts/coord/*} coordSys + * @param {module:echarts/model/Series} seriesModel + * @param {module:echarts/model/Model} mpModel + */ + function createList$3(coordSys, seriesModel, maModel) { + + var coordDimsInfos; + var areaData; + var dims = ['x0', 'y0', 'x1', 'y1']; + if (coordSys) { + coordDimsInfos = map(coordSys && coordSys.dimensions, function(coordDim) { + var data = seriesModel.getData(); + var info = data.getDimensionInfo( + data.mapDimension(coordDim) + ) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return defaults({ + name: coordDim + }, info); + }); + areaData = new List(map(dims, function(dim, idx) { + return { + name: dim, + type: coordDimsInfos[idx % 2].type + }; + }), maModel); + } else { + coordDimsInfos = [{ + name: 'value', + type: 'float' + }]; + areaData = new List(coordDimsInfos, maModel); + } + + var optData = map(maModel.get('data'), curry( + markAreaTransform, seriesModel, coordSys, maModel + )); + if (coordSys) { + optData = filter( + optData, curry(markAreaFilter, coordSys) + ); + } + + var dimValueGetter$$1 = coordSys ? function(item, dimName, dataIndex, dimIndex) { + return item.coord[Math.floor(dimIndex / 2)][dimIndex % 2]; + } : function(item) { + return item.value; + }; + areaData.initData(optData, null, dimValueGetter$$1); + areaData.hasItemOption = true; + return areaData; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerPreprocessor(function(opt) { + // Make sure markArea component is enabled + opt.markArea = opt.markArea || {}; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var preprocessor$3 = function(option) { + var timelineOpt = option && option.timeline; + + if (!isArray(timelineOpt)) { + timelineOpt = timelineOpt ? [timelineOpt] : []; + } + + each$1(timelineOpt, function(opt) { + if (!opt) { + return; + } + + compatibleEC2(opt); + }); + }; + + function compatibleEC2(opt) { + var type = opt.type; + + var ec2Types = { + 'number': 'value', + 'time': 'time' + }; + + // Compatible with ec2 + if (ec2Types[type]) { + opt.axisType = ec2Types[type]; + delete opt.type; + } + + transferItem(opt); + + if (has$2(opt, 'controlPosition')) { + var controlStyle = opt.controlStyle || (opt.controlStyle = {}); + if (!has$2(controlStyle, 'position')) { + controlStyle.position = opt.controlPosition; + } + if (controlStyle.position === 'none' && !has$2(controlStyle, 'show')) { + controlStyle.show = false; + delete controlStyle.position; + } + delete opt.controlPosition; + } + + each$1(opt.data || [], function(dataItem) { + if (isObject$1(dataItem) && !isArray(dataItem)) { + if (!has$2(dataItem, 'value') && has$2(dataItem, 'name')) { + // In ec2, using name as value. + dataItem.value = dataItem.name; + } + transferItem(dataItem); + } + }); + } + + function transferItem(opt) { + var itemStyle = opt.itemStyle || (opt.itemStyle = {}); + + var itemStyleEmphasis = itemStyle.emphasis || (itemStyle.emphasis = {}); + + // Transfer label out + var label = opt.label || (opt.label || {}); + var labelNormal = label.normal || (label.normal = {}); + var excludeLabelAttr = { + normal: 1, + emphasis: 1 + }; + + each$1(label, function(value, name) { + if (!excludeLabelAttr[name] && !has$2(labelNormal, name)) { + labelNormal[name] = value; + } + }); + + if (itemStyleEmphasis.label && !has$2(label, 'emphasis')) { + label.emphasis = itemStyleEmphasis.label; + delete itemStyleEmphasis.label; + } + } + + function has$2(obj, attr) { + return obj.hasOwnProperty(attr); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + ComponentModel.registerSubTypeDefaulter('timeline', function() { + // Only slider now. + return 'slider'; + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + registerAction( + + { + type: 'timelineChange', + event: 'timelineChanged', + update: 'prepareAndUpdate' + }, + + function(payload, ecModel) { + + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel && payload.currentIndex != null) { + timelineModel.setCurrentIndex(payload.currentIndex); + + if (!timelineModel.get('loop', true) && timelineModel.isIndexMax()) { + timelineModel.setPlayState(false); + } + } + + // Set normalized currentIndex to payload. + ecModel.resetOption('timeline'); + + return defaults({ + currentIndex: timelineModel.option.currentIndex + }, payload); + } + ); + + registerAction( + + { + type: 'timelinePlayChange', + event: 'timelinePlayChanged', + update: 'update' + }, + + function(payload, ecModel) { + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel && payload.playState != null) { + timelineModel.setPlayState(payload.playState); + } + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var TimelineModel = ComponentModel.extend({ + + type: 'timeline', + + layoutMode: 'box', + + /** + * @protected + */ + defaultOption: { + + zlevel: 0, // 一级层叠 + z: 4, // 二级层叠 + show: true, + + axisType: 'time', // 模式是时间类型,支持 value, category + + realtime: true, + + left: '20%', + top: null, + right: '20%', + bottom: 0, + width: null, + height: 40, + padding: 5, + + controlPosition: 'left', // 'left' 'right' 'top' 'bottom' 'none' + autoPlay: false, + rewind: false, // 反向播放 + loop: true, + playInterval: 2000, // 播放时间间隔,单位ms + + currentIndex: 0, + + itemStyle: {}, + label: { + color: '#000' + }, + + data: [] + }, + + /** + * @override + */ + init: function(option, parentModel, ecModel) { + + /** + * @private + * @type {module:echarts/data/List} + */ + this._data; + + /** + * @private + * @type {Array.} + */ + this._names; + + this.mergeDefaultAndTheme(option, ecModel); + this._initData(); + }, + + /** + * @override + */ + mergeOption: function(option) { + TimelineModel.superApply(this, 'mergeOption', arguments); + this._initData(); + }, + + /** + * @param {number} [currentIndex] + */ + setCurrentIndex: function(currentIndex) { + if (currentIndex == null) { + currentIndex = this.option.currentIndex; + } + var count = this._data.count(); + + if (this.option.loop) { + currentIndex = (currentIndex % count + count) % count; + } else { + currentIndex >= count && (currentIndex = count - 1); + currentIndex < 0 && (currentIndex = 0); + } + + this.option.currentIndex = currentIndex; + }, + + /** + * @return {number} currentIndex + */ + getCurrentIndex: function() { + return this.option.currentIndex; + }, + + /** + * @return {boolean} + */ + isIndexMax: function() { + return this.getCurrentIndex() >= this._data.count() - 1; + }, + + /** + * @param {boolean} state true: play, false: stop + */ + setPlayState: function(state) { + this.option.autoPlay = !!state; + }, + + /** + * @return {boolean} true: play, false: stop + */ + getPlayState: function() { + return !!this.option.autoPlay; + }, + + /** + * @private + */ + _initData: function() { + var thisOption = this.option; + var dataArr = thisOption.data || []; + var axisType = thisOption.axisType; + var names = this._names = []; + + if (axisType === 'category') { + var idxArr = []; + each$1(dataArr, function(item, index) { + var value = getDataItemValue(item); + var newItem; + + if (isObject$1(item)) { + newItem = clone(item); + newItem.value = index; + } else { + newItem = index; + } + + idxArr.push(newItem); + + if (!isString(value) && (value == null || isNaN(value))) { + value = ''; + } + + names.push(value + ''); + }); + dataArr = idxArr; + } + + var dimType = ({ + category: 'ordinal', + time: 'time' + })[axisType] || 'number'; + + var data = this._data = new List([{ + name: 'value', + type: dimType + }], this); + + data.initData(dataArr, names); + }, + + getData: function() { + return this._data; + }, + + /** + * @public + * @return {Array.} categoreis + */ + getCategories: function() { + if (this.get('axisType') === 'category') { + return this._names.slice(); + } + } + + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var SliderTimelineModel = TimelineModel.extend({ + + type: 'timeline.slider', + + /** + * @protected + */ + defaultOption: { + + backgroundColor: 'rgba(0,0,0,0)', // 时间轴背景颜色 + borderColor: '#ccc', // 时间轴边框颜色 + borderWidth: 0, // 时间轴边框线宽,单位px,默认为0(无边框) + + orient: 'horizontal', // 'vertical' + inverse: false, + + tooltip: { // boolean or Object + trigger: 'item' // data item may also have tootip attr. + }, + + symbol: 'emptyCircle', + symbolSize: 10, + + lineStyle: { + show: true, + width: 2, + color: '#304654' + }, + label: { // 文本标签 + position: 'auto', // auto left right top bottom + // When using number, label position is not + // restricted by viewRect. + // positive: right/bottom, negative: left/top + show: true, + interval: 'auto', + rotate: 0, + // formatter: null, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#304654' + }, + itemStyle: { + color: '#304654', + borderWidth: 1 + }, + + checkpointStyle: { + symbol: 'circle', + symbolSize: 13, + color: '#c23531', + borderWidth: 5, + borderColor: 'rgba(194,53,49, 0.5)', + animation: true, + animationDuration: 300, + animationEasing: 'quinticInOut' + }, + + controlStyle: { + show: true, + showPlayBtn: true, + showPrevBtn: true, + showNextBtn: true, + itemSize: 22, + itemGap: 12, + position: 'left', // 'left' 'right' 'top' 'bottom' + 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 + 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 + 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 + 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 + + color: '#304654', + borderColor: '#304654', + borderWidth: 1 + }, + + emphasis: { + label: { + show: true, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#c23531' + }, + + itemStyle: { + color: '#c23531' + }, + + controlStyle: { + color: '#c23531', + borderColor: '#c23531', + borderWidth: 2 + } + }, + data: [] + } + + }); + + mixin(SliderTimelineModel, dataFormatMixin); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var TimelineView = Component.extend({ + type: 'timeline' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * Extend axis 2d + * @constructor module:echarts/coord/cartesian/Axis2D + * @extends {module:echarts/coord/cartesian/Axis} + * @param {string} dim + * @param {*} scale + * @param {Array.} coordExtent + * @param {string} axisType + * @param {string} position + */ + var TimelineAxis = function(dim, scale, coordExtent, axisType) { + + Axis.call(this, dim, scale, coordExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = axisType || 'value'; + + /** + * Axis model + * @param {module:echarts/component/TimelineModel} + */ + this.model = null; + }; + + TimelineAxis.prototype = { + + constructor: TimelineAxis, + + /** + * @override + */ + getLabelModel: function() { + return this.model.getModel('label'); + }, + + /** + * @override + */ + isHorizontal: function() { + return this.model.get('orient') === 'horizontal'; + } + + }; + + inherits(TimelineAxis, Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var bind$6 = bind; + var each$27 = each$1; + + var PI$4 = Math.PI; + + TimelineView.extend({ + + type: 'timeline.slider', + + init: function(ecModel, api) { + + this.api = api; + + /** + * @private + * @type {module:echarts/component/timeline/TimelineAxis} + */ + this._axis; + + /** + * @private + * @type {module:zrender/core/BoundingRect} + */ + this._viewRect; + + /** + * @type {number} + */ + this._timer; + + /** + * @type {module:zrender/Element} + */ + this._currentPointer; + + /** + * @type {module:zrender/container/Group} + */ + this._mainGroup; + + /** + * @type {module:zrender/container/Group} + */ + this._labelGroup; + }, + + /** + * @override + */ + render: function(timelineModel, ecModel, api, payload) { + this.model = timelineModel; + this.api = api; + this.ecModel = ecModel; + + this.group.removeAll(); + + if (timelineModel.get('show', true)) { + + var layoutInfo = this._layout(timelineModel, api); + var mainGroup = this._createGroup('mainGroup'); + var labelGroup = this._createGroup('labelGroup'); + + /** + * @private + * @type {module:echarts/component/timeline/TimelineAxis} + */ + var axis = this._axis = this._createAxis(layoutInfo, timelineModel); + + timelineModel.formatTooltip = function(dataIndex) { + return encodeHTML(axis.scale.getLabel(dataIndex)); + }; + + each$27( + ['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'], + function(name) { + this['_render' + name](layoutInfo, mainGroup, axis, timelineModel); + }, + this + ); + + this._renderAxisLabel(layoutInfo, labelGroup, axis, timelineModel); + this._position(layoutInfo, timelineModel); + } + + this._doPlayStop(); + }, + + /** + * @override + */ + remove: function() { + this._clearTimer(); + this.group.removeAll(); + }, + + /** + * @override + */ + dispose: function() { + this._clearTimer(); + }, + + _layout: function(timelineModel, api) { + var labelPosOpt = timelineModel.get('label.position'); + var orient = timelineModel.get('orient'); + var viewRect = getViewRect$4(timelineModel, api); + // Auto label offset. + if (labelPosOpt == null || labelPosOpt === 'auto') { + labelPosOpt = orient === 'horizontal' ? + ((viewRect.y + viewRect.height / 2) < api.getHeight() / 2 ? '-' : '+') : + ((viewRect.x + viewRect.width / 2) < api.getWidth() / 2 ? '+' : '-'); + } else if (isNaN(labelPosOpt)) { + labelPosOpt = ({ + horizontal: { + top: '-', + bottom: '+' + }, + vertical: { + left: '-', + right: '+' + } + })[orient][labelPosOpt]; + } + + var labelAlignMap = { + horizontal: 'center', + vertical: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'left' : 'right' + }; + + var labelBaselineMap = { + horizontal: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'top' : 'bottom', + vertical: 'middle' + }; + var rotationMap = { + horizontal: 0, + vertical: PI$4 / 2 + }; + + // Position + var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width; + + var controlModel = timelineModel.getModel('controlStyle'); + var showControl = controlModel.get('show', true); + var controlSize = showControl ? controlModel.get('itemSize') : 0; + var controlGap = showControl ? controlModel.get('itemGap') : 0; + var sizePlusGap = controlSize + controlGap; + + // Special label rotate. + var labelRotation = timelineModel.get('label.rotate') || 0; + labelRotation = labelRotation * PI$4 / 180; // To radian. + + var playPosition; + var prevBtnPosition; + var nextBtnPosition; + var axisExtent; + var controlPosition = controlModel.get('position', true); + var showPlayBtn = showControl && controlModel.get('showPlayBtn', true); + var showPrevBtn = showControl && controlModel.get('showPrevBtn', true); + var showNextBtn = showControl && controlModel.get('showNextBtn', true); + var xLeft = 0; + var xRight = mainLength; + + // position[0] means left, position[1] means middle. + if (controlPosition === 'left' || controlPosition === 'bottom') { + showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap); + showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap); + showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + } else { // 'top' 'right' + showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap); + showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + } + axisExtent = [xLeft, xRight]; + + if (timelineModel.get('inverse')) { + axisExtent.reverse(); + } + + return { + viewRect: viewRect, + mainLength: mainLength, + orient: orient, + + rotation: rotationMap[orient], + labelRotation: labelRotation, + labelPosOpt: labelPosOpt, + labelAlign: timelineModel.get('label.align') || labelAlignMap[orient], + labelBaseline: timelineModel.get('label.verticalAlign') || + timelineModel.get('label.baseline') || + labelBaselineMap[orient], + + // Based on mainGroup. + playPosition: playPosition, + prevBtnPosition: prevBtnPosition, + nextBtnPosition: nextBtnPosition, + axisExtent: axisExtent, + + controlSize: controlSize, + controlGap: controlGap + }; + }, + + _position: function(layoutInfo, timelineModel) { + // Position is be called finally, because bounding rect is needed for + // adapt content to fill viewRect (auto adapt offset). + + // Timeline may be not all in the viewRect when 'offset' is specified + // as a number, because it is more appropriate that label aligns at + // 'offset' but not the other edge defined by viewRect. + + var mainGroup = this._mainGroup; + var labelGroup = this._labelGroup; + + var viewRect = layoutInfo.viewRect; + if (layoutInfo.orient === 'vertical') { + // transform to horizontal, inverse rotate by left-top point. + var m = create$1(); + var rotateOriginX = viewRect.x; + var rotateOriginY = viewRect.y + viewRect.height; + translate(m, m, [-rotateOriginX, -rotateOriginY]); + rotate(m, m, -PI$4 / 2); + translate(m, m, [rotateOriginX, rotateOriginY]); + viewRect = viewRect.clone(); + viewRect.applyTransform(m); + } + + var viewBound = getBound(viewRect); + var mainBound = getBound(mainGroup.getBoundingRect()); + var labelBound = getBound(labelGroup.getBoundingRect()); + + var mainPosition = mainGroup.position; + var labelsPosition = labelGroup.position; + + labelsPosition[0] = mainPosition[0] = viewBound[0][0]; + + var labelPosOpt = layoutInfo.labelPosOpt; + + if (isNaN(labelPosOpt)) { // '+' or '-' + var mainBoundIdx = labelPosOpt === '+' ? 0 : 1; + toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); + toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx); + } else { + var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1; + toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); + labelsPosition[1] = mainPosition[1] + labelPosOpt; + } + + mainGroup.attr('position', mainPosition); + labelGroup.attr('position', labelsPosition); + mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation; + + setOrigin(mainGroup); + setOrigin(labelGroup); + + function setOrigin(targetGroup) { + var pos = targetGroup.position; + targetGroup.origin = [ + viewBound[0][0] - pos[0], + viewBound[1][0] - pos[1] + ]; + } + + function getBound(rect) { + // [[xmin, xmax], [ymin, ymax]] + return [ + [rect.x, rect.x + rect.width], + [rect.y, rect.y + rect.height] + ]; + } + + function toBound(fromPos, from, to, dimIdx, boundIdx) { + fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx]; + } + }, + + _createAxis: function(layoutInfo, timelineModel) { + var data = timelineModel.getData(); + var axisType = timelineModel.get('axisType'); + + var scale = createScaleByModel(timelineModel, axisType); + + // Customize scale. The `tickValue` is `dataIndex`. + scale.getTicks = function() { + return data.mapArray(['value'], function(value) { + return value; + }); + }; + + var dataExtent = data.getDataExtent('value'); + scale.setExtent(dataExtent[0], dataExtent[1]); + scale.niceTicks(); + + var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType); + axis.model = timelineModel; + + return axis; + }, + + _createGroup: function(name) { + var newGroup = this['_' + name] = new Group(); + this.group.add(newGroup); + return newGroup; + }, + + _renderAxisLine: function(layoutInfo, group, axis, timelineModel) { + var axisExtent = axis.getExtent(); + + if (!timelineModel.get('lineStyle.show')) { + return; + } + + group.add(new Line({ + shape: { + x1: axisExtent[0], + y1: 0, + x2: axisExtent[1], + y2: 0 + }, + style: extend({ + lineCap: 'round' + }, + timelineModel.getModel('lineStyle').getLineStyle() + ), + silent: true, + z2: 1 + })); + }, + + /** + * @private + */ + _renderAxisTick: function(layoutInfo, group, axis, timelineModel) { + var data = timelineModel.getData(); + // Show all ticks, despite ignoring strategy. + var ticks = axis.scale.getTicks(); + + // The value is dataIndex, see the costomized scale. + each$27(ticks, function(value) { + var tickCoord = axis.dataToCoord(value); + var itemModel = data.getItemModel(value); + var itemStyleModel = itemModel.getModel('itemStyle'); + var hoverStyleModel = itemModel.getModel('emphasis.itemStyle'); + var symbolOpt = { + position: [tickCoord, 0], + onclick: bind$6(this._changeTimeline, this, value) + }; + var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt); + setHoverStyle(el, hoverStyleModel.getItemStyle()); + + if (itemModel.get('tooltip')) { + el.dataIndex = value; + el.dataModel = timelineModel; + } else { + el.dataIndex = el.dataModel = null; + } + + }, this); + }, + + /** + * @private + */ + _renderAxisLabel: function(layoutInfo, group, axis, timelineModel) { + var labelModel = axis.getLabelModel(); + + if (!labelModel.get('show')) { + return; + } + + var data = timelineModel.getData(); + var labels = axis.getViewLabels(); + + each$27(labels, function(labelItem) { + // The tickValue is dataIndex, see the costomized scale. + var dataIndex = labelItem.tickValue; + + var itemModel = data.getItemModel(dataIndex); + var normalLabelModel = itemModel.getModel('label'); + var hoverLabelModel = itemModel.getModel('emphasis.label'); + var tickCoord = axis.dataToCoord(labelItem.tickValue); + var textEl = new Text({ + position: [tickCoord, 0], + rotation: layoutInfo.labelRotation - layoutInfo.rotation, + onclick: bind$6(this._changeTimeline, this, dataIndex), + silent: false + }); + setTextStyle(textEl.style, normalLabelModel, { + text: labelItem.formattedLabel, + textAlign: layoutInfo.labelAlign, + textVerticalAlign: layoutInfo.labelBaseline + }); + + group.add(textEl); + setHoverStyle( + textEl, setTextStyle({}, hoverLabelModel) + ); + + }, this); + }, + + /** + * @private + */ + _renderControl: function(layoutInfo, group, axis, timelineModel) { + var controlSize = layoutInfo.controlSize; + var rotation = layoutInfo.rotation; + + var itemStyle = timelineModel.getModel('controlStyle').getItemStyle(); + var hoverStyle = timelineModel.getModel('emphasis.controlStyle').getItemStyle(); + var rect = [0, -controlSize / 2, controlSize, controlSize]; + var playState = timelineModel.getPlayState(); + var inverse = timelineModel.get('inverse', true); + + makeBtn( + layoutInfo.nextBtnPosition, + 'controlStyle.nextIcon', + bind$6(this._changeTimeline, this, inverse ? '-' : '+') + ); + makeBtn( + layoutInfo.prevBtnPosition, + 'controlStyle.prevIcon', + bind$6(this._changeTimeline, this, inverse ? '+' : '-') + ); + makeBtn( + layoutInfo.playPosition, + 'controlStyle.' + (playState ? 'stopIcon' : 'playIcon'), + bind$6(this._handlePlayClick, this, !playState), + true + ); + + function makeBtn(position, iconPath, onclick, willRotate) { + if (!position) { + return; + } + var opt = { + position: position, + origin: [controlSize / 2, 0], + rotation: willRotate ? -rotation : 0, + rectHover: true, + style: itemStyle, + onclick: onclick + }; + var btn = makeIcon(timelineModel, iconPath, rect, opt); + group.add(btn); + setHoverStyle(btn, hoverStyle); + } + }, + + _renderCurrentPointer: function(layoutInfo, group, axis, timelineModel) { + var data = timelineModel.getData(); + var currentIndex = timelineModel.getCurrentIndex(); + var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle'); + var me = this; + + var callback = { + onCreate: function(pointer) { + pointer.draggable = true; + pointer.drift = bind$6(me._handlePointerDrag, me); + pointer.ondragend = bind$6(me._handlePointerDragend, me); + pointerMoveTo(pointer, currentIndex, axis, timelineModel, true); + }, + onUpdate: function(pointer) { + pointerMoveTo(pointer, currentIndex, axis, timelineModel); + } + }; + + // Reuse when exists, for animation and drag. + this._currentPointer = giveSymbol( + pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback + ); + }, + + _handlePlayClick: function(nextState) { + this._clearTimer(); + this.api.dispatchAction({ + type: 'timelinePlayChange', + playState: nextState, + from: this.uid + }); + }, + + _handlePointerDrag: function(dx, dy, e) { + this._clearTimer(); + this._pointerChangeTimeline([e.offsetX, e.offsetY]); + }, + + _handlePointerDragend: function(e) { + this._pointerChangeTimeline([e.offsetX, e.offsetY], true); + }, + + _pointerChangeTimeline: function(mousePos, trigger) { + var toCoord = this._toAxisCoord(mousePos)[0]; + + var axis = this._axis; + var axisExtent = asc(axis.getExtent().slice()); + + toCoord > axisExtent[1] && (toCoord = axisExtent[1]); + toCoord < axisExtent[0] && (toCoord = axisExtent[0]); + + this._currentPointer.position[0] = toCoord; + this._currentPointer.dirty(); + + var targetDataIndex = this._findNearestTick(toCoord); + var timelineModel = this.model; + + if (trigger || ( + targetDataIndex !== timelineModel.getCurrentIndex() && + timelineModel.get('realtime') + )) { + this._changeTimeline(targetDataIndex); + } + }, + + _doPlayStop: function() { + this._clearTimer(); + + if (this.model.getPlayState()) { + this._timer = setTimeout( + bind$6(handleFrame, this), + this.model.get('playInterval') + ); + } + + function handleFrame() { + // Do not cache + var timelineModel = this.model; + this._changeTimeline( + timelineModel.getCurrentIndex() + + (timelineModel.get('rewind', true) ? -1 : 1) + ); + } + }, + + _toAxisCoord: function(vertex) { + var trans = this._mainGroup.getLocalTransform(); + return applyTransform$1(vertex, trans, true); + }, + + _findNearestTick: function(axisCoord) { + var data = this.model.getData(); + var dist = Infinity; + var targetDataIndex; + var axis = this._axis; + + data.each(['value'], function(value, dataIndex) { + var coord = axis.dataToCoord(value); + var d = Math.abs(coord - axisCoord); + if (d < dist) { + dist = d; + targetDataIndex = dataIndex; + } + }); + + return targetDataIndex; + }, + + _clearTimer: function() { + if (this._timer) { + clearTimeout(this._timer); + this._timer = null; + } + }, + + _changeTimeline: function(nextIndex) { + var currentIndex = this.model.getCurrentIndex(); + + if (nextIndex === '+') { + nextIndex = currentIndex + 1; + } else if (nextIndex === '-') { + nextIndex = currentIndex - 1; + } + + this.api.dispatchAction({ + type: 'timelineChange', + currentIndex: nextIndex, + from: this.uid + }); + } + + }); + + function getViewRect$4(model, api) { + return getLayoutRect( + model.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }, + model.get('padding') + ); + } + + function makeIcon(timelineModel, objPath, rect, opts) { + var icon = makePath( + timelineModel.get(objPath).replace(/^path:\/\//, ''), + clone(opts || {}), + new BoundingRect(rect[0], rect[1], rect[2], rect[3]), + 'center' + ); + + return icon; + } + + /** + * Create symbol or update symbol + * opt: basic position and event handlers + */ + function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) { + var color = itemStyleModel.get('color'); + + if (!symbol) { + var symbolType = hostModel.get('symbol'); + symbol = createSymbol(symbolType, -1, -1, 2, 2, color); + symbol.setStyle('strokeNoScale', true); + group.add(symbol); + callback && callback.onCreate(symbol); + } else { + symbol.setColor(color); + group.add(symbol); // Group may be new, also need to add. + callback && callback.onUpdate(symbol); + } + + // Style + var itemStyle = itemStyleModel.getItemStyle(['color', 'symbol', 'symbolSize']); + symbol.setStyle(itemStyle); + + // Transform and events. + opt = merge({ + rectHover: true, + z2: 100 + }, opt, true); + + var symbolSize = hostModel.get('symbolSize'); + symbolSize = symbolSize instanceof Array ? + symbolSize.slice() : + [+symbolSize, +symbolSize]; + symbolSize[0] /= 2; + symbolSize[1] /= 2; + opt.scale = symbolSize; + + var symbolOffset = hostModel.get('symbolOffset'); + if (symbolOffset) { + var pos = opt.position = opt.position || [0, 0]; + pos[0] += parsePercent$1(symbolOffset[0], symbolSize[0]); + pos[1] += parsePercent$1(symbolOffset[1], symbolSize[1]); + } + + var symbolRotate = hostModel.get('symbolRotate'); + opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0; + + symbol.attr(opt); + + // FIXME + // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed, + // getBoundingRect will return wrong result. + // (This is supposed to be resolved in zrender, but it is a little difficult to + // leverage performance and auto updateTransform) + // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol. + symbol.updateTransform(); + + return symbol; + } + + function pointerMoveTo(pointer, dataIndex, axis, timelineModel, noAnimation) { + if (pointer.dragging) { + return; + } + + var pointerModel = timelineModel.getModel('checkpointStyle'); + var toCoord = axis.dataToCoord(timelineModel.getData().get(['value'], dataIndex)); + + if (noAnimation || !pointerModel.get('animation', true)) { + pointer.attr({ + position: [toCoord, 0] + }); + } else { + pointer.stopAnimation(true); + pointer.animateTo({ + position: [toCoord, 0] + }, + pointerModel.get('animationDuration', true), + pointerModel.get('animationEasing', true) + ); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * DataZoom component entry + */ + + registerPreprocessor(preprocessor$3); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var ToolboxModel = extendComponentModel({ + + type: 'toolbox', + + layoutMode: { + type: 'box', + ignoreSize: true + }, + + optionUpdated: function() { + ToolboxModel.superApply(this, 'optionUpdated', arguments); + + each$1(this.option.feature, function(featureOpt, featureName) { + var Feature = get$1(featureName); + Feature && merge(featureOpt, Feature.defaultOption); + }); + }, + + defaultOption: { + + show: true, + + z: 6, + + zlevel: 0, + + orient: 'horizontal', + + left: 'right', + + top: 'top', + + // right + // bottom + + backgroundColor: 'transparent', + + borderColor: '#ccc', + + borderRadius: 0, + + borderWidth: 0, + + padding: 5, + + itemSize: 15, + + itemGap: 8, + + showTitle: true, + + iconStyle: { + borderColor: '#666', + color: 'none' + }, + emphasis: { + iconStyle: { + borderColor: '#3E98C5' + } + } + // textStyle: {}, + + // feature + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + extendComponentView({ + + type: 'toolbox', + + render: function(toolboxModel, ecModel, api, payload) { + var group = this.group; + group.removeAll(); + + if (!toolboxModel.get('show')) { + return; + } + + var itemSize = +toolboxModel.get('itemSize'); + var featureOpts = toolboxModel.get('feature') || {}; + var features = this._features || (this._features = {}); + + var featureNames = []; + each$1(featureOpts, function(opt, name) { + featureNames.push(name); + }); + + (new DataDiffer(this._featureNames || [], featureNames)) + .add(processFeature) + .update(processFeature) + .remove(curry(processFeature, null)) + .execute(); + + // Keep for diff. + this._featureNames = featureNames; + + function processFeature(newIndex, oldIndex) { + var featureName = featureNames[newIndex]; + var oldName = featureNames[oldIndex]; + var featureOpt = featureOpts[featureName]; + var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel); + var feature; + + if (featureName && !oldName) { // Create + if (isUserFeatureName(featureName)) { + feature = { + model: featureModel, + onclick: featureModel.option.onclick, + featureName: featureName + }; + } else { + var Feature = get$1(featureName); + if (!Feature) { + return; + } + feature = new Feature(featureModel, ecModel, api); + } + features[featureName] = feature; + } else { + feature = features[oldName]; + // If feature does not exsit. + if (!feature) { + return; + } + feature.model = featureModel; + feature.ecModel = ecModel; + feature.api = api; + } + + if (!featureName && oldName) { + feature.dispose && feature.dispose(ecModel, api); + return; + } + + if (!featureModel.get('show') || feature.unusable) { + feature.remove && feature.remove(ecModel, api); + return; + } + + createIconPaths(featureModel, feature, featureName); + + featureModel.setIconStatus = function(iconName, status) { + var option = this.option; + var iconPaths = this.iconPaths; + option.iconStatus = option.iconStatus || {}; + option.iconStatus[iconName] = status; + // FIXME + iconPaths[iconName] && iconPaths[iconName].trigger(status); + }; + + if (feature.render) { + feature.render(featureModel, ecModel, api, payload); + } + } + + function createIconPaths(featureModel, feature, featureName) { + var iconStyleModel = featureModel.getModel('iconStyle'); + var iconStyleEmphasisModel = featureModel.getModel('emphasis.iconStyle'); + + // If one feature has mutiple icon. they are orginaized as + // { + // icon: { + // foo: '', + // bar: '' + // }, + // title: { + // foo: '', + // bar: '' + // } + // } + var icons = feature.getIcons ? feature.getIcons() : featureModel.get('icon'); + var titles = featureModel.get('title') || {}; + if (typeof icons === 'string') { + var icon = icons; + var title = titles; + icons = {}; + titles = {}; + icons[featureName] = icon; + titles[featureName] = title; + } + var iconPaths = featureModel.iconPaths = {}; + each$1(icons, function(iconStr, iconName) { + var path = createIcon( + iconStr, {}, { + x: -itemSize / 2, + y: -itemSize / 2, + width: itemSize, + height: itemSize + } + ); + path.setStyle(iconStyleModel.getItemStyle()); + path.hoverStyle = iconStyleEmphasisModel.getItemStyle(); + + setHoverStyle(path); + + if (toolboxModel.get('showTitle')) { + path.__title = titles[iconName]; + path.on('mouseover', function() { + // Should not reuse above hoverStyle, which might be modified. + var hoverStyle = iconStyleEmphasisModel.getItemStyle(); + path.setStyle({ + text: titles[iconName], + textPosition: hoverStyle.textPosition || 'bottom', + textFill: hoverStyle.fill || hoverStyle.stroke || '#000', + textAlign: hoverStyle.textAlign || 'center' + }); + }) + .on('mouseout', function() { + path.setStyle({ + textFill: null + }); + }); + } + path.trigger(featureModel.get('iconStatus.' + iconName) || 'normal'); + + group.add(path); + path.on('click', bind( + feature.onclick, feature, ecModel, api, iconName + )); + + iconPaths[iconName] = path; + }); + } + + layout$3(group, toolboxModel, api); + // Render background after group is layout + // FIXME + group.add(makeBackground(group.getBoundingRect(), toolboxModel)); + + // Adjust icon title positions to avoid them out of screen + group.eachChild(function(icon) { + var titleText = icon.__title; + var hoverStyle = icon.hoverStyle; + // May be background element + if (hoverStyle && titleText) { + var rect = getBoundingRect( + titleText, makeFont(hoverStyle) + ); + var offsetX = icon.position[0] + group.position[0]; + var offsetY = icon.position[1] + group.position[1] + itemSize; + + var needPutOnTop = false; + if (offsetY + rect.height > api.getHeight()) { + hoverStyle.textPosition = 'top'; + needPutOnTop = true; + } + var topOffset = needPutOnTop ? (-5 - rect.height) : (itemSize + 8); + if (offsetX + rect.width / 2 > api.getWidth()) { + hoverStyle.textPosition = ['100%', topOffset]; + hoverStyle.textAlign = 'right'; + } else if (offsetX - rect.width / 2 < 0) { + hoverStyle.textPosition = [0, topOffset]; + hoverStyle.textAlign = 'left'; + } + } + }); + }, + + updateView: function(toolboxModel, ecModel, api, payload) { + each$1(this._features, function(feature) { + feature.updateView && feature.updateView(feature.model, ecModel, api, payload); + }); + }, + + // updateLayout: function (toolboxModel, ecModel, api, payload) { + // zrUtil.each(this._features, function (feature) { + // feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload); + // }); + // }, + + remove: function(ecModel, api) { + each$1(this._features, function(feature) { + feature.remove && feature.remove(ecModel, api); + }); + this.group.removeAll(); + }, + + dispose: function(ecModel, api) { + each$1(this._features, function(feature) { + feature.dispose && feature.dispose(ecModel, api); + }); + } + }); + + function isUserFeatureName(featureName) { + return featureName.indexOf('my') === 0; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var saveAsImageLang = lang.toolbox.saveAsImage; + + function SaveAsImage(model) { + this.model = model; + } + + SaveAsImage.defaultOption = { + show: true, + 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', + title: saveAsImageLang.title, + type: 'png', + // Default use option.backgroundColor + // backgroundColor: '#fff', + name: '', + excludeComponents: ['toolbox'], + pixelRatio: 1, + lang: saveAsImageLang.lang.slice() + }; + + SaveAsImage.prototype.unusable = !env$1.canvasSupported; + + var proto$4 = SaveAsImage.prototype; + + proto$4.onclick = function(ecModel, api) { + var model = this.model; + var title = model.get('name') || ecModel.get('title.0.text') || 'echarts'; + var $a = document.createElement('a'); + var type = model.get('type', true) || 'png'; + $a.download = title + '.' + type; + $a.target = '_blank'; + var url = api.getConnectedDataURL({ + type: type, + backgroundColor: model.get('backgroundColor', true) || + ecModel.get('backgroundColor') || '#fff', + excludeComponents: model.get('excludeComponents'), + pixelRatio: model.get('pixelRatio') + }); + $a.href = url; + // Chrome and Firefox + if (typeof MouseEvent === 'function' && !env$1.browser.ie && !env$1.browser.edge) { + var evt = new MouseEvent('click', { + view: window, + bubbles: true, + cancelable: false + }); + $a.dispatchEvent(evt); + } + // IE + else { + if (window.navigator.msSaveOrOpenBlob) { + var bstr = atob(url.split(',')[1]); + var n = bstr.length; + var u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + var blob = new Blob([u8arr]); + window.navigator.msSaveOrOpenBlob(blob, title + '.' + type); + } else { + var lang$$1 = model.get('lang'); + var html = '' + + '' + + '' + + ''; + var tab = window.open(); + tab.document.write(html); + } + } + }; + + register$1( + 'saveAsImage', SaveAsImage + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var magicTypeLang = lang.toolbox.magicType; + + function MagicType(model) { + this.model = model; + } + + MagicType.defaultOption = { + show: true, + type: [], + // Icon group + icon: { + line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4', + bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7', + 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 + tiled: 'M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z' + }, + // `line`, `bar`, `stack`, `tiled` + title: clone(magicTypeLang.title), + option: {}, + seriesIndex: {} + }; + + var proto$5 = MagicType.prototype; + + proto$5.getIcons = function() { + var model = this.model; + var availableIcons = model.get('icon'); + var icons = {}; + each$1(model.get('type'), function(type) { + if (availableIcons[type]) { + icons[type] = availableIcons[type]; + } + }); + return icons; + }; + + var seriesOptGenreator = { + 'line': function(seriesType, seriesId, seriesModel, model) { + if (seriesType === 'bar') { + return merge({ + id: seriesId, + type: 'line', + // Preserve data related option + data: seriesModel.get('data'), + stack: seriesModel.get('stack'), + markPoint: seriesModel.get('markPoint'), + markLine: seriesModel.get('markLine') + }, model.get('option.line') || {}, true); + } + }, + 'bar': function(seriesType, seriesId, seriesModel, model) { + if (seriesType === 'line') { + return merge({ + id: seriesId, + type: 'bar', + // Preserve data related option + data: seriesModel.get('data'), + stack: seriesModel.get('stack'), + markPoint: seriesModel.get('markPoint'), + markLine: seriesModel.get('markLine') + }, model.get('option.bar') || {}, true); + } + }, + 'stack': function(seriesType, seriesId, seriesModel, model) { + if (seriesType === 'line' || seriesType === 'bar') { + return merge({ + id: seriesId, + stack: '__ec_magicType_stack__' + }, model.get('option.stack') || {}, true); + } + }, + 'tiled': function(seriesType, seriesId, seriesModel, model) { + if (seriesType === 'line' || seriesType === 'bar') { + return merge({ + id: seriesId, + stack: '' + }, model.get('option.tiled') || {}, true); + } + } + }; + + var radioTypes = [ + ['line', 'bar'], + ['stack', 'tiled'] + ]; + + proto$5.onclick = function(ecModel, api, type) { + var model = this.model; + var seriesIndex = model.get('seriesIndex.' + type); + // Not supported magicType + if (!seriesOptGenreator[type]) { + return; + } + var newOption = { + series: [] + }; + var generateNewSeriesTypes = function(seriesModel) { + var seriesType = seriesModel.subType; + var seriesId = seriesModel.id; + var newSeriesOpt = seriesOptGenreator[type]( + seriesType, seriesId, seriesModel, model + ); + if (newSeriesOpt) { + // PENDING If merge original option? + defaults(newSeriesOpt, seriesModel.option); + newOption.series.push(newSeriesOpt); + } + // Modify boundaryGap + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type === 'cartesian2d' && (type === 'line' || type === 'bar')) { + var categoryAxis = coordSys.getAxesByScale('ordinal')[0]; + if (categoryAxis) { + var axisDim = categoryAxis.dim; + var axisType = axisDim + 'Axis'; + var axisModel = ecModel.queryComponents({ + mainType: axisType, + index: seriesModel.get(name + 'Index'), + id: seriesModel.get(name + 'Id') + })[0]; + var axisIndex = axisModel.componentIndex; + + newOption[axisType] = newOption[axisType] || []; + for (var i = 0; i <= axisIndex; i++) { + newOption[axisType][axisIndex] = newOption[axisType][axisIndex] || {}; + } + newOption[axisType][axisIndex].boundaryGap = type === 'bar' ? true : false; + } + } + }; + + each$1(radioTypes, function(radio) { + if (indexOf(radio, type) >= 0) { + each$1(radio, function(item) { + model.setIconStatus(item, 'normal'); + }); + } + }); + + model.setIconStatus(type, 'emphasis'); + + ecModel.eachComponent({ + mainType: 'series', + query: seriesIndex == null ? null : { + seriesIndex: seriesIndex + } + }, generateNewSeriesTypes); + api.dispatchAction({ + type: 'changeMagicType', + currentType: type, + newOption: newOption + }); + }; + + registerAction({ + type: 'changeMagicType', + event: 'magicTypeChanged', + update: 'prepareAndUpdate' + }, function(payload, ecModel) { + ecModel.mergeOption(payload.newOption); + }); + + register$1('magicType', MagicType); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var dataViewLang = lang.toolbox.dataView; + + var BLOCK_SPLITER = new Array(60).join('-'); + var ITEM_SPLITER = '\t'; + /** + * Group series into two types + * 1. on category axis, like line, bar + * 2. others, like scatter, pie + * @param {module:echarts/model/Global} ecModel + * @return {Object} + * @inner + */ + function groupSeries(ecModel) { + var seriesGroupByCategoryAxis = {}; + var otherSeries = []; + var meta = []; + ecModel.eachRawSeries(function(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + + if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) { + var baseAxis = coordSys.getBaseAxis(); + if (baseAxis.type === 'category') { + var key = baseAxis.dim + '_' + baseAxis.index; + if (!seriesGroupByCategoryAxis[key]) { + seriesGroupByCategoryAxis[key] = { + categoryAxis: baseAxis, + valueAxis: coordSys.getOtherAxis(baseAxis), + series: [] + }; + meta.push({ + axisDim: baseAxis.dim, + axisIndex: baseAxis.index + }); + } + seriesGroupByCategoryAxis[key].series.push(seriesModel); + } else { + otherSeries.push(seriesModel); + } + } else { + otherSeries.push(seriesModel); + } + }); + + return { + seriesGroupByCategoryAxis: seriesGroupByCategoryAxis, + other: otherSeries, + meta: meta + }; + } + + /** + * Assemble content of series on cateogory axis + * @param {Array.} series + * @return {string} + * @inner + */ + function assembleSeriesWithCategoryAxis(series) { + var tables = []; + each$1(series, function(group, key) { + var categoryAxis = group.categoryAxis; + var valueAxis = group.valueAxis; + var valueAxisDim = valueAxis.dim; + + var headers = [' '].concat(map(group.series, function(series) { + return series.name; + })); + var columns = [categoryAxis.model.getCategories()]; + each$1(group.series, function(series) { + columns.push(series.getRawData().mapArray(valueAxisDim, function(val) { + return val; + })); + }); + // Assemble table content + var lines = [headers.join(ITEM_SPLITER)]; + for (var i = 0; i < columns[0].length; i++) { + var items = []; + for (var j = 0; j < columns.length; j++) { + items.push(columns[j][i]); + } + lines.push(items.join(ITEM_SPLITER)); + } + tables.push(lines.join('\n')); + }); + return tables.join('\n\n' + BLOCK_SPLITER + '\n\n'); + } + + /** + * Assemble content of other series + * @param {Array.} series + * @return {string} + * @inner + */ + function assembleOtherSeries(series) { + return map(series, function(series) { + var data = series.getRawData(); + var lines = [series.name]; + var vals = []; + data.each(data.dimensions, function() { + var argLen = arguments.length; + var dataIndex = arguments[argLen - 1]; + var name = data.getName(dataIndex); + for (var i = 0; i < argLen - 1; i++) { + vals[i] = arguments[i]; + } + lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER)); + }); + return lines.join('\n'); + }).join('\n\n' + BLOCK_SPLITER + '\n\n'); + } + + /** + * @param {module:echarts/model/Global} + * @return {Object} + * @inner + */ + function getContentFromModel(ecModel) { + + var result = groupSeries(ecModel); + + return { + value: filter([ + assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis), + assembleOtherSeries(result.other) + ], function(str) { + return str.replace(/[\n\t\s]/g, ''); + }).join('\n\n' + BLOCK_SPLITER + '\n\n'), + + meta: result.meta + }; + } + + + function trim$1(str) { + return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + /** + * If a block is tsv format + */ + function isTSVFormat(block) { + // Simple method to find out if a block is tsv format + var firstLine = block.slice(0, block.indexOf('\n')); + if (firstLine.indexOf(ITEM_SPLITER) >= 0) { + return true; + } + } + + var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g'); + /** + * @param {string} tsv + * @return {Object} + */ + function parseTSVContents(tsv) { + var tsvLines = tsv.split(/\n+/g); + var headers = trim$1(tsvLines.shift()).split(itemSplitRegex); + + var categories = []; + var series = map(headers, function(header) { + return { + name: header, + data: [] + }; + }); + for (var i = 0; i < tsvLines.length; i++) { + var items = trim$1(tsvLines[i]).split(itemSplitRegex); + categories.push(items.shift()); + for (var j = 0; j < items.length; j++) { + series[j] && (series[j].data[i] = items[j]); + } + } + return { + series: series, + categories: categories + }; + } + + /** + * @param {string} str + * @return {Array.} + * @inner + */ + function parseListContents(str) { + var lines = str.split(/\n+/g); + var seriesName = trim$1(lines.shift()); + + var data = []; + for (var i = 0; i < lines.length; i++) { + var items = trim$1(lines[i]).split(itemSplitRegex); + var name = ''; + var value; + var hasName = false; + if (isNaN(items[0])) { // First item is name + hasName = true; + name = items[0]; + items = items.slice(1); + data[i] = { + name: name, + value: [] + }; + value = data[i].value; + } else { + value = data[i] = []; + } + for (var j = 0; j < items.length; j++) { + value.push(+items[j]); + } + if (value.length === 1) { + hasName ? (data[i].value = value[0]) : (data[i] = value[0]); + } + } + + return { + name: seriesName, + data: data + }; + } + + /** + * @param {string} str + * @param {Array.} blockMetaList + * @return {Object} + * @inner + */ + function parseContents(str, blockMetaList) { + var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g')); + var newOption = { + series: [] + }; + each$1(blocks, function(block, idx) { + if (isTSVFormat(block)) { + var result = parseTSVContents(block); + var blockMeta = blockMetaList[idx]; + var axisKey = blockMeta.axisDim + 'Axis'; + + if (blockMeta) { + newOption[axisKey] = newOption[axisKey] || []; + newOption[axisKey][blockMeta.axisIndex] = { + data: result.categories + }; + newOption.series = newOption.series.concat(result.series); + } + } else { + var result = parseListContents(block); + newOption.series.push(result); + } + }); + return newOption; + } + + /** + * @alias {module:echarts/component/toolbox/feature/DataView} + * @constructor + * @param {module:echarts/model/Model} model + */ + function DataView(model) { + + this._dom = null; + + this.model = model; + } + + DataView.defaultOption = { + show: true, + readOnly: false, + optionToContent: null, + contentToOption: null, + + 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', + title: clone(dataViewLang.title), + lang: clone(dataViewLang.lang), + backgroundColor: '#fff', + textColor: '#000', + textareaColor: '#fff', + textareaBorderColor: '#333', + buttonColor: '#c23531', + buttonTextColor: '#fff' + }; + + DataView.prototype.onclick = function(ecModel, api) { + var container = api.getDom(); + var model = this.model; + if (this._dom) { + container.removeChild(this._dom); + } + var root = document.createElement('div'); + root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;'; + root.style.backgroundColor = model.get('backgroundColor') || '#fff'; + + // Create elements + var header = document.createElement('h4'); + var lang$$1 = model.get('lang') || []; + header.innerHTML = lang$$1[0] || model.get('title'); + header.style.cssText = 'margin: 10px 20px;'; + header.style.color = model.get('textColor'); + + var viewMain = document.createElement('div'); + var textarea = document.createElement('textarea'); + viewMain.style.cssText = 'display:block;width:100%;overflow:auto;'; + + var optionToContent = model.get('optionToContent'); + var contentToOption = model.get('contentToOption'); + var result = getContentFromModel(ecModel); + if (typeof optionToContent === 'function') { + var htmlOrDom = optionToContent(api.getOption()); + if (typeof htmlOrDom === 'string') { + viewMain.innerHTML = htmlOrDom; + } else if (isDom(htmlOrDom)) { + viewMain.appendChild(htmlOrDom); + } + } else { + // Use default textarea + viewMain.appendChild(textarea); + textarea.readOnly = model.get('readOnly'); + textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;'; + textarea.style.color = model.get('textColor'); + textarea.style.borderColor = model.get('textareaBorderColor'); + textarea.style.backgroundColor = model.get('textareaColor'); + textarea.value = result.value; + } + + var blockMetaList = result.meta; + + var buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;'; + + var buttonStyle = 'float:right;margin-right:20px;border:none;' + + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px'; + var closeButton = document.createElement('div'); + var refreshButton = document.createElement('div'); + + buttonStyle += ';background-color:' + model.get('buttonColor'); + buttonStyle += ';color:' + model.get('buttonTextColor'); + + var self = this; + + function close() { + container.removeChild(root); + self._dom = null; + } + addEventListener(closeButton, 'click', close); + + addEventListener(refreshButton, 'click', function() { + var newOption; + try { + if (typeof contentToOption === 'function') { + newOption = contentToOption(viewMain, api.getOption()); + } else { + newOption = parseContents(textarea.value, blockMetaList); + } + } catch (e) { + close(); + throw new Error('Data view format error ' + e); + } + if (newOption) { + api.dispatchAction({ + type: 'changeDataView', + newOption: newOption + }); + } + + close(); + }); + + closeButton.innerHTML = lang$$1[1]; + refreshButton.innerHTML = lang$$1[2]; + refreshButton.style.cssText = buttonStyle; + closeButton.style.cssText = buttonStyle; + + !model.get('readOnly') && buttonContainer.appendChild(refreshButton); + buttonContainer.appendChild(closeButton); + + // http://stackoverflow.com/questions/6637341/use-tab-to-indent-in-textarea + addEventListener(textarea, 'keydown', function(e) { + if ((e.keyCode || e.which) === 9) { + // get caret position/selection + var val = this.value; + var start = this.selectionStart; + var end = this.selectionEnd; + + // set textarea value to: text before caret + tab + text after caret + this.value = val.substring(0, start) + ITEM_SPLITER + val.substring(end); + + // put caret at right position again + this.selectionStart = this.selectionEnd = start + 1; + + // prevent the focus lose + stop(e); + } + }); + + root.appendChild(header); + root.appendChild(viewMain); + root.appendChild(buttonContainer); + + viewMain.style.height = (container.clientHeight - 80) + 'px'; + + container.appendChild(root); + this._dom = root; + }; + + DataView.prototype.remove = function(ecModel, api) { + this._dom && api.getDom().removeChild(this._dom); + }; + + DataView.prototype.dispose = function(ecModel, api) { + this.remove(ecModel, api); + }; + + /** + * @inner + */ + function tryMergeDataOption(newData, originalData) { + return map(newData, function(newVal, idx) { + var original = originalData && originalData[idx]; + if (isObject$1(original) && !isArray(original)) { + if (isObject$1(newVal) && !isArray(newVal)) { + newVal = newVal.value; + } + // Original data has option + return defaults({ + value: newVal + }, original); + } else { + return newVal; + } + }); + } + + register$1('dataView', DataView); + + registerAction({ + type: 'changeDataView', + event: 'dataViewChanged', + update: 'prepareAndUpdate' + }, function(payload, ecModel) { + var newSeriesOptList = []; + each$1(payload.newOption.series, function(seriesOpt) { + var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0]; + if (!seriesModel) { + // New created series + // Geuss the series type + newSeriesOptList.push(extend({ + // Default is scatter + type: 'scatter' + }, seriesOpt)); + } else { + var originalData = seriesModel.get('data'); + newSeriesOptList.push({ + name: seriesOpt.name, + data: tryMergeDataOption(seriesOpt.data, originalData) + }); + } + }); + + ecModel.mergeOption(defaults({ + series: newSeriesOptList + }, payload.newOption)); + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var each$29 = each$1; + + var ATTR$2 = '\0_ec_hist_store'; + + /** + * @param {module:echarts/model/Global} ecModel + * @param {Object} newSnapshot {dataZoomId, batch: [payloadInfo, ...]} + */ + function push(ecModel, newSnapshot) { + var store = giveStore$1(ecModel); + + // If previous dataZoom can not be found, + // complete an range with current range. + each$29(newSnapshot, function(batchItem, dataZoomId) { + var i = store.length - 1; + for (; i >= 0; i--) { + var snapshot = store[i]; + if (snapshot[dataZoomId]) { + break; + } + } + if (i < 0) { + // No origin range set, create one by current range. + var dataZoomModel = ecModel.queryComponents({ + mainType: 'dataZoom', + subType: 'select', + id: dataZoomId + })[0]; + if (dataZoomModel) { + var percentRange = dataZoomModel.getPercentRange(); + store[0][dataZoomId] = { + dataZoomId: dataZoomId, + start: percentRange[0], + end: percentRange[1] + }; + } + } + }); + + store.push(newSnapshot); + } + + /** + * @param {module:echarts/model/Global} ecModel + * @return {Object} snapshot + */ + function pop(ecModel) { + var store = giveStore$1(ecModel); + var head = store[store.length - 1]; + store.length > 1 && store.pop(); + + // Find top for all dataZoom. + var snapshot = {}; + each$29(head, function(batchItem, dataZoomId) { + for (var i = store.length - 1; i >= 0; i--) { + var batchItem = store[i][dataZoomId]; + if (batchItem) { + snapshot[dataZoomId] = batchItem; + break; + } + } + }); + + return snapshot; + } + + /** + * @param {module:echarts/model/Global} ecModel + */ + function clear$1(ecModel) { + ecModel[ATTR$2] = null; + } + + /** + * @param {module:echarts/model/Global} ecModel + * @return {number} records. always >= 1. + */ + function count(ecModel) { + return giveStore$1(ecModel).length; + } + + /** + * [{key: dataZoomId, value: {dataZoomId, range}}, ...] + * History length of each dataZoom may be different. + * this._history[0] is used to store origin range. + * @type {Array.} + */ + function giveStore$1(ecModel) { + var store = ecModel[ATTR$2]; + if (!store) { + store = ecModel[ATTR$2] = [{}]; + } + return store; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + DataZoomModel.extend({ + type: 'dataZoom.select' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + DataZoomView.extend({ + type: 'dataZoom.select' + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + /** + * DataZoom component entry + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Use dataZoomSelect + var dataZoomLang = lang.toolbox.dataZoom; + var each$28 = each$1; + + // Spectial component id start with \0ec\0, see echarts/model/Global.js~hasInnerId + var DATA_ZOOM_ID_BASE = '\0_ec_\0toolbox-dataZoom_'; + + function DataZoom(model, ecModel, api) { + + /** + * @private + * @type {module:echarts/component/helper/BrushController} + */ + (this._brushController = new BrushController(api.getZr())) + .on('brush', bind(this._onBrush, this)) + .mount(); + + /** + * @private + * @type {boolean} + */ + this._isZoomActive; + } + + DataZoom.defaultOption = { + show: true, + // Icon group + icon: { + zoom: 'M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1', + back: 'M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26' + }, + // `zoom`, `back` + title: clone(dataZoomLang.title) + }; + + var proto$6 = DataZoom.prototype; + + proto$6.render = function(featureModel, ecModel, api, payload) { + this.model = featureModel; + this.ecModel = ecModel; + this.api = api; + + updateZoomBtnStatus(featureModel, ecModel, this, payload, api); + updateBackBtnStatus(featureModel, ecModel); + }; + + proto$6.onclick = function(ecModel, api, type) { + handlers$1[type].call(this); + }; + + proto$6.remove = function(ecModel, api) { + this._brushController.unmount(); + }; + + proto$6.dispose = function(ecModel, api) { + this._brushController.dispose(); + }; + + /** + * @private + */ + var handlers$1 = { + + zoom: function() { + var nextActive = !this._isZoomActive; + + this.api.dispatchAction({ + type: 'takeGlobalCursor', + key: 'dataZoomSelect', + dataZoomSelectActive: nextActive + }); + }, + + back: function() { + this._dispatchZoomAction(pop(this.ecModel)); + } + }; + + /** + * @private + */ + proto$6._onBrush = function(areas, opt) { + if (!opt.isEnd || !areas.length) { + return; + } + var snapshot = {}; + var ecModel = this.ecModel; + + this._brushController.updateCovers([]); // remove cover + + var brushTargetManager = new BrushTargetManager( + retrieveAxisSetting(this.model.option), ecModel, { + include: ['grid'] + } + ); + brushTargetManager.matchOutputRanges(areas, ecModel, function(area, coordRange, coordSys) { + if (coordSys.type !== 'cartesian2d') { + return; + } + + var brushType = area.brushType; + if (brushType === 'rect') { + setBatch('x', coordSys, coordRange[0]); + setBatch('y', coordSys, coordRange[1]); + } else { + setBatch(({ + lineX: 'x', + lineY: 'y' + })[brushType], coordSys, coordRange); + } + }); + + push(ecModel, snapshot); + + this._dispatchZoomAction(snapshot); + + function setBatch(dimName, coordSys, minMax) { + var axis = coordSys.getAxis(dimName); + var axisModel = axis.model; + var dataZoomModel = findDataZoom(dimName, axisModel, ecModel); + + // Restrict range. + var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan(); + if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) { + minMax = sliderMove( + 0, minMax.slice(), axis.scale.getExtent(), 0, + minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan + ); + } + + dataZoomModel && (snapshot[dataZoomModel.id] = { + dataZoomId: dataZoomModel.id, + startValue: minMax[0], + endValue: minMax[1] + }); + } + + function findDataZoom(dimName, axisModel, ecModel) { + var found; + ecModel.eachComponent({ + mainType: 'dataZoom', + subType: 'select' + }, function(dzModel) { + var has = dzModel.getAxisModel(dimName, axisModel.componentIndex); + has && (found = dzModel); + }); + return found; + } + }; + + /** + * @private + */ + proto$6._dispatchZoomAction = function(snapshot) { + var batch = []; + + // Convert from hash map to array. + each$28(snapshot, function(batchItem, dataZoomId) { + batch.push(clone(batchItem)); + }); + + batch.length && this.api.dispatchAction({ + type: 'dataZoom', + from: this.uid, + batch: batch + }); + }; + + function retrieveAxisSetting(option) { + var setting = {}; + // Compatible with previous setting: null => all axis, false => no axis. + each$1(['xAxisIndex', 'yAxisIndex'], function(name) { + setting[name] = option[name]; + setting[name] == null && (setting[name] = 'all'); + (setting[name] === false || setting[name] === 'none') && (setting[name] = []); + }); + return setting; + } + + function updateBackBtnStatus(featureModel, ecModel) { + featureModel.setIconStatus( + 'back', + count(ecModel) > 1 ? 'emphasis' : 'normal' + ); + } + + function updateZoomBtnStatus(featureModel, ecModel, view, payload, api) { + var zoomActive = view._isZoomActive; + + if (payload && payload.type === 'takeGlobalCursor') { + zoomActive = payload.key === 'dataZoomSelect' ? + payload.dataZoomSelectActive : false; + } + + view._isZoomActive = zoomActive; + + featureModel.setIconStatus('zoom', zoomActive ? 'emphasis' : 'normal'); + + var brushTargetManager = new BrushTargetManager( + retrieveAxisSetting(featureModel.option), ecModel, { + include: ['grid'] + } + ); + + view._brushController + .setPanels(brushTargetManager.makePanelOpts(api, function(targetInfo) { + return (targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared) ? + 'lineX' : + (!targetInfo.xAxisDeclared && targetInfo.yAxisDeclared) ? + 'lineY' : + 'rect'; + })) + .enableBrush( + zoomActive ? + { + brushType: 'auto', + brushStyle: { + // FIXME user customized? + lineWidth: 0, + fill: 'rgba(0,0,0,0.2)' + } + } : + false + ); + } + + + register$1('dataZoom', DataZoom); + + + // Create special dataZoom option for select + // FIXME consider the case of merge option, where axes options are not exists. + registerPreprocessor(function(option) { + if (!option) { + return; + } + + var dataZoomOpts = option.dataZoom || (option.dataZoom = []); + if (!isArray(dataZoomOpts)) { + option.dataZoom = dataZoomOpts = [dataZoomOpts]; + } + + var toolboxOpt = option.toolbox; + if (toolboxOpt) { + // Assume there is only one toolbox + if (isArray(toolboxOpt)) { + toolboxOpt = toolboxOpt[0]; + } + + if (toolboxOpt && toolboxOpt.feature) { + var dataZoomOpt = toolboxOpt.feature.dataZoom; + // FIXME: If add dataZoom when setOption in merge mode, + // no axis info to be added. See `test/dataZoom-extreme.html` + addForAxis('xAxis', dataZoomOpt); + addForAxis('yAxis', dataZoomOpt); + } + } + + function addForAxis(axisName, dataZoomOpt) { + if (!dataZoomOpt) { + return; + } + + // Try not to modify model, because it is not merged yet. + var axisIndicesName = axisName + 'Index'; + var givenAxisIndices = dataZoomOpt[axisIndicesName]; + if (givenAxisIndices != null && + givenAxisIndices != 'all' && + !isArray(givenAxisIndices) + ) { + givenAxisIndices = (givenAxisIndices === false || givenAxisIndices === 'none') ? [] : [givenAxisIndices]; + } + + forEachComponent(axisName, function(axisOpt, axisIndex) { + if (givenAxisIndices != null && + givenAxisIndices != 'all' && + indexOf(givenAxisIndices, axisIndex) === -1 + ) { + return; + } + var newOpt = { + type: 'select', + $fromToolbox: true, + // Id for merge mapping. + id: DATA_ZOOM_ID_BASE + axisName + axisIndex + }; + // FIXME + // Only support one axis now. + newOpt[axisIndicesName] = axisIndex; + dataZoomOpts.push(newOpt); + }); + } + + function forEachComponent(mainType, cb) { + var opts = option[mainType]; + if (!isArray(opts)) { + opts = opts ? [opts] : []; + } + each$28(opts, cb); + } + }); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var restoreLang = lang.toolbox.restore; + + function Restore(model) { + this.model = model; + } + + Restore.defaultOption = { + show: true, + 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', + title: restoreLang.title + }; + + var proto$7 = Restore.prototype; + + proto$7.onclick = function(ecModel, api, type) { + clear$1(ecModel); + + api.dispatchAction({ + type: 'restore', + from: this.uid + }); + }; + + register$1('restore', Restore); + + registerAction({ + type: 'restore', + event: 'restore', + update: 'prepareAndUpdate' + }, + function(payload, ecModel) { + ecModel.resetOption('recreate'); + } + ); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + var urn = 'urn:schemas-microsoft-com:vml'; + var win = typeof window === 'undefined' ? null : window; + + var vmlInited = false; + + var doc = win && win.document; + + function createNode(tagName) { + return doCreateNode(tagName); + } + + // Avoid assign to an exported variable, for transforming to cjs. + var doCreateNode; + + if (doc && !env$1.canvasSupported) { + try { + !doc.namespaces.zrvml && doc.namespaces.add('zrvml', urn); + doCreateNode = function(tagName) { + return doc.createElement(''); + }; + } catch (e) { + doCreateNode = function(tagName) { + return doc.createElement('<' + tagName + ' xmlns="' + urn + '" class="zrvml">'); + }; + } + } + + // From raphael + function initVML() { + if (vmlInited || !doc) { + return; + } + vmlInited = true; + + var styleSheets = doc.styleSheets; + if (styleSheets.length < 31) { + doc.createStyleSheet().addRule('.zrvml', 'behavior:url(#default#VML)'); + } else { + // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx + styleSheets[0].addRule('.zrvml', 'behavior:url(#default#VML)'); + } + } + + // http://www.w3.org/TR/NOTE-VML + // TODO Use proxy like svg instead of overwrite brush methods + + var CMD$3 = PathProxy.CMD; + var round$3 = Math.round; + var sqrt = Math.sqrt; + var abs$1 = Math.abs; + var cos = Math.cos; + var sin = Math.sin; + var mathMax$8 = Math.max; + + if (!env$1.canvasSupported) { + + var comma = ','; + var imageTransformPrefix = 'progid:DXImageTransform.Microsoft'; + + var Z = 21600; + var Z2 = Z / 2; + + var ZLEVEL_BASE = 100000; + var Z_BASE$1 = 1000; + + var initRootElStyle = function(el) { + el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;'; + el.coordsize = Z + ',' + Z; + el.coordorigin = '0,0'; + }; + + var encodeHtmlAttribute = function(s) { + return String(s).replace(/&/g, '&').replace(/"/g, '"'); + }; + + var rgb2Str = function(r, g, b) { + return 'rgb(' + [r, g, b].join(',') + ')'; + }; + + var append = function(parent, child) { + if (child && parent && child.parentNode !== parent) { + parent.appendChild(child); + } + }; + + var remove = function(parent, child) { + if (child && parent && child.parentNode === parent) { + parent.removeChild(child); + } + }; + + var getZIndex = function(zlevel, z, z2) { + // z 的取值范围为 [0, 1000] + return (parseFloat(zlevel) || 0) * ZLEVEL_BASE + (parseFloat(z) || 0) * Z_BASE$1 + z2; + }; + + var parsePercent$3 = function(value, maxValue) { + if (typeof value === 'string') { + if (value.lastIndexOf('%') >= 0) { + return parseFloat(value) / 100 * maxValue; + } + return parseFloat(value); + } + return value; + }; + + /*************************************************** + * PATH + **************************************************/ + + var setColorAndOpacity = function(el, color, opacity) { + var colorArr = parse(color); + opacity = +opacity; + if (isNaN(opacity)) { + opacity = 1; + } + if (colorArr) { + el.color = rgb2Str(colorArr[0], colorArr[1], colorArr[2]); + el.opacity = opacity * colorArr[3]; + } + }; + + var getColorAndAlpha = function(color) { + var colorArr = parse(color); + return [ + rgb2Str(colorArr[0], colorArr[1], colorArr[2]), + colorArr[3] + ]; + }; + + var updateFillNode = function(el, style, zrEl) { + // TODO pattern + var fill = style.fill; + if (fill != null) { + // Modified from excanvas + if (fill instanceof Gradient) { + var gradientType; + var angle = 0; + var focus = [0, 0]; + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + var rect = zrEl.getBoundingRect(); + var rectWidth = rect.width; + var rectHeight = rect.height; + if (fill.type === 'linear') { + gradientType = 'gradient'; + var transform = zrEl.transform; + var p0 = [fill.x * rectWidth, fill.y * rectHeight]; + var p1 = [fill.x2 * rectWidth, fill.y2 * rectHeight]; + if (transform) { + applyTransform(p0, p0, transform); + applyTransform(p1, p1, transform); + } + var dx = p1[0] - p0[0]; + var dy = p1[1] - p0[1]; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + gradientType = 'gradientradial'; + var p0 = [fill.x * rectWidth, fill.y * rectHeight]; + var transform = zrEl.transform; + var scale$$1 = zrEl.scale; + var width = rectWidth; + var height = rectHeight; + focus = [ + // Percent in bounding rect + (p0[0] - rect.x) / width, + (p0[1] - rect.y) / height + ]; + if (transform) { + applyTransform(p0, p0, transform); + } + + width /= scale$$1[0] * Z; + height /= scale$$1[1] * Z; + var dimension = mathMax$8(width, height); + shift = 2 * 0 / dimension; + expansion = 2 * fill.r / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fill.colorStops.slice(); + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length$$1 = stops.length; + // Color and alpha list of first and last stop + var colorAndAlphaList = []; + var colors = []; + for (var i = 0; i < length$$1; i++) { + var stop = stops[i]; + var colorAndAlpha = getColorAndAlpha(stop.color); + colors.push(stop.offset * expansion + shift + ' ' + colorAndAlpha[0]); + if (i === 0 || i === length$$1 - 1) { + colorAndAlphaList.push(colorAndAlpha); + } + } + + if (length$$1 >= 2) { + var color1 = colorAndAlphaList[0][0]; + var color2 = colorAndAlphaList[1][0]; + var opacity1 = colorAndAlphaList[0][1] * style.opacity; + var opacity2 = colorAndAlphaList[1][1] * style.opacity; + + el.type = gradientType; + el.method = 'none'; + el.focus = '100%'; + el.angle = angle; + el.color = color1; + el.color2 = color2; + el.colors = colors.join(','); + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + el.opacity = opacity2; + // FIXME g_o_:opacity ? + el.opacity2 = opacity1; + } + if (gradientType === 'radial') { + el.focusposition = focus.join(','); + } + } else { + // FIXME Change from Gradient fill to color fill + setColorAndOpacity(el, fill, style.opacity); + } + } + }; + + var updateStrokeNode = function(el, style) { + // if (style.lineJoin != null) { + // el.joinstyle = style.lineJoin; + // } + // if (style.miterLimit != null) { + // el.miterlimit = style.miterLimit * Z; + // } + // if (style.lineCap != null) { + // el.endcap = style.lineCap; + // } + if (style.lineDash != null) { + el.dashstyle = style.lineDash.join(' '); + } + if (style.stroke != null && !(style.stroke instanceof Gradient)) { + setColorAndOpacity(el, style.stroke, style.opacity); + } + }; + + var updateFillAndStroke = function(vmlEl, type, style, zrEl) { + var isFill = type == 'fill'; + var el = vmlEl.getElementsByTagName(type)[0]; + // Stroke must have lineWidth + if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) { + vmlEl[isFill ? 'filled' : 'stroked'] = 'true'; + // FIXME Remove before updating, or set `colors` will throw error + if (style[type] instanceof Gradient) { + remove(vmlEl, el); + } + if (!el) { + el = createNode(type); + } + + isFill ? updateFillNode(el, style, zrEl) : updateStrokeNode(el, style); + append(vmlEl, el); + } else { + vmlEl[isFill ? 'filled' : 'stroked'] = 'false'; + remove(vmlEl, el); + } + }; + + var points$3 = [ + [], + [], + [] + ]; + var pathDataToString = function(path, m) { + var M = CMD$3.M; + var C = CMD$3.C; + var L = CMD$3.L; + var A = CMD$3.A; + var Q = CMD$3.Q; + + var str = []; + var nPoint; + var cmdStr; + var cmd; + var i; + var xi; + var yi; + var data = path.data; + var dataLength = path.len(); + for (i = 0; i < dataLength;) { + cmd = data[i++]; + cmdStr = ''; + nPoint = 0; + switch (cmd) { + case M: + cmdStr = ' m '; + nPoint = 1; + xi = data[i++]; + yi = data[i++]; + points$3[0][0] = xi; + points$3[0][1] = yi; + break; + case L: + cmdStr = ' l '; + nPoint = 1; + xi = data[i++]; + yi = data[i++]; + points$3[0][0] = xi; + points$3[0][1] = yi; + break; + case Q: + case C: + cmdStr = ' c '; + nPoint = 3; + var x1 = data[i++]; + var y1 = data[i++]; + var x2 = data[i++]; + var y2 = data[i++]; + var x3; + var y3; + if (cmd === Q) { + // Convert quadratic to cubic using degree elevation + x3 = x2; + y3 = y2; + x2 = (x2 + 2 * x1) / 3; + y2 = (y2 + 2 * y1) / 3; + x1 = (xi + 2 * x1) / 3; + y1 = (yi + 2 * y1) / 3; + } else { + x3 = data[i++]; + y3 = data[i++]; + } + points$3[0][0] = x1; + points$3[0][1] = y1; + points$3[1][0] = x2; + points$3[1][1] = y2; + points$3[2][0] = x3; + points$3[2][1] = y3; + + xi = x3; + yi = y3; + break; + case A: + var x = 0; + var y = 0; + var sx = 1; + var sy = 1; + var angle = 0; + if (m) { + // Extract SRT from matrix + x = m[4]; + y = m[5]; + sx = sqrt(m[0] * m[0] + m[1] * m[1]); + sy = sqrt(m[2] * m[2] + m[3] * m[3]); + angle = Math.atan2(-m[1] / sy, m[0] / sx); + } + + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var startAngle = data[i++] + angle; + var endAngle = data[i++] + startAngle + angle; + // FIXME + // var psi = data[i++]; + i++; + var clockwise = data[i++]; + + var x0 = cx + cos(startAngle) * rx; + var y0 = cy + sin(startAngle) * ry; + + var x1 = cx + cos(endAngle) * rx; + var y1 = cy + sin(endAngle) * ry; + + var type = clockwise ? ' wa ' : ' at '; + if (Math.abs(x0 - x1) < 1e-4) { + // IE won't render arches drawn counter clockwise if x0 == x1. + if (Math.abs(endAngle - startAngle) > 1e-2) { + // Offset x0 by 1/80 of a pixel. Use something + // that can be represented in binary + if (clockwise) { + x0 += 270 / Z; + } + } else { + // Avoid case draw full circle + if (Math.abs(y0 - cy) < 1e-4) { + if ((clockwise && x0 < cx) || (!clockwise && x0 > cx)) { + y1 -= 270 / Z; + } else { + y1 += 270 / Z; + } + } else if ((clockwise && y0 < cy) || (!clockwise && y0 > cy)) { + x1 += 270 / Z; + } else { + x1 -= 270 / Z; + } + } + } + str.push( + type, + round$3(((cx - rx) * sx + x) * Z - Z2), comma, + round$3(((cy - ry) * sy + y) * Z - Z2), comma, + round$3(((cx + rx) * sx + x) * Z - Z2), comma, + round$3(((cy + ry) * sy + y) * Z - Z2), comma, + round$3((x0 * sx + x) * Z - Z2), comma, + round$3((y0 * sy + y) * Z - Z2), comma, + round$3((x1 * sx + x) * Z - Z2), comma, + round$3((y1 * sy + y) * Z - Z2) + ); + + xi = x1; + yi = y1; + break; + case CMD$3.R: + var p0 = points$3[0]; + var p1 = points$3[1]; + // x0, y0 + p0[0] = data[i++]; + p0[1] = data[i++]; + // x1, y1 + p1[0] = p0[0] + data[i++]; + p1[1] = p0[1] + data[i++]; + + if (m) { + applyTransform(p0, p0, m); + applyTransform(p1, p1, m); + } + + p0[0] = round$3(p0[0] * Z - Z2); + p1[0] = round$3(p1[0] * Z - Z2); + p0[1] = round$3(p0[1] * Z - Z2); + p1[1] = round$3(p1[1] * Z - Z2); + str.push( + // x0, y0 + ' m ', p0[0], comma, p0[1], + // x1, y0 + ' l ', p1[0], comma, p0[1], + // x1, y1 + ' l ', p1[0], comma, p1[1], + // x0, y1 + ' l ', p0[0], comma, p1[1] + ); + break; + case CMD$3.Z: + // FIXME Update xi, yi + str.push(' x '); + } + + if (nPoint > 0) { + str.push(cmdStr); + for (var k = 0; k < nPoint; k++) { + var p = points$3[k]; + + m && applyTransform(p, p, m); + // 不 round 会非常慢 + str.push( + round$3(p[0] * Z - Z2), comma, round$3(p[1] * Z - Z2), + k < nPoint - 1 ? comma : '' + ); + } + } + } + + return str.join(''); + }; + + // Rewrite the original path method + Path.prototype.brushVML = function(vmlRoot) { + var style = this.style; + + var vmlEl = this._vmlEl; + if (!vmlEl) { + vmlEl = createNode('shape'); + initRootElStyle(vmlEl); + + this._vmlEl = vmlEl; + } + + updateFillAndStroke(vmlEl, 'fill', style, this); + updateFillAndStroke(vmlEl, 'stroke', style, this); + + var m = this.transform; + var needTransform = m != null; + var strokeEl = vmlEl.getElementsByTagName('stroke')[0]; + if (strokeEl) { + var lineWidth = style.lineWidth; + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + if (needTransform && !style.strokeNoScale) { + var det = m[0] * m[3] - m[1] * m[2]; + lineWidth *= sqrt(abs$1(det)); + } + strokeEl.weight = lineWidth + 'px'; + } + + var path = this.path || (this.path = new PathProxy()); + if (this.__dirtyPath) { + path.beginPath(); + this.buildPath(path, this.shape); + path.toStatic(); + this.__dirtyPath = false; + } + + vmlEl.path = pathDataToString(path, this.transform); + + vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2); + + // Append to root + append(vmlRoot, vmlEl); + + // Text + if (style.text != null) { + this.drawRectText(vmlRoot, this.getBoundingRect()); + } else { + this.removeRectText(vmlRoot); + } + }; + + Path.prototype.onRemove = function(vmlRoot) { + remove(vmlRoot, this._vmlEl); + this.removeRectText(vmlRoot); + }; + + Path.prototype.onAdd = function(vmlRoot) { + append(vmlRoot, this._vmlEl); + this.appendRectText(vmlRoot); + }; + + /*************************************************** + * IMAGE + **************************************************/ + var isImage = function(img) { + // FIXME img instanceof Image 如果 img 是一个字符串的时候,IE8 下会报错 + return (typeof img === 'object') && img.tagName && img.tagName.toUpperCase() === 'IMG'; + // return img instanceof Image; + }; + + // Rewrite the original path method + ZImage.prototype.brushVML = function(vmlRoot) { + var style = this.style; + var image = style.image; + + // Image original width, height + var ow; + var oh; + + if (isImage(image)) { + var src = image.src; + if (src === this._imageSrc) { + ow = this._imageWidth; + oh = this._imageHeight; + } else { + var imageRuntimeStyle = image.runtimeStyle; + var oldRuntimeWidth = imageRuntimeStyle.width; + var oldRuntimeHeight = imageRuntimeStyle.height; + imageRuntimeStyle.width = 'auto'; + imageRuntimeStyle.height = 'auto'; + + // get the original size + ow = image.width; + oh = image.height; + + // and remove overides + imageRuntimeStyle.width = oldRuntimeWidth; + imageRuntimeStyle.height = oldRuntimeHeight; + + // Caching image original width, height and src + this._imageSrc = src; + this._imageWidth = ow; + this._imageHeight = oh; + } + image = src; + } else { + if (image === this._imageSrc) { + ow = this._imageWidth; + oh = this._imageHeight; + } + } + if (!image) { + return; + } + + var x = style.x || 0; + var y = style.y || 0; + + var dw = style.width; + var dh = style.height; + + var sw = style.sWidth; + var sh = style.sHeight; + var sx = style.sx || 0; + var sy = style.sy || 0; + + var hasCrop = sw && sh; + + var vmlEl = this._vmlEl; + if (!vmlEl) { + // FIXME 使用 group 在 left, top 都不是 0 的时候就无法显示了。 + // vmlEl = vmlCore.createNode('group'); + vmlEl = doc.createElement('div'); + initRootElStyle(vmlEl); + + this._vmlEl = vmlEl; + } + + var vmlElStyle = vmlEl.style; + var hasRotation = false; + var m; + var scaleX = 1; + var scaleY = 1; + if (this.transform) { + m = this.transform; + scaleX = sqrt(m[0] * m[0] + m[1] * m[1]); + scaleY = sqrt(m[2] * m[2] + m[3] * m[3]); + + hasRotation = m[1] || m[2]; + } + if (hasRotation) { + // If filters are necessary (rotation exists), create them + // filters are bog-slow, so only create them if abbsolutely necessary + // The following check doesn't account for skews (which don't exist + // in the canvas spec (yet) anyway. + // From excanvas + var p0 = [x, y]; + var p1 = [x + dw, y]; + var p2 = [x, y + dh]; + var p3 = [x + dw, y + dh]; + applyTransform(p0, p0, m); + applyTransform(p1, p1, m); + applyTransform(p2, p2, m); + applyTransform(p3, p3, m); + + var maxX = mathMax$8(p0[0], p1[0], p2[0], p3[0]); + var maxY = mathMax$8(p0[1], p1[1], p2[1], p3[1]); + + var transformFilter = []; + transformFilter.push('M11=', m[0] / scaleX, comma, + 'M12=', m[2] / scaleY, comma, + 'M21=', m[1] / scaleX, comma, + 'M22=', m[3] / scaleY, comma, + 'Dx=', round$3(x * scaleX + m[4]), comma, + 'Dy=', round$3(y * scaleY + m[5])); + + vmlElStyle.padding = '0 ' + round$3(maxX) + 'px ' + round$3(maxY) + 'px 0'; + // FIXME DXImageTransform 在 IE11 的兼容模式下不起作用 + vmlElStyle.filter = imageTransformPrefix + '.Matrix(' + + transformFilter.join('') + ', SizingMethod=clip)'; + + } else { + if (m) { + x = x * scaleX + m[4]; + y = y * scaleY + m[5]; + } + vmlElStyle.filter = ''; + vmlElStyle.left = round$3(x) + 'px'; + vmlElStyle.top = round$3(y) + 'px'; + } + + var imageEl = this._imageEl; + var cropEl = this._cropEl; + + if (!imageEl) { + imageEl = doc.createElement('div'); + this._imageEl = imageEl; + } + var imageELStyle = imageEl.style; + if (hasCrop) { + // Needs know image original width and height + if (!(ow && oh)) { + var tmpImage = new Image(); + var self = this; + tmpImage.onload = function() { + tmpImage.onload = null; + ow = tmpImage.width; + oh = tmpImage.height; + // Adjust image width and height to fit the ratio destinationSize / sourceSize + imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px'; + imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px'; + + // Caching image original width, height and src + self._imageWidth = ow; + self._imageHeight = oh; + self._imageSrc = image; + }; + tmpImage.src = image; + } else { + imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px'; + imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px'; + } + + if (!cropEl) { + cropEl = doc.createElement('div'); + cropEl.style.overflow = 'hidden'; + this._cropEl = cropEl; + } + var cropElStyle = cropEl.style; + cropElStyle.width = round$3((dw + sx * dw / sw) * scaleX); + cropElStyle.height = round$3((dh + sy * dh / sh) * scaleY); + cropElStyle.filter = imageTransformPrefix + '.Matrix(Dx=' + + (-sx * dw / sw * scaleX) + ',Dy=' + (-sy * dh / sh * scaleY) + ')'; + + if (!cropEl.parentNode) { + vmlEl.appendChild(cropEl); + } + if (imageEl.parentNode != cropEl) { + cropEl.appendChild(imageEl); + } + } else { + imageELStyle.width = round$3(scaleX * dw) + 'px'; + imageELStyle.height = round$3(scaleY * dh) + 'px'; + + vmlEl.appendChild(imageEl); + + if (cropEl && cropEl.parentNode) { + vmlEl.removeChild(cropEl); + this._cropEl = null; + } + } + + var filterStr = ''; + var alpha = style.opacity; + if (alpha < 1) { + filterStr += '.Alpha(opacity=' + round$3(alpha * 100) + ') '; + } + filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)'; + + imageELStyle.filter = filterStr; + + vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2); + + // Append to root + append(vmlRoot, vmlEl); + + // Text + if (style.text != null) { + this.drawRectText(vmlRoot, this.getBoundingRect()); + } + }; + + ZImage.prototype.onRemove = function(vmlRoot) { + remove(vmlRoot, this._vmlEl); + + this._vmlEl = null; + this._cropEl = null; + this._imageEl = null; + + this.removeRectText(vmlRoot); + }; + + ZImage.prototype.onAdd = function(vmlRoot) { + append(vmlRoot, this._vmlEl); + this.appendRectText(vmlRoot); + }; + + + /*************************************************** + * TEXT + **************************************************/ + + var DEFAULT_STYLE_NORMAL = 'normal'; + + var fontStyleCache = {}; + var fontStyleCacheCount = 0; + var MAX_FONT_CACHE_SIZE = 100; + var fontEl = document.createElement('div'); + + var getFontStyle = function(fontString) { + var fontStyle = fontStyleCache[fontString]; + if (!fontStyle) { + // Clear cache + if (fontStyleCacheCount > MAX_FONT_CACHE_SIZE) { + fontStyleCacheCount = 0; + fontStyleCache = {}; + } + + var style = fontEl.style; + var fontFamily; + try { + style.font = fontString; + fontFamily = style.fontFamily.split(',')[0]; + } catch (e) {} + + fontStyle = { + style: style.fontStyle || DEFAULT_STYLE_NORMAL, + variant: style.fontVariant || DEFAULT_STYLE_NORMAL, + weight: style.fontWeight || DEFAULT_STYLE_NORMAL, + size: parseFloat(style.fontSize || 12) | 0, + family: fontFamily || 'Microsoft YaHei' + }; + + fontStyleCache[fontString] = fontStyle; + fontStyleCacheCount++; + } + return fontStyle; + }; + + var textMeasureEl; + // Overwrite measure text method + $override$1('measureText', function(text, textFont) { + var doc$$1 = doc; + if (!textMeasureEl) { + textMeasureEl = doc$$1.createElement('div'); + textMeasureEl.style.cssText = 'position:absolute;top:-20000px;left:0;' + + 'padding:0;margin:0;border:none;white-space:pre;'; + doc.body.appendChild(textMeasureEl); + } + + try { + textMeasureEl.style.font = textFont; + } catch (ex) { + // Ignore failures to set to invalid font. + } + textMeasureEl.innerHTML = ''; + // Don't use innerHTML or innerText because they allow markup/whitespace. + textMeasureEl.appendChild(doc$$1.createTextNode(text)); + return { + width: textMeasureEl.offsetWidth + }; + }); + + var tmpRect$2 = new BoundingRect(); + + var drawRectText = function(vmlRoot, rect, textRect, fromTextEl) { + + var style = this.style; + + // Optimize, avoid normalize every time. + this.__dirty && normalizeTextStyle(style, true); + + var text = style.text; + // Convert to string + text != null && (text += ''); + if (!text) { + return; + } + + // Convert rich text to plain text. Rich text is not supported in + // IE8-, but tags in rich text template will be removed. + if (style.rich) { + var contentBlock = parseRichText(text, style); + text = []; + for (var i = 0; i < contentBlock.lines.length; i++) { + var tokens = contentBlock.lines[i].tokens; + var textLine = []; + for (var j = 0; j < tokens.length; j++) { + textLine.push(tokens[j].text); + } + text.push(textLine.join('')); + } + text = text.join('\n'); + } + + var x; + var y; + var align = style.textAlign; + var verticalAlign = style.textVerticalAlign; + + var fontStyle = getFontStyle(style.font); + // FIXME encodeHtmlAttribute ? + var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' ' + + fontStyle.size + 'px "' + fontStyle.family + '"'; + + textRect = textRect || getBoundingRect(text, font, align, verticalAlign); + + // Transform rect to view space + var m = this.transform; + // Ignore transform for text in other element + if (m && !fromTextEl) { + tmpRect$2.copy(rect); + tmpRect$2.applyTransform(m); + rect = tmpRect$2; + } + + if (!fromTextEl) { + var textPosition = style.textPosition; + var distance$$1 = style.textDistance; + // Text position represented by coord + if (textPosition instanceof Array) { + x = rect.x + parsePercent$3(textPosition[0], rect.width); + y = rect.y + parsePercent$3(textPosition[1], rect.height); + + align = align || 'left'; + } else { + var res = adjustTextPositionOnRect( + textPosition, rect, distance$$1 + ); + x = res.x; + y = res.y; + + // Default align and baseline when has textPosition + align = align || res.textAlign; + verticalAlign = verticalAlign || res.textVerticalAlign; + } + } else { + x = rect.x; + y = rect.y; + } + + x = adjustTextX(x, textRect.width, align); + y = adjustTextY(y, textRect.height, verticalAlign); + + // Force baseline 'middle' + y += textRect.height / 2; + + // var fontSize = fontStyle.size; + // 1.75 is an arbitrary number, as there is no info about the text baseline + // switch (baseline) { + // case 'hanging': + // case 'top': + // y += fontSize / 1.75; + // break; + // case 'middle': + // break; + // default: + // // case null: + // // case 'alphabetic': + // // case 'ideographic': + // // case 'bottom': + // y -= fontSize / 2.25; + // break; + // } + + // switch (align) { + // case 'left': + // break; + // case 'center': + // x -= textRect.width / 2; + // break; + // case 'right': + // x -= textRect.width; + // break; + // case 'end': + // align = elementStyle.direction == 'ltr' ? 'right' : 'left'; + // break; + // case 'start': + // align = elementStyle.direction == 'rtl' ? 'right' : 'left'; + // break; + // default: + // align = 'left'; + // } + + var createNode$$1 = createNode; + + var textVmlEl = this._textVmlEl; + var pathEl; + var textPathEl; + var skewEl; + if (!textVmlEl) { + textVmlEl = createNode$$1('line'); + pathEl = createNode$$1('path'); + textPathEl = createNode$$1('textpath'); + skewEl = createNode$$1('skew'); + + // FIXME Why here is not cammel case + // Align 'center' seems wrong + textPathEl.style['v-text-align'] = 'left'; + + initRootElStyle(textVmlEl); + + pathEl.textpathok = true; + textPathEl.on = true; + + textVmlEl.from = '0 0'; + textVmlEl.to = '1000 0.05'; + + append(textVmlEl, skewEl); + append(textVmlEl, pathEl); + append(textVmlEl, textPathEl); + + this._textVmlEl = textVmlEl; + } else { + // 这里是在前面 appendChild 保证顺序的前提下 + skewEl = textVmlEl.firstChild; + pathEl = skewEl.nextSibling; + textPathEl = pathEl.nextSibling; + } + + var coords = [x, y]; + var textVmlElStyle = textVmlEl.style; + // Ignore transform for text in other element + if (m && fromTextEl) { + applyTransform(coords, coords, m); + + skewEl.on = true; + + skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma + + m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0'; + + // Text position + skewEl.offset = (round$3(coords[0]) || 0) + ',' + (round$3(coords[1]) || 0); + // Left top point as origin + skewEl.origin = '0 0'; + + textVmlElStyle.left = '0px'; + textVmlElStyle.top = '0px'; + } else { + skewEl.on = false; + textVmlElStyle.left = round$3(x) + 'px'; + textVmlElStyle.top = round$3(y) + 'px'; + } + + textPathEl.string = encodeHtmlAttribute(text); + // TODO + try { + textPathEl.style.font = font; + } + // Error font format + catch (e) {} + + updateFillAndStroke(textVmlEl, 'fill', { + fill: style.textFill, + opacity: style.opacity + }, this); + updateFillAndStroke(textVmlEl, 'stroke', { + stroke: style.textStroke, + opacity: style.opacity, + lineDash: style.lineDash + }, this); + + textVmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2); + + // Attached to root + append(vmlRoot, textVmlEl); + }; + + var removeRectText = function(vmlRoot) { + remove(vmlRoot, this._textVmlEl); + this._textVmlEl = null; + }; + + var appendRectText = function(vmlRoot) { + append(vmlRoot, this._textVmlEl); + }; + + var list = [RectText, Displayable, ZImage, Path, Text]; + + // In case Displayable has been mixed in RectText + for (var i$3 = 0; i$3 < list.length; i$3++) { + var proto$8 = list[i$3].prototype; + proto$8.drawRectText = drawRectText; + proto$8.removeRectText = removeRectText; + proto$8.appendRectText = appendRectText; + } + + Text.prototype.brushVML = function(vmlRoot) { + var style = this.style; + if (style.text != null) { + this.drawRectText(vmlRoot, { + x: style.x || 0, + y: style.y || 0, + width: 0, + height: 0 + }, this.getBoundingRect(), true); + } else { + this.removeRectText(vmlRoot); + } + }; + + Text.prototype.onRemove = function(vmlRoot) { + this.removeRectText(vmlRoot); + }; + + Text.prototype.onAdd = function(vmlRoot) { + this.appendRectText(vmlRoot); + }; + } + + /** + * VML Painter. + * + * @module zrender/vml/Painter + */ + + function parseInt10$1(val) { + return parseInt(val, 10); + } + + /** + * @alias module:zrender/vml/Painter + */ + function VMLPainter(root, storage) { + + initVML(); + + this.root = root; + + this.storage = storage; + + var vmlViewport = document.createElement('div'); + + var vmlRoot = document.createElement('div'); + + vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;'; + + vmlRoot.style.cssText = 'position:absolute;left:0;top:0;'; + + root.appendChild(vmlViewport); + + this._vmlRoot = vmlRoot; + this._vmlViewport = vmlViewport; + + this.resize(); + + // Modify storage + var oldDelFromStorage = storage.delFromStorage; + var oldAddToStorage = storage.addToStorage; + storage.delFromStorage = function(el) { + oldDelFromStorage.call(storage, el); + + if (el) { + el.onRemove && el.onRemove(vmlRoot); + } + }; + + storage.addToStorage = function(el) { + // Displayable already has a vml node + el.onAdd && el.onAdd(vmlRoot); + + oldAddToStorage.call(storage, el); + }; + + this._firstPaint = true; + } + + VMLPainter.prototype = { + + constructor: VMLPainter, + + getType: function() { + return 'vml'; + }, + + /** + * @return {HTMLDivElement} + */ + getViewportRoot: function() { + return this._vmlViewport; + }, + + getViewportRootOffset: function() { + var viewportRoot = this.getViewportRoot(); + if (viewportRoot) { + return { + offsetLeft: viewportRoot.offsetLeft || 0, + offsetTop: viewportRoot.offsetTop || 0 + }; + } + }, + + /** + * 刷新 + */ + refresh: function() { + + var list = this.storage.getDisplayList(true, true); + + this._paintList(list); + }, + + _paintList: function(list) { + var vmlRoot = this._vmlRoot; + for (var i = 0; i < list.length; i++) { + var el = list[i]; + if (el.invisible || el.ignore) { + if (!el.__alreadyNotVisible) { + el.onRemove(vmlRoot); + } + // Set as already invisible + el.__alreadyNotVisible = true; + } else { + if (el.__alreadyNotVisible) { + el.onAdd(vmlRoot); + } + el.__alreadyNotVisible = false; + if (el.__dirty) { + el.beforeBrush && el.beforeBrush(); + (el.brushVML || el.brush).call(el, vmlRoot); + el.afterBrush && el.afterBrush(); + } + } + el.__dirty = false; + } + + if (this._firstPaint) { + // Detached from document at first time + // to avoid page refreshing too many times + + // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变 + this._vmlViewport.appendChild(vmlRoot); + this._firstPaint = false; + } + }, + + resize: function(width, height) { + var width = width == null ? this._getWidth() : width; + var height = height == null ? this._getHeight() : height; + + if (this._width != width || this._height != height) { + this._width = width; + this._height = height; + + var vmlViewportStyle = this._vmlViewport.style; + vmlViewportStyle.width = width + 'px'; + vmlViewportStyle.height = height + 'px'; + } + }, + + dispose: function() { + this.root.innerHTML = ''; + + this._vmlRoot = + this._vmlViewport = + this.storage = null; + }, + + getWidth: function() { + return this._width; + }, + + getHeight: function() { + return this._height; + }, + + clear: function() { + if (this._vmlViewport) { + this.root.removeChild(this._vmlViewport); + } + }, + + _getWidth: function() { + var root = this.root; + var stl = root.currentStyle; + + return ((root.clientWidth || parseInt10$1(stl.width)) - + parseInt10$1(stl.paddingLeft) - + parseInt10$1(stl.paddingRight)) | 0; + }, + + _getHeight: function() { + var root = this.root; + var stl = root.currentStyle; + + return ((root.clientHeight || parseInt10$1(stl.height)) - + parseInt10$1(stl.paddingTop) - + parseInt10$1(stl.paddingBottom)) | 0; + } + }; + + // Not supported methods + function createMethodNotSupport(method) { + return function() { + zrLog('In IE8.0 VML mode painter not support method "' + method + '"'); + }; + } + + // Unsupported methods + each$1([ + 'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', 'eachOtherLayer', 'getLayers', + 'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage' + ], function(name) { + VMLPainter.prototype[name] = createMethodNotSupport(name); + }); + + registerPainter('vml', VMLPainter); + + var svgURI = 'http://www.w3.org/2000/svg'; + + function createElement(name) { + return document.createElementNS(svgURI, name); + } + + // TODO + // 1. shadow + // 2. Image: sx, sy, sw, sh + + var CMD$4 = PathProxy.CMD; + var arrayJoin = Array.prototype.join; + + var NONE = 'none'; + var mathRound = Math.round; + var mathSin$3 = Math.sin; + var mathCos$3 = Math.cos; + var PI$5 = Math.PI; + var PI2$7 = Math.PI * 2; + var degree = 180 / PI$5; + + var EPSILON$4 = 1e-4; + + function round4(val) { + return mathRound(val * 1e4) / 1e4; + } + + function isAroundZero$1(val) { + return val < EPSILON$4 && val > -EPSILON$4; + } + + function pathHasFill(style, isText) { + var fill = isText ? style.textFill : style.fill; + return fill != null && fill !== NONE; + } + + function pathHasStroke(style, isText) { + var stroke = isText ? style.textStroke : style.stroke; + return stroke != null && stroke !== NONE; + } + + function setTransform(svgEl, m) { + if (m) { + attr(svgEl, 'transform', 'matrix(' + arrayJoin.call(m, ',') + ')'); + } + } + + function attr(el, key, val) { + if (!val || val.type !== 'linear' && val.type !== 'radial') { + // Don't set attribute for gradient, since it need new dom nodes + if (typeof val === 'string' && val.indexOf('NaN') > -1) { + console.log(val); + } + el.setAttribute(key, val); + } + } + + function attrXLink(el, key, val) { + el.setAttributeNS('http://www.w3.org/1999/xlink', key, val); + } + + function bindStyle(svgEl, style, isText) { + if (pathHasFill(style, isText)) { + var fill = isText ? style.textFill : style.fill; + fill = fill === 'transparent' ? NONE : fill; + + /** + * FIXME: + * This is a temporary fix for Chrome's clipping bug + * that happens when a clip-path is referring another one. + * This fix should be used before Chrome's bug is fixed. + * For an element that has clip-path, and fill is none, + * set it to be "rgba(0, 0, 0, 0.002)" will hide the element. + * Otherwise, it will show black fill color. + * 0.002 is used because this won't work for alpha values smaller + * than 0.002. + * + * See + * https://bugs.chromium.org/p/chromium/issues/detail?id=659790 + * for more information. + */ + if (svgEl.getAttribute('clip-path') !== 'none' && fill === NONE) { + fill = 'rgba(0, 0, 0, 0.002)'; + } + + attr(svgEl, 'fill', fill); + attr(svgEl, 'fill-opacity', style.opacity); + } else { + attr(svgEl, 'fill', NONE); + } + + if (pathHasStroke(style, isText)) { + var stroke = isText ? style.textStroke : style.stroke; + stroke = stroke === 'transparent' ? NONE : stroke; + attr(svgEl, 'stroke', stroke); + var strokeWidth = isText ? + style.textStrokeWidth : + style.lineWidth; + var strokeScale = !isText && style.strokeNoScale ? + style.host.getLineScale() : + 1; + attr(svgEl, 'stroke-width', strokeWidth / strokeScale); + // stroke then fill for text; fill then stroke for others + attr(svgEl, 'paint-order', isText ? 'stroke' : 'fill'); + attr(svgEl, 'stroke-opacity', style.opacity); + var lineDash = style.lineDash; + if (lineDash) { + attr(svgEl, 'stroke-dasharray', style.lineDash.join(',')); + attr(svgEl, 'stroke-dashoffset', mathRound(style.lineDashOffset || 0)); + } else { + attr(svgEl, 'stroke-dasharray', ''); + } + + // PENDING + style.lineCap && attr(svgEl, 'stroke-linecap', style.lineCap); + style.lineJoin && attr(svgEl, 'stroke-linejoin', style.lineJoin); + style.miterLimit && attr(svgEl, 'stroke-miterlimit', style.miterLimit); + } else { + attr(svgEl, 'stroke', NONE); + } + } + + /*************************************************** + * PATH + **************************************************/ + function pathDataToString$1(path) { + var str = []; + var data = path.data; + var dataLength = path.len(); + for (var i = 0; i < dataLength;) { + var cmd = data[i++]; + var cmdStr = ''; + var nData = 0; + switch (cmd) { + case CMD$4.M: + cmdStr = 'M'; + nData = 2; + break; + case CMD$4.L: + cmdStr = 'L'; + nData = 2; + break; + case CMD$4.Q: + cmdStr = 'Q'; + nData = 4; + break; + case CMD$4.C: + cmdStr = 'C'; + nData = 6; + break; + case CMD$4.A: + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var theta = data[i++]; + var dTheta = data[i++]; + var psi = data[i++]; + var clockwise = data[i++]; + + var dThetaPositive = Math.abs(dTheta); + var isCircle = isAroundZero$1(dThetaPositive - PI2$7) && + !isAroundZero$1(dThetaPositive); + + var large = false; + if (dThetaPositive >= PI2$7) { + large = true; + } else if (isAroundZero$1(dThetaPositive)) { + large = false; + } else { + large = (dTheta > -PI$5 && dTheta < 0 || dTheta > PI$5) === + !!clockwise; + } + + var x0 = round4(cx + rx * mathCos$3(theta)); + var y0 = round4(cy + ry * mathSin$3(theta)); + + // It will not draw if start point and end point are exactly the same + // We need to shift the end point with a small value + // FIXME A better way to draw circle ? + if (isCircle) { + if (clockwise) { + dTheta = PI2$7 - 1e-4; + } else { + dTheta = -PI2$7 + 1e-4; + } + + large = true; + + if (i === 9) { + // Move to (x0, y0) only when CMD.A comes at the + // first position of a shape. + // For instance, when drawing a ring, CMD.A comes + // after CMD.M, so it's unnecessary to move to + // (x0, y0). + str.push('M', x0, y0); + } + } + + var x = round4(cx + rx * mathCos$3(theta + dTheta)); + var y = round4(cy + ry * mathSin$3(theta + dTheta)); + + // FIXME Ellipse + str.push('A', round4(rx), round4(ry), + mathRound(psi * degree), +large, +clockwise, x, y); + break; + case CMD$4.Z: + cmdStr = 'Z'; + break; + case CMD$4.R: + var x = round4(data[i++]); + var y = round4(data[i++]); + var w = round4(data[i++]); + var h = round4(data[i++]); + str.push( + 'M', x, y, + 'L', x + w, y, + 'L', x + w, y + h, + 'L', x, y + h, + 'L', x, y + ); + break; + } + cmdStr && str.push(cmdStr); + for (var j = 0; j < nData; j++) { + // PENDING With scale + str.push(round4(data[i++])); + } + } + return str.join(' '); + } + + var svgPath = {}; + svgPath.brush = function(el) { + var style = el.style; + + var svgEl = el.__svgEl; + if (!svgEl) { + svgEl = createElement('path'); + el.__svgEl = svgEl; + } + + if (!el.path) { + el.createPathProxy(); + } + var path = el.path; + + if (el.__dirtyPath) { + path.beginPath(); + el.buildPath(path, el.shape); + el.__dirtyPath = false; + + var pathStr = pathDataToString$1(path); + if (pathStr.indexOf('NaN') < 0) { + // Ignore illegal path, which may happen such in out-of-range + // data in Calendar series. + attr(svgEl, 'd', pathStr); + } + } + + bindStyle(svgEl, style); + setTransform(svgEl, el.transform); + + if (style.text != null) { + svgTextDrawRectText(el, el.getBoundingRect()); + } + }; + + /*************************************************** + * IMAGE + **************************************************/ + var svgImage = {}; + svgImage.brush = function(el) { + var style = el.style; + var image = style.image; + + if (image instanceof HTMLImageElement) { + var src = image.src; + image = src; + } + if (!image) { + return; + } + + var x = style.x || 0; + var y = style.y || 0; + + var dw = style.width; + var dh = style.height; + + var svgEl = el.__svgEl; + if (!svgEl) { + svgEl = createElement('image'); + el.__svgEl = svgEl; + } + + if (image !== el.__imageSrc) { + attrXLink(svgEl, 'href', image); + // Caching image src + el.__imageSrc = image; + } + + attr(svgEl, 'width', dw); + attr(svgEl, 'height', dh); + + attr(svgEl, 'x', x); + attr(svgEl, 'y', y); + + setTransform(svgEl, el.transform); + + if (style.text != null) { + svgTextDrawRectText(el, el.getBoundingRect()); + } + }; + + /*************************************************** + * TEXT + **************************************************/ + var svgText = {}; + var tmpRect$3 = new BoundingRect(); + + var svgTextDrawRectText = function(el, rect, textRect) { + var style = el.style; + + el.__dirty && normalizeTextStyle(style, true); + + var text = style.text; + // Convert to string + if (text == null) { + // Draw no text only when text is set to null, but not '' + return; + } else { + text += ''; + } + + var textSvgEl = el.__textSvgEl; + if (!textSvgEl) { + textSvgEl = createElement('text'); + el.__textSvgEl = textSvgEl; + } + + var x; + var y; + var textPosition = style.textPosition; + var distance = style.textDistance; + var align = style.textAlign || 'left'; + + if (typeof style.fontSize === 'number') { + style.fontSize += 'px'; + } + var font = style.font || + [ + style.fontStyle || '', + style.fontWeight || '', + style.fontSize || '', + style.fontFamily || '' + ].join(' ') || + DEFAULT_FONT; + + var verticalAlign = getVerticalAlignForSvg(style.textVerticalAlign); + + textRect = getBoundingRect(text, font, align, + verticalAlign); + + var lineHeight = textRect.lineHeight; + // Text position represented by coord + if (textPosition instanceof Array) { + x = rect.x + textPosition[0]; + y = rect.y + textPosition[1]; + } else { + var newPos = adjustTextPositionOnRect( + textPosition, rect, distance + ); + x = newPos.x; + y = newPos.y; + verticalAlign = getVerticalAlignForSvg(newPos.textVerticalAlign); + align = newPos.textAlign; + } + + attr(textSvgEl, 'alignment-baseline', verticalAlign); + + if (font) { + textSvgEl.style.font = font; + } + + var textPadding = style.textPadding; + + // Make baseline top + attr(textSvgEl, 'x', x); + attr(textSvgEl, 'y', y); + + bindStyle(textSvgEl, style, true); + if (el instanceof Text || el.style.transformText) { + // Transform text with element + setTransform(textSvgEl, el.transform); + } else { + if (el.transform) { + tmpRect$3.copy(rect); + tmpRect$3.applyTransform(el.transform); + rect = tmpRect$3; + } else { + var pos = el.transformCoordToGlobal(rect.x, rect.y); + rect.x = pos[0]; + rect.y = pos[1]; + } + + // Text rotation, but no element transform + var origin = style.textOrigin; + if (origin === 'center') { + x = textRect.width / 2 + x; + y = textRect.height / 2 + y; + } else if (origin) { + x = origin[0] + x; + y = origin[1] + y; + } + var rotate$$1 = -style.textRotation || 0; + var transform = create$1(); + // Apply textRotate to element matrix + rotate(transform, el.transform, rotate$$1); + setTransform(textSvgEl, transform); + } + + var textLines = text.split('\n'); + var nTextLines = textLines.length; + var textAnchor = align; + // PENDING + if (textAnchor === 'left') { + textAnchor = 'start'; + textPadding && (x += textPadding[3]); + } else if (textAnchor === 'right') { + textAnchor = 'end'; + textPadding && (x -= textPadding[1]); + } else if (textAnchor === 'center') { + textAnchor = 'middle'; + textPadding && (x += (textPadding[3] - textPadding[1]) / 2); + } + + var dy = 0; + if (verticalAlign === 'baseline') { + dy = -textRect.height + lineHeight; + textPadding && (dy -= textPadding[2]); + } else if (verticalAlign === 'middle') { + dy = (-textRect.height + lineHeight) / 2; + textPadding && (y += (textPadding[0] - textPadding[2]) / 2); + } else { + textPadding && (dy += textPadding[0]); + } + + // Font may affect position of each tspan elements + if (el.__text !== text || el.__textFont !== font) { + var tspanList = el.__tspanList || []; + el.__tspanList = tspanList; + for (var i = 0; i < nTextLines; i++) { + // Using cached tspan elements + var tspan = tspanList[i]; + if (!tspan) { + tspan = tspanList[i] = createElement('tspan'); + textSvgEl.appendChild(tspan); + attr(tspan, 'alignment-baseline', verticalAlign); + attr(tspan, 'text-anchor', textAnchor); + } else { + tspan.innerHTML = ''; + } + attr(tspan, 'x', x); + attr(tspan, 'y', y + i * lineHeight + dy); + tspan.appendChild(document.createTextNode(textLines[i])); + } + // Remove unsed tspan elements + for (; i < tspanList.length; i++) { + textSvgEl.removeChild(tspanList[i]); + } + tspanList.length = nTextLines; + + el.__text = text; + el.__textFont = font; + } else if (el.__tspanList.length) { + // Update span x and y + var len = el.__tspanList.length; + for (var i = 0; i < len; ++i) { + var tspan = el.__tspanList[i]; + if (tspan) { + attr(tspan, 'x', x); + attr(tspan, 'y', y + i * lineHeight + dy); + } + } + } + }; + + function getVerticalAlignForSvg(verticalAlign) { + if (verticalAlign === 'middle') { + return 'middle'; + } else if (verticalAlign === 'bottom') { + return 'baseline'; + } else { + return 'hanging'; + } + } + + svgText.drawRectText = svgTextDrawRectText; + + svgText.brush = function(el) { + var style = el.style; + if (style.text != null) { + // 强制设置 textPosition + style.textPosition = [0, 0]; + svgTextDrawRectText(el, { + x: style.x || 0, + y: style.y || 0, + width: 0, + height: 0 + }, el.getBoundingRect()); + } + }; + + // Myers' Diff Algorithm + // Modified from https://github.com/kpdecker/jsdiff/blob/master/src/diff/base.js + + function Diff() {} + + Diff.prototype = { + diff: function(oldArr, newArr, equals) { + if (!equals) { + equals = function(a, b) { + return a === b; + }; + } + this.equals = equals; + + var self = this; + + oldArr = oldArr.slice(); + newArr = newArr.slice(); + // Allow subclasses to massage the input prior to running + var newLen = newArr.length; + var oldLen = oldArr.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + var bestPath = [{ + newPos: -1, + components: [] + }]; + + // Seed editLength = 0, i.e. the content starts with the same values + var oldPos = this.extractCommon(bestPath[0], newArr, oldArr, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + var indices = []; + for (var i = 0; i < newArr.length; i++) { + indices.push(i); + } + // Identity per the equality and tokenizer + return [{ + indices: indices, + count: newArr.length + }]; + } + + // Main worker method. checks all permutations of a given edit length for acceptance. + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath; + var addPath = bestPath[diagonalPath - 1]; + var removePath = bestPath[diagonalPath + 1]; + var oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + // No one else is going to attempt to use this value, clear it + bestPath[diagonalPath - 1] = undefined; + } + + var canAdd = addPath && addPath.newPos + 1 < newLen; + var canRemove = removePath && 0 <= oldPos && oldPos < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + bestPath[diagonalPath] = undefined; + continue; + } + + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the new string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { + basePath = clonePath(removePath); + self.pushComponent(basePath.components, undefined, true); + } else { + basePath = addPath; // No need to clone, we've pulled it from the list + basePath.newPos++; + self.pushComponent(basePath.components, true, undefined); + } + + oldPos = self.extractCommon(basePath, newArr, oldArr, diagonalPath); + + // If we have hit the end of both strings, then we are done + if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + return buildValues(self, basePath.components, newArr, oldArr); + } else { + // Otherwise track this path as a potential candidate and continue. + bestPath[diagonalPath] = basePath; + } + } + + editLength++; + } + + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + }, + + pushComponent: function(components, added, removed) { + var last = components[components.length - 1]; + if (last && last.added === added && last.removed === removed) { + // We need to clone here as the component clone operation is just + // as shallow array clone + components[components.length - 1] = { + count: last.count + 1, + added: added, + removed: removed + }; + } else { + components.push({ + count: 1, + added: added, + removed: removed + }); + } + }, + extractCommon: function(basePath, newArr, oldArr, diagonalPath) { + var newLen = newArr.length; + var oldLen = oldArr.length; + var newPos = basePath.newPos; + var oldPos = newPos - diagonalPath; + var commonCount = 0; + + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newArr[newPos + 1], oldArr[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; + } + + if (commonCount) { + basePath.components.push({ + count: commonCount + }); + } + + basePath.newPos = newPos; + return oldPos; + }, + tokenize: function(value) { + return value.slice(); + }, + join: function(value) { + return value.slice(); + } + }; + + function buildValues(diff, components, newArr, oldArr) { + var componentPos = 0; + var componentLen = components.length; + var newPos = 0; + var oldPos = 0; + + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + var indices = []; + for (var i = newPos; i < newPos + component.count; i++) { + indices.push(i); + } + component.indices = indices; + newPos += component.count; + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + var indices = []; + for (var i = oldPos; i < oldPos + component.count; i++) { + indices.push(i); + } + component.indices = indices; + oldPos += component.count; + } + } + + return components; + } + + function clonePath(path) { + return { + newPos: path.newPos, + components: path.components.slice(0) + }; + } + + var arrayDiff = new Diff(); + + var arrayDiff$1 = function(oldArr, newArr, callback) { + return arrayDiff.diff(oldArr, newArr, callback); + }; + + /** + * @file Manages elements that can be defined in in SVG, + * e.g., gradients, clip path, etc. + * @author Zhang Wenli + */ + + var MARK_UNUSED = '0'; + var MARK_USED = '1'; + + /** + * Manages elements that can be defined in in SVG, + * e.g., gradients, clip path, etc. + * + * @class + * @param {number} zrId zrender instance id + * @param {SVGElement} svgRoot root of SVG document + * @param {string|string[]} tagNames possible tag names + * @param {string} markLabel label name to make if the element + * is used + */ + function Definable( + zrId, + svgRoot, + tagNames, + markLabel, + domName + ) { + this._zrId = zrId; + this._svgRoot = svgRoot; + this._tagNames = typeof tagNames === 'string' ? [tagNames] : tagNames; + this._markLabel = markLabel; + this._domName = domName || '_dom'; + + this.nextId = 0; + } + + + Definable.prototype.createElement = createElement; + + + /** + * Get the tag for svgRoot; optionally creates one if not exists. + * + * @param {boolean} isForceCreating if need to create when not exists + * @return {SVGDefsElement} SVG element, null if it doesn't + * exist and isForceCreating is false + */ + Definable.prototype.getDefs = function(isForceCreating) { + var svgRoot = this._svgRoot; + var defs = this._svgRoot.getElementsByTagName('defs'); + if (defs.length === 0) { + // Not exist + if (isForceCreating) { + defs = svgRoot.insertBefore( + this.createElement('defs'), // Create new tag + svgRoot.firstChild // Insert in the front of svg + ); + if (!defs.contains) { + // IE doesn't support contains method + defs.contains = function(el) { + var children = defs.children; + if (!children) { + return false; + } + for (var i = children.length - 1; i >= 0; --i) { + if (children[i] === el) { + return true; + } + } + return false; + }; + } + return defs; + } else { + return null; + } + } else { + return defs[0]; + } + }; + + + /** + * Update DOM element if necessary. + * + * @param {Object|string} element style element. e.g., for gradient, + * it may be '#ccc' or {type: 'linear', ...} + * @param {Function|undefined} onUpdate update callback + */ + Definable.prototype.update = function(element, onUpdate) { + if (!element) { + return; + } + + var defs = this.getDefs(false); + if (element[this._domName] && defs.contains(element[this._domName])) { + // Update DOM + if (typeof onUpdate === 'function') { + onUpdate(element); + } + } else { + // No previous dom, create new + var dom = this.add(element); + if (dom) { + element[this._domName] = dom; + } + } + }; + + + /** + * Add gradient dom to defs + * + * @param {SVGElement} dom DOM to be added to + */ + Definable.prototype.addDom = function(dom) { + var defs = this.getDefs(true); + defs.appendChild(dom); + }; + + + /** + * Remove DOM of a given element. + * + * @param {SVGElement} element element to remove dom + */ + Definable.prototype.removeDom = function(element) { + var defs = this.getDefs(false); + if (defs && element[this._domName]) { + defs.removeChild(element[this._domName]); + element[this._domName] = null; + } + }; + + + /** + * Get DOMs of this element. + * + * @return {HTMLDomElement} doms of this defineable elements in + */ + Definable.prototype.getDoms = function() { + var defs = this.getDefs(false); + if (!defs) { + // No dom when defs is not defined + return []; + } + + var doms = []; + each$1(this._tagNames, function(tagName) { + var tags = defs.getElementsByTagName(tagName); + // Note that tags is HTMLCollection, which is array-like + // rather than real array. + // So `doms.concat(tags)` add tags as one object. + doms = doms.concat([].slice.call(tags)); + }); + + return doms; + }; + + + /** + * Mark DOMs to be unused before painting, and clear unused ones at the end + * of the painting. + */ + Definable.prototype.markAllUnused = function() { + var doms = this.getDoms(); + var that = this; + each$1(doms, function(dom) { + dom[that._markLabel] = MARK_UNUSED; + }); + }; + + + /** + * Mark a single DOM to be used. + * + * @param {SVGElement} dom DOM to mark + */ + Definable.prototype.markUsed = function(dom) { + if (dom) { + dom[this._markLabel] = MARK_USED; + } + }; + + + /** + * Remove unused DOMs defined in + */ + Definable.prototype.removeUnused = function() { + var defs = this.getDefs(false); + if (!defs) { + // Nothing to remove + return; + } + + var doms = this.getDoms(); + var that = this; + each$1(doms, function(dom) { + if (dom[that._markLabel] !== MARK_USED) { + // Remove gradient + defs.removeChild(dom); + } + }); + }; + + + /** + * Get SVG proxy. + * + * @param {Displayable} displayable displayable element + * @return {Path|Image|Text} svg proxy of given element + */ + Definable.prototype.getSvgProxy = function(displayable) { + if (displayable instanceof Path) { + return svgPath; + } else if (displayable instanceof ZImage) { + return svgImage; + } else if (displayable instanceof Text) { + return svgText; + } else { + return svgPath; + } + }; + + + /** + * Get text SVG element. + * + * @param {Displayable} displayable displayable element + * @return {SVGElement} SVG element of text + */ + Definable.prototype.getTextSvgElement = function(displayable) { + return displayable.__textSvgEl; + }; + + + /** + * Get SVG element. + * + * @param {Displayable} displayable displayable element + * @return {SVGElement} SVG element + */ + Definable.prototype.getSvgElement = function(displayable) { + return displayable.__svgEl; + }; + + /** + * @file Manages SVG gradient elements. + * @author Zhang Wenli + */ + + /** + * Manages SVG gradient elements. + * + * @class + * @extends Definable + * @param {number} zrId zrender instance id + * @param {SVGElement} svgRoot root of SVG document + */ + function GradientManager(zrId, svgRoot) { + Definable.call( + this, + zrId, + svgRoot, + ['linearGradient', 'radialGradient'], + '__gradient_in_use__' + ); + } + + + inherits(GradientManager, Definable); + + + /** + * Create new gradient DOM for fill or stroke if not exist, + * but will not update gradient if exists. + * + * @param {SvgElement} svgElement SVG element to paint + * @param {Displayable} displayable zrender displayable element + */ + GradientManager.prototype.addWithoutUpdate = function( + svgElement, + displayable + ) { + if (displayable && displayable.style) { + var that = this; + each$1(['fill', 'stroke'], function(fillOrStroke) { + if (displayable.style[fillOrStroke] && + (displayable.style[fillOrStroke].type === 'linear' || + displayable.style[fillOrStroke].type === 'radial') + ) { + var gradient = displayable.style[fillOrStroke]; + var defs = that.getDefs(true); + + // Create dom in if not exists + var dom; + if (gradient._dom) { + // Gradient exists + dom = gradient._dom; + if (!defs.contains(gradient._dom)) { + // _dom is no longer in defs, recreate + that.addDom(dom); + } + } else { + // New dom + dom = that.add(gradient); + } + + that.markUsed(displayable); + + var id = dom.getAttribute('id'); + svgElement.setAttribute(fillOrStroke, 'url(#' + id + ')'); + } + }); + } + }; + + + /** + * Add a new gradient tag in + * + * @param {Gradient} gradient zr gradient instance + * @return {SVGLinearGradientElement | SVGRadialGradientElement} + * created DOM + */ + GradientManager.prototype.add = function(gradient) { + var dom; + if (gradient.type === 'linear') { + dom = this.createElement('linearGradient'); + } else if (gradient.type === 'radial') { + dom = this.createElement('radialGradient'); + } else { + zrLog('Illegal gradient type.'); + return null; + } + + // Set dom id with gradient id, since each gradient instance + // will have no more than one dom element. + // id may exists before for those dirty elements, in which case + // id should remain the same, and other attributes should be + // updated. + gradient.id = gradient.id || this.nextId++; + dom.setAttribute('id', 'zr' + this._zrId + + '-gradient-' + gradient.id); + + this.updateDom(gradient, dom); + this.addDom(dom); + + return dom; + }; + + + /** + * Update gradient. + * + * @param {Gradient} gradient zr gradient instance + */ + GradientManager.prototype.update = function(gradient) { + var that = this; + Definable.prototype.update.call(this, gradient, function() { + var type = gradient.type; + var tagName = gradient._dom.tagName; + if (type === 'linear' && tagName === 'linearGradient' || + type === 'radial' && tagName === 'radialGradient' + ) { + // Gradient type is not changed, update gradient + that.updateDom(gradient, gradient._dom); + } else { + // Remove and re-create if type is changed + that.removeDom(gradient); + that.add(gradient); + } + }); + }; + + + /** + * Update gradient dom + * + * @param {Gradient} gradient zr gradient instance + * @param {SVGLinearGradientElement | SVGRadialGradientElement} dom + * DOM to update + */ + GradientManager.prototype.updateDom = function(gradient, dom) { + if (gradient.type === 'linear') { + dom.setAttribute('x1', gradient.x); + dom.setAttribute('y1', gradient.y); + dom.setAttribute('x2', gradient.x2); + dom.setAttribute('y2', gradient.y2); + } else if (gradient.type === 'radial') { + dom.setAttribute('cx', gradient.x); + dom.setAttribute('cy', gradient.y); + dom.setAttribute('r', gradient.r); + } else { + zrLog('Illegal gradient type.'); + return; + } + + if (gradient.global) { + // x1, x2, y1, y2 in range of 0 to canvas width or height + dom.setAttribute('gradientUnits', 'userSpaceOnUse'); + } else { + // x1, x2, y1, y2 in range of 0 to 1 + dom.setAttribute('gradientUnits', 'objectBoundingBox'); + } + + // Remove color stops if exists + dom.innerHTML = ''; + + // Add color stops + var colors = gradient.colorStops; + for (var i = 0, len = colors.length; i < len; ++i) { + var stop = this.createElement('stop'); + stop.setAttribute('offset', colors[i].offset * 100 + '%'); + stop.setAttribute('stop-color', colors[i].color); + dom.appendChild(stop); + } + + // Store dom element in gradient, to avoid creating multiple + // dom instances for the same gradient element + gradient._dom = dom; + }; + + /** + * Mark a single gradient to be used + * + * @param {Displayable} displayable displayable element + */ + GradientManager.prototype.markUsed = function(displayable) { + if (displayable.style) { + var gradient = displayable.style.fill; + if (gradient && gradient._dom) { + Definable.prototype.markUsed.call(this, gradient._dom); + } + + gradient = displayable.style.stroke; + if (gradient && gradient._dom) { + Definable.prototype.markUsed.call(this, gradient._dom); + } + } + }; + + /** + * @file Manages SVG clipPath elements. + * @author Zhang Wenli + */ + + /** + * Manages SVG clipPath elements. + * + * @class + * @extends Definable + * @param {number} zrId zrender instance id + * @param {SVGElement} svgRoot root of SVG document + */ + function ClippathManager(zrId, svgRoot) { + Definable.call(this, zrId, svgRoot, 'clipPath', '__clippath_in_use__'); + } + + + inherits(ClippathManager, Definable); + + + /** + * Update clipPath. + * + * @param {Displayable} displayable displayable element + */ + ClippathManager.prototype.update = function(displayable) { + var svgEl = this.getSvgElement(displayable); + if (svgEl) { + this.updateDom(svgEl, displayable.__clipPaths, false); + } + + var textEl = this.getTextSvgElement(displayable); + if (textEl) { + // Make another clipPath for text, since it's transform + // matrix is not the same with svgElement + this.updateDom(textEl, displayable.__clipPaths, true); + } + + this.markUsed(displayable); + }; + + + /** + * Create an SVGElement of displayable and create a of its + * clipPath + * + * @param {Displayable} parentEl parent element + * @param {ClipPath[]} clipPaths clipPaths of parent element + * @param {boolean} isText if parent element is Text + */ + ClippathManager.prototype.updateDom = function( + parentEl, + clipPaths, + isText + ) { + if (clipPaths && clipPaths.length > 0) { + // Has clipPath, create with the first clipPath + var defs = this.getDefs(true); + var clipPath = clipPaths[0]; + var clipPathEl; + var id; + + var dom = isText ? '_textDom' : '_dom'; + + if (clipPath[dom]) { + // Use a dom that is already in + id = clipPath[dom].getAttribute('id'); + clipPathEl = clipPath[dom]; + + // Use a dom that is already in + if (!defs.contains(clipPathEl)) { + // This happens when set old clipPath that has + // been previously removed + defs.appendChild(clipPathEl); + } + } else { + // New + id = 'zr' + this._zrId + '-clip-' + this.nextId; + ++this.nextId; + clipPathEl = this.createElement('clipPath'); + clipPathEl.setAttribute('id', id); + defs.appendChild(clipPathEl); + + clipPath[dom] = clipPathEl; + } + + // Build path and add to + var svgProxy = this.getSvgProxy(clipPath); + if (clipPath.transform && + clipPath.parent.invTransform && + !isText + ) { + /** + * If a clipPath has a parent with transform, the transform + * of parent should not be considered when setting transform + * of clipPath. So we need to transform back from parent's + * transform, which is done by multiplying parent's inverse + * transform. + */ + // Store old transform + var transform = Array.prototype.slice.call( + clipPath.transform + ); + + // Transform back from parent, and brush path + mul$1( + clipPath.transform, + clipPath.parent.invTransform, + clipPath.transform + ); + svgProxy.brush(clipPath); + + // Set back transform of clipPath + clipPath.transform = transform; + } else { + svgProxy.brush(clipPath); + } + + var pathEl = this.getSvgElement(clipPath); + + clipPathEl.innerHTML = ''; + /** + * Use `cloneNode()` here to appendChild to multiple parents, + * which may happend when Text and other shapes are using the same + * clipPath. Since Text will create an extra clipPath DOM due to + * different transform rules. + */ + clipPathEl.appendChild(pathEl.cloneNode()); + + parentEl.setAttribute('clip-path', 'url(#' + id + ')'); + + if (clipPaths.length > 1) { + // Make the other clipPaths recursively + this.updateDom(clipPathEl, clipPaths.slice(1), isText); + } + } else { + // No clipPath + if (parentEl) { + parentEl.setAttribute('clip-path', 'none'); + } + } + }; + + /** + * Mark a single clipPath to be used + * + * @param {Displayable} displayable displayable element + */ + ClippathManager.prototype.markUsed = function(displayable) { + var that = this; + if (displayable.__clipPaths && displayable.__clipPaths.length > 0) { + each$1(displayable.__clipPaths, function(clipPath) { + if (clipPath._dom) { + Definable.prototype.markUsed.call(that, clipPath._dom); + } + if (clipPath._textDom) { + Definable.prototype.markUsed.call(that, clipPath._textDom); + } + }); + } + }; + + /** + * @file Manages SVG shadow elements. + * @author Zhang Wenli + */ + + /** + * Manages SVG shadow elements. + * + * @class + * @extends Definable + * @param {number} zrId zrender instance id + * @param {SVGElement} svgRoot root of SVG document + */ + function ShadowManager(zrId, svgRoot) { + Definable.call( + this, + zrId, + svgRoot, + ['filter'], + '__filter_in_use__', + '_shadowDom' + ); + } + + + inherits(ShadowManager, Definable); + + + /** + * Create new shadow DOM for fill or stroke if not exist, + * but will not update shadow if exists. + * + * @param {SvgElement} svgElement SVG element to paint + * @param {Displayable} displayable zrender displayable element + */ + ShadowManager.prototype.addWithoutUpdate = function( + svgElement, + displayable + ) { + if (displayable && hasShadow(displayable.style)) { + var style = displayable.style; + + // Create dom in if not exists + var dom; + if (style._shadowDom) { + // Gradient exists + dom = style._shadowDom; + + var defs = this.getDefs(true); + if (!defs.contains(style._shadowDom)) { + // _shadowDom is no longer in defs, recreate + this.addDom(dom); + } + } else { + // New dom + dom = this.add(displayable); + } + + this.markUsed(displayable); + + var id = dom.getAttribute('id'); + svgElement.style.filter = 'url(#' + id + ')'; + } + }; + + + /** + * Add a new shadow tag in + * + * @param {Displayable} displayable zrender displayable element + * @return {SVGFilterElement} created DOM + */ + ShadowManager.prototype.add = function(displayable) { + var dom = this.createElement('filter'); + var style = displayable.style; + + // Set dom id with shadow id, since each shadow instance + // will have no more than one dom element. + // id may exists before for those dirty elements, in which case + // id should remain the same, and other attributes should be + // updated. + style._shadowDomId = style._shadowDomId || this.nextId++; + dom.setAttribute('id', 'zr' + this._zrId + + '-shadow-' + style._shadowDomId); + + this.updateDom(displayable, dom); + this.addDom(dom); + + return dom; + }; + + + /** + * Update shadow. + * + * @param {Displayable} displayable zrender displayable element + */ + ShadowManager.prototype.update = function(svgElement, displayable) { + var style = displayable.style; + if (hasShadow(style)) { + var that = this; + Definable.prototype.update.call(this, displayable, function(style) { + that.updateDom(displayable, style._shadowDom); + }); + } else { + // Remove shadow + this.remove(svgElement, style); + } + }; + + + /** + * Remove DOM and clear parent filter + */ + ShadowManager.prototype.remove = function(svgElement, style) { + if (style._shadowDomId != null) { + this.removeDom(style); + svgElement.style.filter = ''; + } + }; + + + /** + * Update shadow dom + * + * @param {Displayable} displayable zrender displayable element + * @param {SVGFilterElement} dom DOM to update + */ + ShadowManager.prototype.updateDom = function(displayable, dom) { + var domChild = dom.getElementsByTagName('feDropShadow'); + if (domChild.length === 0) { + domChild = this.createElement('feDropShadow'); + } else { + domChild = domChild[0]; + } + + var style = displayable.style; + var scaleX = displayable.scale ? (displayable.scale[0] || 1) : 1; + var scaleY = displayable.scale ? (displayable.scale[1] || 1) : 1; + + // TODO: textBoxShadowBlur is not supported yet + var offsetX, offsetY, blur, color; + if (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY) { + offsetX = style.shadowOffsetX || 0; + offsetY = style.shadowOffsetY || 0; + blur = style.shadowBlur; + color = style.shadowColor; + } else if (style.textShadowBlur) { + offsetX = style.textShadowOffsetX || 0; + offsetY = style.textShadowOffsetY || 0; + blur = style.textShadowBlur; + color = style.textShadowColor; + } else { + // Remove shadow + this.removeDom(dom, style); + return; + } + + domChild.setAttribute('dx', offsetX / scaleX); + domChild.setAttribute('dy', offsetY / scaleY); + domChild.setAttribute('flood-color', color); + + // Divide by two here so that it looks the same as in canvas + // See: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur + var stdDx = blur / 2 / scaleX; + var stdDy = blur / 2 / scaleY; + var stdDeviation = stdDx + ' ' + stdDy; + domChild.setAttribute('stdDeviation', stdDeviation); + + // Fix filter clipping problem + dom.setAttribute('x', '-100%'); + dom.setAttribute('y', '-100%'); + dom.setAttribute('width', Math.ceil(blur / 2 * 200) + '%'); + dom.setAttribute('height', Math.ceil(blur / 2 * 200) + '%'); + + dom.appendChild(domChild); + + // Store dom element in shadow, to avoid creating multiple + // dom instances for the same shadow element + style._shadowDom = dom; + }; + + /** + * Mark a single shadow to be used + * + * @param {Displayable} displayable displayable element + */ + ShadowManager.prototype.markUsed = function(displayable) { + var style = displayable.style; + if (style && style._shadowDom) { + Definable.prototype.markUsed.call(this, style._shadowDom); + } + }; + + function hasShadow(style) { + // TODO: textBoxShadowBlur is not supported yet + return style && + (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY || + style.textShadowBlur || style.textShadowOffsetX || + style.textShadowOffsetY); + } + + /** + * SVG Painter + * @module zrender/svg/Painter + */ + + function parseInt10$2(val) { + return parseInt(val, 10); + } + + function getSvgProxy(el) { + if (el instanceof Path) { + return svgPath; + } else if (el instanceof ZImage) { + return svgImage; + } else if (el instanceof Text) { + return svgText; + } else { + return svgPath; + } + } + + function checkParentAvailable(parent, child) { + return child && parent && child.parentNode !== parent; + } + + function insertAfter(parent, child, prevSibling) { + if (checkParentAvailable(parent, child) && prevSibling) { + var nextSibling = prevSibling.nextSibling; + nextSibling ? parent.insertBefore(child, nextSibling) : + parent.appendChild(child); + } + } + + function prepend(parent, child) { + if (checkParentAvailable(parent, child)) { + var firstChild = parent.firstChild; + firstChild ? parent.insertBefore(child, firstChild) : + parent.appendChild(child); + } + } + + function remove$1(parent, child) { + if (child && parent && child.parentNode === parent) { + parent.removeChild(child); + } + } + + function getTextSvgElement(displayable) { + return displayable.__textSvgEl; + } + + function getSvgElement(displayable) { + return displayable.__svgEl; + } + + /** + * @alias module:zrender/svg/Painter + * @constructor + * @param {HTMLElement} root 绘图容器 + * @param {module:zrender/Storage} storage + * @param {Object} opts + */ + var SVGPainter = function(root, storage, opts, zrId) { + + this.root = root; + this.storage = storage; + this._opts = opts = extend({}, opts || {}); + + var svgRoot = createElement('svg'); + svgRoot.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + svgRoot.setAttribute('version', '1.1'); + svgRoot.setAttribute('baseProfile', 'full'); + svgRoot.style.cssText = 'user-select:none;position:absolute;left:0;top:0;'; + + this.gradientManager = new GradientManager(zrId, svgRoot); + this.clipPathManager = new ClippathManager(zrId, svgRoot); + this.shadowManager = new ShadowManager(zrId, svgRoot); + + var viewport = document.createElement('div'); + viewport.style.cssText = 'overflow:hidden;position:relative'; + + this._svgRoot = svgRoot; + this._viewport = viewport; + + root.appendChild(viewport); + viewport.appendChild(svgRoot); + + this.resize(opts.width, opts.height); + + this._visibleList = []; + }; + + SVGPainter.prototype = { + + constructor: SVGPainter, + + getType: function() { + return 'svg'; + }, + + getViewportRoot: function() { + return this._viewport; + }, + + getViewportRootOffset: function() { + var viewportRoot = this.getViewportRoot(); + if (viewportRoot) { + return { + offsetLeft: viewportRoot.offsetLeft || 0, + offsetTop: viewportRoot.offsetTop || 0 + }; + } + }, + + refresh: function() { + + var list = this.storage.getDisplayList(true); + + this._paintList(list); + }, + + setBackgroundColor: function(backgroundColor) { + // TODO gradient + this._viewport.style.background = backgroundColor; + }, + + _paintList: function(list) { + this.gradientManager.markAllUnused(); + this.clipPathManager.markAllUnused(); + this.shadowManager.markAllUnused(); + + var svgRoot = this._svgRoot; + var visibleList = this._visibleList; + var listLen = list.length; + + var newVisibleList = []; + var i; + for (i = 0; i < listLen; i++) { + var displayable = list[i]; + var svgProxy = getSvgProxy(displayable); + var svgElement = getSvgElement(displayable) || + getTextSvgElement(displayable); + if (!displayable.invisible) { + if (displayable.__dirty) { + svgProxy && svgProxy.brush(displayable); + + // Update clipPath + this.clipPathManager.update(displayable); + + // Update gradient and shadow + if (displayable.style) { + this.gradientManager + .update(displayable.style.fill); + this.gradientManager + .update(displayable.style.stroke); + + this.shadowManager + .update(svgElement, displayable); + } + + displayable.__dirty = false; + } + newVisibleList.push(displayable); + } + } + + var diff = arrayDiff$1(visibleList, newVisibleList); + var prevSvgElement; + + // First do remove, in case element moved to the head and do remove + // after add + for (i = 0; i < diff.length; i++) { + var item = diff[i]; + if (item.removed) { + for (var k = 0; k < item.count; k++) { + var displayable = visibleList[item.indices[k]]; + var svgElement = getSvgElement(displayable); + var textSvgElement = getTextSvgElement(displayable); + remove$1(svgRoot, svgElement); + remove$1(svgRoot, textSvgElement); + } + } + } + for (i = 0; i < diff.length; i++) { + var item = diff[i]; + if (item.added) { + for (var k = 0; k < item.count; k++) { + var displayable = newVisibleList[item.indices[k]]; + var svgElement = getSvgElement(displayable); + var textSvgElement = getTextSvgElement(displayable); + prevSvgElement + ? + insertAfter(svgRoot, svgElement, prevSvgElement) : + prepend(svgRoot, svgElement); + if (svgElement) { + insertAfter(svgRoot, textSvgElement, svgElement); + } else if (prevSvgElement) { + insertAfter( + svgRoot, textSvgElement, prevSvgElement + ); + } else { + prepend(svgRoot, textSvgElement); + } + // Insert text + insertAfter(svgRoot, textSvgElement, svgElement); + prevSvgElement = textSvgElement || svgElement || + prevSvgElement; + + this.gradientManager + .addWithoutUpdate(svgElement, displayable); + this.shadowManager + .addWithoutUpdate(prevSvgElement, displayable); + this.clipPathManager.markUsed(displayable); + } + } else if (!item.removed) { + for (var k = 0; k < item.count; k++) { + var displayable = newVisibleList[item.indices[k]]; + prevSvgElement + = svgElement = getTextSvgElement(displayable) || + getSvgElement(displayable) || + prevSvgElement; + + this.gradientManager.markUsed(displayable); + this.gradientManager + .addWithoutUpdate(svgElement, displayable); + + this.shadowManager.markUsed(displayable); + this.shadowManager + .addWithoutUpdate(svgElement, displayable); + + this.clipPathManager.markUsed(displayable); + } + } + } + + this.gradientManager.removeUnused(); + this.clipPathManager.removeUnused(); + this.shadowManager.removeUnused(); + + this._visibleList = newVisibleList; + }, + + _getDefs: function(isForceCreating) { + var svgRoot = this._svgRoot; + var defs = this._svgRoot.getElementsByTagName('defs'); + if (defs.length === 0) { + // Not exist + if (isForceCreating) { + var defs = svgRoot.insertBefore( + createElement('defs'), // Create new tag + svgRoot.firstChild // Insert in the front of svg + ); + if (!defs.contains) { + // IE doesn't support contains method + defs.contains = function(el) { + var children = defs.children; + if (!children) { + return false; + } + for (var i = children.length - 1; i >= 0; --i) { + if (children[i] === el) { + return true; + } + } + return false; + }; + } + return defs; + } else { + return null; + } + } else { + return defs[0]; + } + }, + + resize: function(width, height) { + var viewport = this._viewport; + // FIXME Why ? + viewport.style.display = 'none'; + + // Save input w/h + var opts = this._opts; + width != null && (opts.width = width); + height != null && (opts.height = height); + + width = this._getSize(0); + height = this._getSize(1); + + viewport.style.display = ''; + + if (this._width !== width || this._height !== height) { + this._width = width; + this._height = height; + + var viewportStyle = viewport.style; + viewportStyle.width = width + 'px'; + viewportStyle.height = height + 'px'; + + var svgRoot = this._svgRoot; + // Set width by 'svgRoot.width = width' is invalid + svgRoot.setAttribute('width', width); + svgRoot.setAttribute('height', height); + } + }, + + /** + * 获取绘图区域宽度 + */ + getWidth: function() { + return this._width; + }, + + /** + * 获取绘图区域高度 + */ + getHeight: function() { + return this._height; + }, + + _getSize: function(whIdx) { + var opts = this._opts; + var wh = ['width', 'height'][whIdx]; + var cwh = ['clientWidth', 'clientHeight'][whIdx]; + var plt = ['paddingLeft', 'paddingTop'][whIdx]; + var prb = ['paddingRight', 'paddingBottom'][whIdx]; + + if (opts[wh] != null && opts[wh] !== 'auto') { + return parseFloat(opts[wh]); + } + + var root = this.root; + // IE8 does not support getComputedStyle, but it use VML. + var stl = document.defaultView.getComputedStyle(root); + + return ( + (root[cwh] || parseInt10$2(stl[wh]) || parseInt10$2(root.style[wh])) - + (parseInt10$2(stl[plt]) || 0) - + (parseInt10$2(stl[prb]) || 0) + ) | 0; + }, + + dispose: function() { + this.root.innerHTML = ''; + + this._svgRoot = this._viewport = this.storage = null; + }, + + clear: function() { + if (this._viewport) { + this.root.removeChild(this._viewport); + } + }, + + pathToDataUrl: function() { + this.refresh(); + var html = this._svgRoot.outerHTML; + return 'data:image/svg+xml;charset=UTF-8,' + html; + } + }; + + // Not supported methods + function createMethodNotSupport$1(method) { + return function() { + zrLog('In SVG mode painter not support method "' + method + '"'); + }; + } + + // Unsuppoted methods + each$1([ + 'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', + 'eachOtherLayer', 'getLayers', 'modLayer', 'delLayer', 'clearLayer', + 'toDataURL', 'pathToImage' + ], function(name) { + SVGPainter.prototype[name] = createMethodNotSupport$1(name); + }); + + registerPainter('svg', SVGPainter); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + // Import all charts and components + + exports.version = version; + exports.dependencies = dependencies; + exports.PRIORITY = PRIORITY; + exports.init = init; + exports.connect = connect; + exports.disConnect = disConnect; + exports.disconnect = disconnect; + exports.dispose = dispose; + exports.getInstanceByDom = getInstanceByDom; + exports.getInstanceById = getInstanceById; + exports.registerTheme = registerTheme; + exports.registerPreprocessor = registerPreprocessor; + exports.registerProcessor = registerProcessor; + exports.registerPostUpdate = registerPostUpdate; + exports.registerAction = registerAction; + exports.registerCoordinateSystem = registerCoordinateSystem; + exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions; + exports.registerLayout = registerLayout; + exports.registerVisual = registerVisual; + exports.registerLoading = registerLoading; + exports.extendComponentModel = extendComponentModel; + exports.extendComponentView = extendComponentView; + exports.extendSeriesModel = extendSeriesModel; + exports.extendChartView = extendChartView; + exports.setCanvasCreator = setCanvasCreator; + exports.registerMap = registerMap; + exports.getMap = getMap; + exports.dataTool = dataTool; + exports.zrender = zrender; + exports.graphic = graphic; + exports.number = number; + exports.format = format; + exports.throttle = throttle; + exports.helper = helper; + exports.matrix = matrix; + exports.vector = vector; + exports.color = color; + exports.parseGeoJSON = parseGeoJson$1; + exports.parseGeoJson = parseGeoJson; + exports.util = ecUtil; + exports.List = List; + exports.Model = Model; + exports.Axis = Axis; + exports.env = env$1; + //接着:在代码最尾部加:(其余的看情况加) + exports.Axis = Axis;exports.env = env$1; + // exports.parseGeoJson = parseGeoJson; + // return exports; + +}))); +//# sourceMappingURL=echarts.js.map diff --git a/src/main/resources/static/js/echarts.min.js b/src/main/resources/static/js/echarts.min.js new file mode 100644 index 0000000..1bd7ce6 --- /dev/null +++ b/src/main/resources/static/js/echarts.min.js @@ -0,0 +1,22 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.echarts={})}(this,function(t){"use strict";function e(t,e){"createCanvas"===t&&(v_=null),g_[t]=e}function i(t){if(null==t||"object"!=typeof t)return t;var e=t,n=l_.call(t);if("[object Array]"===n){if(!O(t)){e=[];for(var o=0,a=t.length;oO_||t<-O_}function vt(t){this._target=t.target,this._life=t.life||1e3,this._delay=t.delay||0,this._initialized=!1,this.loop=null!=t.loop&&t.loop,this.gap=t.gap||0,this.easing=t.easing||"Linear",this.onframe=t.onframe,this.ondestroy=t.ondestroy,this.onrestart=t.onrestart,this._pausedTime=0,this._paused=!1}function yt(t){return(t=Math.round(t))<0?0:t>255?255:t}function xt(t){return(t=Math.round(t))<0?0:t>360?360:t}function _t(t){return t<0?0:t>1?1:t}function wt(t){return yt(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function bt(t){return _t(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function St(t,e,i){return i<0?i+=1:i>1&&(i-=1),6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function Mt(t,e,i){return t+(e-t)*i}function It(t,e,i,n,o){return t[0]=e,t[1]=i,t[2]=n,t[3]=o,t}function Tt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function Dt(t,e){X_&&Tt(X_,e),X_=U_.put(t,X_||e.slice())}function At(t,e){if(t){e=e||[];var i=U_.get(t);if(i)return Tt(e,i);var n=(t+="").replace(/ /g,"").toLowerCase();if(n in Z_)return Tt(e,Z_[n]),Dt(t,e),e;if("#"!==n.charAt(0)){var o=n.indexOf("("),a=n.indexOf(")");if(-1!==o&&a+1===n.length){var r=n.substr(0,o),s=n.substr(o+1,a-(o+1)).split(","),l=1;switch(r){case"rgba":if(4!==s.length)return void It(e,0,0,0,1);l=bt(s.pop());case"rgb":return 3!==s.length?void It(e,0,0,0,1):(It(e,wt(s[0]),wt(s[1]),wt(s[2]),l),Dt(t,e),e);case"hsla":return 4!==s.length?void It(e,0,0,0,1):(s[3]=bt(s[3]),Ct(s,e),Dt(t,e),e);case"hsl":return 3!==s.length?void It(e,0,0,0,1):(Ct(s,e),Dt(t,e),e);default:return}}It(e,0,0,0,1)}else{if(4===n.length)return(u=parseInt(n.substr(1),16))>=0&&u<=4095?(It(e,(3840&u)>>4|(3840&u)>>8,240&u|(240&u)>>4,15&u|(15&u)<<4,1),Dt(t,e),e):void It(e,0,0,0,1);if(7===n.length){var u=parseInt(n.substr(1),16);return u>=0&&u<=16777215?(It(e,(16711680&u)>>16,(65280&u)>>8,255&u,1),Dt(t,e),e):void It(e,0,0,0,1)}}}}function Ct(t,e){var i=(parseFloat(t[0])%360+360)%360/360,n=bt(t[1]),o=bt(t[2]),a=o<=.5?o*(n+1):o+n-o*n,r=2*o-a;return e=e||[],It(e,yt(255*St(r,a,i+1/3)),yt(255*St(r,a,i)),yt(255*St(r,a,i-1/3)),1),4===t.length&&(e[3]=t[3]),e}function Lt(t){if(t){var e,i,n=t[0]/255,o=t[1]/255,a=t[2]/255,r=Math.min(n,o,a),s=Math.max(n,o,a),l=s-r,u=(s+r)/2;if(0===l)e=0,i=0;else{i=u<.5?l/(s+r):l/(2-s-r);var h=((s-n)/6+l/2)/l,c=((s-o)/6+l/2)/l,d=((s-a)/6+l/2)/l;n===s?e=d-c:o===s?e=1/3+h-d:a===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,u];return null!=t[3]&&f.push(t[3]),f}}function kt(t,e){var i=At(t);if(i){for(var n=0;n<3;n++)i[n]=e<0?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0,i[n]>255?i[n]=255:t[n]<0&&(i[n]=0);return zt(i,4===i.length?"rgba":"rgb")}}function Pt(t){var e=At(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)}function Nt(t,e,i){if(e&&e.length&&t>=0&&t<=1){i=i||[];var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=e[o],s=e[a],l=n-o;return i[0]=yt(Mt(r[0],s[0],l)),i[1]=yt(Mt(r[1],s[1],l)),i[2]=yt(Mt(r[2],s[2],l)),i[3]=_t(Mt(r[3],s[3],l)),i}}function Ot(t,e,i){if(e&&e.length&&t>=0&&t<=1){var n=t*(e.length-1),o=Math.floor(n),a=Math.ceil(n),r=At(e[o]),s=At(e[a]),l=n-o,u=zt([yt(Mt(r[0],s[0],l)),yt(Mt(r[1],s[1],l)),yt(Mt(r[2],s[2],l)),_t(Mt(r[3],s[3],l))],"rgba");return i?{color:u,leftIndex:o,rightIndex:a,value:n}:u}}function Et(t,e,i,n){if(t=At(t))return t=Lt(t),null!=e&&(t[0]=xt(e)),null!=i&&(t[1]=bt(i)),null!=n&&(t[2]=bt(n)),zt(Ct(t),"rgba")}function Rt(t,e){if((t=At(t))&&null!=e)return t[3]=_t(e),zt(t,"rgba")}function zt(t,e){if(t&&t.length){var i=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(i+=","+t[3]),e+"("+i+")"}}function Bt(t,e){return t[e]}function Vt(t,e,i){t[e]=i}function Gt(t,e,i){return(e-t)*i+t}function Wt(t,e,i){return i>.5?e:t}function Ft(t,e,i,n,o){var a=t.length;if(1==o)for(s=0;so)t.length=o;else for(r=n;r=0&&!(m[i]<=e);i--);i=Math.min(i,u-2)}else{for(i=L;ie);i++);i=Math.min(i-1,u-2)}L=i,k=e;var n=m[i+1]-m[i];if(0!==n)if(I=(e-m[i])/n,l)if(D=v[i],T=v[0===i?i:i-1],A=v[i>u-2?u-1:i+1],C=v[i>u-3?u-1:i+2],d)Ut(T,D,A,C,I,I*I,I*I*I,r(t,o),g);else{if(f)a=Ut(T,D,A,C,I,I*I,I*I*I,P,1),a=Yt(P);else{if(p)return Wt(D,A,I);a=Xt(T,D,A,C,I,I*I,I*I*I)}s(t,o,a)}else if(d)Ft(v[i],v[i+1],I,r(t,o),g);else{var a;if(f)Ft(v[i],v[i+1],I,P,1),a=Yt(P);else{if(p)return Wt(v[i],v[i+1],I);a=Gt(v[i],v[i+1],I)}s(t,o,a)}},ondestroy:i});return e&&"spline"!==e&&(N.easing=e),N}}}function $t(t,e,i,n){i<0&&(t+=i,i=-i),n<0&&(e+=n,n=-n),this.x=t,this.y=e,this.width=i,this.height=n}function Jt(t){for(var e=0;t>=lw;)e|=1&t,t>>=1;return t+e}function Qt(t,e,i,n){var o=e+1;if(o===i)return 1;if(n(t[o++],t[e])<0){for(;o=0;)o++;return o-e}function te(t,e,i){for(i--;e>>1])<0?l=a:s=a+1;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=r}}function ie(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])>0){for(s=n-o;l0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}else{for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}for(r++;r>>1);a(t,e[i+h])>0?r=h+1:l=h}return l}function ne(t,e,i,n,o,a){var r=0,s=0,l=1;if(a(t,e[i+o])<0){for(s=o+1;ls&&(l=s);var u=r;r=o-l,l=o-u}else{for(s=n-o;l=0;)r=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),r+=o,l+=o}for(r++;r>>1);a(t,e[i+h])<0?l=h:r=h+1}return l}function oe(t,e){function i(i){var s=a[i],u=r[i],h=a[i+1],c=r[i+1];r[i]=u+c,i===l-3&&(a[i+1]=a[i+2],r[i+1]=r[i+2]),l--;var d=ne(t[h],t,s,u,0,e);s+=d,0!==(u-=d)&&0!==(c=ie(t[s+u-1],t,h,c,c-1,e))&&(u<=c?n(s,u,h,c):o(s,u,h,c))}function n(i,n,o,a){var r=0;for(r=0;r=uw||f>=uw);if(p)break;g<0&&(g=0),g+=2}if((s=g)<1&&(s=1),1===n){for(r=0;r=0;r--)t[f+r]=t[d+r];if(0===n){v=!0;break}}if(t[c--]=u[h--],1==--a){v=!0;break}if(0!=(m=a-ie(t[l],u,0,a,a-1,e))){for(a-=m,f=(c-=m)+1,d=(h-=m)+1,r=0;r=uw||m>=uw);if(v)break;p<0&&(p=0),p+=2}if((s=p)<1&&(s=1),1===a){for(f=(c-=n)+1,d=(l-=n)+1,r=n-1;r>=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else{if(0===a)throw new Error;for(d=c-(a-1),r=0;r=0;r--)t[f+r]=t[d+r];t[c]=u[h]}else for(d=c-(a-1),r=0;r1;){var t=l-2;if(t>=1&&r[t-1]<=r[t]+r[t+1]||t>=2&&r[t-2]<=r[t]+r[t-1])r[t-1]r[t+1])break;i(t)}},this.forceMergeRuns=function(){for(;l>1;){var t=l-2;t>0&&r[t-1]s&&(l=s),ee(t,i,i+l,i+a,e),a=l}r.pushRun(i,a),r.mergeRuns(),o-=a,i+=a}while(0!==o);r.forceMergeRuns()}}function re(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}function se(t,e,i){var n=null==e.x?0:e.x,o=null==e.x2?1:e.x2,a=null==e.y?0:e.y,r=null==e.y2?0:e.y2;return e.global||(n=n*i.width+i.x,o=o*i.width+i.x,a=a*i.height+i.y,r=r*i.height+i.y),n=isNaN(n)?0:n,o=isNaN(o)?1:o,a=isNaN(a)?0:a,r=isNaN(r)?0:r,t.createLinearGradient(n,a,o,r)}function le(t,e,i){var n=i.width,o=i.height,a=Math.min(n,o),r=null==e.x?.5:e.x,s=null==e.y?.5:e.y,l=null==e.r?.5:e.r;return e.global||(r=r*n+i.x,s=s*o+i.y,l*=a),t.createRadialGradient(r,s,0,r,s,l)}function ue(){return!1}function he(t,e,i){var n=m_(),o=e.getWidth(),a=e.getHeight(),r=n.style;return r&&(r.position="absolute",r.left=0,r.top=0,r.width=o+"px",r.height=a+"px",n.setAttribute("data-zr-dom-id",t)),n.width=o*i,n.height=a*i,n}function ce(t){if("string"==typeof t){var e=ww.get(t);return e&&e.image}return t}function de(t,e,i,n,o){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!i)return e;var a=ww.get(t),r={hostEl:i,cb:n,cbPayload:o};return a?!pe(e=a.image)&&a.pending.push(r):(!e&&(e=new Image),e.onload=fe,ww.put(t,e.__cachedImgObj={image:e,pending:[r]}),e.src=e.__zrImageSrc=t),e}return t}return e}function fe(){var t=this.__cachedImgObj;this.onload=this.__cachedImgObj=null;for(var e=0;eMw&&(Sw=0,bw={}),Sw++,bw[i]=o,o}function me(t,e,i,n,o,a,r){return a?ye(t,e,i,n,o,a,r):ve(t,e,i,n,o,r)}function ve(t,e,i,n,o,a){var r=Ae(t,e,o,a),s=ge(t,e);o&&(s+=o[1]+o[3]);var l=r.outerHeight,u=new $t(xe(0,s,i),_e(0,l,n),s,l);return u.lineHeight=r.lineHeight,u}function ye(t,e,i,n,o,a,r){var s=Ce(t,{rich:a,truncate:r,font:e,textAlign:i,textPadding:o}),l=s.outerWidth,u=s.outerHeight;return new $t(xe(0,l,i),_e(0,u,n),l,u)}function xe(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function _e(t,e,i){return"middle"===i?t-=e/2:"bottom"===i&&(t-=e),t}function we(t,e,i){var n=e.x,o=e.y,a=e.height,r=e.width,s=a/2,l="left",u="top";switch(t){case"left":n-=i,o+=s,l="right",u="middle";break;case"right":n+=i+r,o+=s,u="middle";break;case"top":n+=r/2,o-=i,l="center",u="bottom";break;case"bottom":n+=r/2,o+=a+i,l="center";break;case"inside":n+=r/2,o+=s,l="center",u="middle";break;case"insideLeft":n+=i,o+=s,u="middle";break;case"insideRight":n+=r-i,o+=s,l="right",u="middle";break;case"insideTop":n+=r/2,o+=i,l="center";break;case"insideBottom":n+=r/2,o+=a-i,l="center",u="bottom";break;case"insideTopLeft":n+=i,o+=i;break;case"insideTopRight":n+=r-i,o+=i,l="right";break;case"insideBottomLeft":n+=i,o+=a-i,u="bottom";break;case"insideBottomRight":n+=r-i,o+=a-i,l="right",u="bottom"}return{x:n,y:o,textAlign:l,textVerticalAlign:u}}function be(t,e,i,n,o){if(!e)return"";var a=(t+"").split("\n");o=Se(e,i,n,o);for(var r=0,s=a.length;r=r;l++)s-=r;var u=ge(i);return u>s&&(i="",u=0),s=t-u,n.ellipsis=i,n.ellipsisWidth=u,n.contentWidth=s,n.containerWidth=t,n}function Me(t,e){var i=e.containerWidth,n=e.font,o=e.contentWidth;if(!i)return"";var a=ge(t,n);if(a<=i)return t;for(var r=0;;r++){if(a<=o||r>=e.maxIterations){t+=e.ellipsis;break}var s=0===r?Ie(t,o,e.ascCharWidth,e.cnCharWidth):a>0?Math.floor(t.length*o/a):0;a=ge(t=t.substr(0,s),n)}return""===t&&(t=e.placeholder),t}function Ie(t,e,i,n){for(var o=0,a=0,r=t.length;al)t="",a=[];else if(null!=u)for(var h=Se(u-(i?i[1]+i[3]:0),e,n.ellipsis,{minChar:n.minChar,placeholder:n.placeholder}),c=0,d=a.length;co&&Le(i,t.substring(o,a)),Le(i,n[2],n[1]),o=Iw.lastIndex}of)return{lines:[],width:0,height:0};k.textWidth=ge(k.text,_);var b=y.textWidth,S=null==b||"auto"===b;if("string"==typeof b&&"%"===b.charAt(b.length-1))k.percentWidth=b,u.push(k),b=0;else{if(S){b=k.textWidth;var M=y.textBackgroundColor,I=M&&M.image;I&&pe(I=ce(I))&&(b=Math.max(b,I.width*w/I.height))}var T=x?x[1]+x[3]:0;b+=T;var C=null!=d?d-m:null;null!=C&&Cl&&(i*=l/(c=i+n),n*=l/c),o+a>l&&(o*=l/(c=o+a),a*=l/c),n+o>u&&(n*=u/(c=n+o),o*=u/c),i+a>u&&(i*=u/(c=i+a),a*=u/c),t.moveTo(r+i,s),t.lineTo(r+l-n,s),0!==n&&t.arc(r+l-n,s+n,n,-Math.PI/2,0),t.lineTo(r+l,s+u-o),0!==o&&t.arc(r+l-o,s+u-o,o,0,Math.PI/2),t.lineTo(r+a,s+u),0!==a&&t.arc(r+a,s+u-a,a,Math.PI/2,Math.PI),t.lineTo(r,s+i),0!==i&&t.arc(r+i,s+i,i,Math.PI,1.5*Math.PI)}function Ne(t){return Oe(t),d(t.rich,Oe),t}function Oe(t){if(t){t.font=ke(t);var e=t.textAlign;"middle"===e&&(e="center"),t.textAlign=null==e||Aw[e]?e:"left";var i=t.textVerticalAlign||t.textBaseline;"center"===i&&(i="middle"),t.textVerticalAlign=null==i||Cw[i]?i:"top",t.textPadding&&(t.textPadding=L(t.textPadding))}}function Ee(t,e,i,n,o){n.rich?ze(t,e,i,n,o):Re(t,e,i,n,o)}function Re(t,e,i,n,o){var a=Ue(e,"font",n.font||Tw),r=n.textPadding,s=t.__textCotentBlock;s&&!t.__dirty||(s=t.__textCotentBlock=Ae(i,a,r,n.truncate));var l=s.outerHeight,u=s.lines,h=s.lineHeight,c=Ze(l,n,o),d=c.baseX,f=c.baseY,p=c.textAlign,g=c.textVerticalAlign;Ve(e,n,o,d,f);var m=_e(f,l,g),v=d,y=m,x=We(n);if(x||r){var _=ge(i,a);r&&(_+=r[1]+r[3]);var w=xe(d,_,p);x&&Fe(t,e,n,w,m,_,l),r&&(v=qe(d,p,r),y+=r[0])}Ue(e,"textAlign",p||"left"),Ue(e,"textBaseline","middle"),Ue(e,"shadowBlur",n.textShadowBlur||0),Ue(e,"shadowColor",n.textShadowColor||"transparent"),Ue(e,"shadowOffsetX",n.textShadowOffsetX||0),Ue(e,"shadowOffsetY",n.textShadowOffsetY||0),y+=h/2;var b=n.textStrokeWidth,S=Xe(n.textStroke,b),M=je(n.textFill);S&&(Ue(e,"lineWidth",b),Ue(e,"strokeStyle",S)),M&&Ue(e,"fillStyle",M);for(var I=0;I=0&&"right"===(_=b[C]).textAlign;)Ge(t,e,_,n,M,v,A,"right"),I-=_.width,A-=_.width,C--;for(D+=(a-(D-m)-(y-A)-I)/2;T<=C;)Ge(t,e,_=b[T],n,M,v,D+_.width/2,"center"),D+=_.width,T++;v+=M}}function Ve(t,e,i,n,o){if(i&&e.textRotation){var a=e.textOrigin;"center"===a?(n=i.width/2+i.x,o=i.height/2+i.y):a&&(n=a[0]+i.x,o=a[1]+i.y),t.translate(n,o),t.rotate(-e.textRotation),t.translate(-n,-o)}}function Ge(t,e,i,n,o,a,r,s){var l=n.rich[i.styleName]||{},u=i.textVerticalAlign,h=a+o/2;"top"===u?h=a+i.height/2:"bottom"===u&&(h=a+o-i.height/2),!i.isLineHolder&&We(l)&&Fe(t,e,l,"right"===s?r-i.width:"center"===s?r-i.width/2:r,h-i.height/2,i.width,i.height);var c=i.textPadding;c&&(r=qe(r,s,c),h-=i.height/2-c[2]-i.textHeight/2),Ue(e,"shadowBlur",A(l.textShadowBlur,n.textShadowBlur,0)),Ue(e,"shadowColor",l.textShadowColor||n.textShadowColor||"transparent"),Ue(e,"shadowOffsetX",A(l.textShadowOffsetX,n.textShadowOffsetX,0)),Ue(e,"shadowOffsetY",A(l.textShadowOffsetY,n.textShadowOffsetY,0)),Ue(e,"textAlign",s),Ue(e,"textBaseline","middle"),Ue(e,"font",i.font||Tw);var d=Xe(l.textStroke||n.textStroke,p),f=je(l.textFill||n.textFill),p=D(l.textStrokeWidth,n.textStrokeWidth);d&&(Ue(e,"lineWidth",p),Ue(e,"strokeStyle",d),e.strokeText(i.text,r,h)),f&&(Ue(e,"fillStyle",f),e.fillText(i.text,r,h))}function We(t){return t.textBackgroundColor||t.textBorderWidth&&t.textBorderColor}function Fe(t,e,i,n,o,a,r){var s=i.textBackgroundColor,l=i.textBorderWidth,u=i.textBorderColor,h=_(s);if(Ue(e,"shadowBlur",i.textBoxShadowBlur||0),Ue(e,"shadowColor",i.textBoxShadowColor||"transparent"),Ue(e,"shadowOffsetX",i.textBoxShadowOffsetX||0),Ue(e,"shadowOffsetY",i.textBoxShadowOffsetY||0),h||l&&u){e.beginPath();var c=i.textBorderRadius;c?Pe(e,{x:n,y:o,width:a,height:r,r:c}):e.rect(n,o,a,r),e.closePath()}if(h)Ue(e,"fillStyle",s),e.fill();else if(w(s)){var d=s.image;(d=de(d,null,t,He,s))&&pe(d)&&e.drawImage(d,n,o,a,r)}l&&u&&(Ue(e,"lineWidth",l),Ue(e,"strokeStyle",u),e.stroke())}function He(t,e){e.image=t}function Ze(t,e,i){var n=e.x||0,o=e.y||0,a=e.textAlign,r=e.textVerticalAlign;if(i){var s=e.textPosition;if(s instanceof Array)n=i.x+Ye(s[0],i.width),o=i.y+Ye(s[1],i.height);else{var l=we(s,i,e.textDistance);n=l.x,o=l.y,a=a||l.textAlign,r=r||l.textVerticalAlign}var u=e.textOffset;u&&(n+=u[0],o+=u[1])}return{baseX:n,baseY:o,textAlign:a,textVerticalAlign:r}}function Ue(t,e,i){return t[e]=dw(t,e,i),t[e]}function Xe(t,e){return null==t||e<=0||"transparent"===t||"none"===t?null:t.image||t.colorStops?"#000":t}function je(t){return null==t||"none"===t?null:t.image||t.colorStops?"#000":t}function Ye(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t}function qe(t,e,i){return"right"===e?t-i[1]:"center"===e?t+i[3]/2-i[1]/2:t+i[3]}function Ke(t,e){return null!=t&&(t||e.textBackgroundColor||e.textBorderWidth&&e.textBorderColor||e.textPadding)}function $e(t){t=t||{},nw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&"style"!==e&&(this[e]=t[e]);this.style=new pw(t.style,this),this._rect=null,this.__clipPaths=[]}function Je(t){$e.call(this,t)}function Qe(t){return parseInt(t,10)}function ti(t){return!!t&&(!!t.__builtin__||"function"==typeof t.resize&&"function"==typeof t.refresh)}function ei(t,e,i){return Pw.copy(t.getBoundingRect()),t.transform&&Pw.applyTransform(t.transform),Nw.width=e,Nw.height=i,!Pw.intersect(Nw)}function ii(t,e){if(t==e)return!1;if(!t||!e||t.length!==e.length)return!0;for(var i=0;i=0){var o="touchend"!=n?e.targetTouches[0]:e.changedTouches[0];o&&ri(t,o,e,i)}else ri(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;var a=e.button;return null==e.which&&void 0!==a&&Rw.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ui(t,e,i){Ew?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function hi(t,e,i){Ew?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}function ci(t){return t.which>1}function di(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function fi(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function pi(t){return"mousewheel"===t&&a_.browser.firefox?"DOMMouseScroll":t}function gi(t,e,i){var n=t._gestureMgr;"start"===i&&n.clear();var o=n.recognize(e,t.handler.findHover(e.zrX,e.zrY,null).target,t.dom);if("end"===i&&n.clear(),o){var a=o.type;e.gestureEvent=a,t.handler.dispatchToElement({target:o.target},a,o.event)}}function mi(t){t._touching=!0,clearTimeout(t._touchTimer),t._touchTimer=setTimeout(function(){t._touching=!1},700)}function vi(t){var e=t.pointerType;return"pen"===e||"touch"===e}function yi(t){function e(t,e){return function(){if(!e._touching)return t.apply(e,arguments)}}d(Fw,function(e){t._handlers[e]=m(Uw[e],t)}),d(Zw,function(e){t._handlers[e]=m(Uw[e],t)}),d(Ww,function(i){t._handlers[i]=e(Uw[i],t)})}function xi(t){function e(e,i){d(e,function(e){ui(t,pi(e),i._handlers[e])},i)}D_.call(this),this.dom=t,this._touching=!1,this._touchTimer,this._gestureMgr=new Vw,this._handlers={},yi(this),a_.pointerEventsSupported?e(Zw,this):(a_.touchEventsSupported&&e(Fw,this),e(Ww,this))}function _i(t,e){var i=new Kw(n_(),t,e);return qw[i.id]=i,i}function wi(t,e){Yw[t]=e}function bi(t){delete qw[t]}function Si(t){return t instanceof Array?t:null==t?[]:[t]}function Mi(t,e,i){if(t){t[e]=t[e]||{},t.emphasis=t.emphasis||{},t.emphasis[e]=t.emphasis[e]||{};for(var n=0,o=i.length;n=i.length&&i.push({option:t})}}),i}function Ai(t){var e=R();Jw(t,function(t,i){var n=t.exist;n&&e.set(n.id,t)}),Jw(t,function(t,i){var n=t.option;k(!n||null==n.id||!e.get(n.id)||e.get(n.id)===t,"id duplicates: "+(n&&n.id)),n&&null!=n.id&&e.set(n.id,t),!t.keyInfo&&(t.keyInfo={})}),Jw(t,function(t,i){var n=t.exist,o=t.option,a=t.keyInfo;if(Qw(o)){if(a.name=null!=o.name?o.name+"":n?n.name:eb+i,n)a.id=n.id;else if(null!=o.id)a.id=o.id+"";else{var r=0;do{a.id="\0"+a.name+"\0"+r++}while(e.get(a.id))}e.set(a.id,t)}})}function Ci(t){var e=t.name;return!(!e||!e.indexOf(eb))}function Li(t){return Qw(t)&&t.id&&0===(t.id+"").indexOf("\0_ec_\0")}function ki(t,e){function i(t,e,i){for(var n=0,o=t.length;n-pb&&tpb||t<-pb}function ji(t,e,i,n,o){var a=1-o;return a*a*(a*t+3*o*e)+o*o*(o*n+3*a*i)}function Yi(t,e,i,n,o){var a=1-o;return 3*(((e-t)*a+2*(i-e)*o)*a+(n-i)*o*o)}function qi(t,e,i,n,o,a){var r=n+3*(e-i)-t,s=3*(i-2*e+t),l=3*(e-t),u=t-o,h=s*s-3*r*l,c=s*l-9*r*u,d=l*l-3*s*u,f=0;if(Ui(h)&&Ui(c))Ui(s)?a[0]=0:(M=-l/s)>=0&&M<=1&&(a[f++]=M);else{var p=c*c-4*h*d;if(Ui(p)){var g=c/h,m=-g/2;(M=-s/r+g)>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m)}else if(p>0){var v=fb(p),y=h*s+1.5*r*(-c+v),x=h*s+1.5*r*(-c-v);(M=(-s-((y=y<0?-db(-y,vb):db(y,vb))+(x=x<0?-db(-x,vb):db(x,vb))))/(3*r))>=0&&M<=1&&(a[f++]=M)}else{var _=(2*h*s-3*r*c)/(2*fb(h*h*h)),w=Math.acos(_)/3,b=fb(h),S=Math.cos(w),M=(-s-2*b*S)/(3*r),m=(-s+b*(S+mb*Math.sin(w)))/(3*r),I=(-s+b*(S-mb*Math.sin(w)))/(3*r);M>=0&&M<=1&&(a[f++]=M),m>=0&&m<=1&&(a[f++]=m),I>=0&&I<=1&&(a[f++]=I)}}return f}function Ki(t,e,i,n,o){var a=6*i-12*e+6*t,r=9*e+3*n-3*t-9*i,s=3*e-3*t,l=0;if(Ui(r))Xi(a)&&(c=-s/a)>=0&&c<=1&&(o[l++]=c);else{var u=a*a-4*r*s;if(Ui(u))o[0]=-a/(2*r);else if(u>0){var h=fb(u),c=(-a+h)/(2*r),d=(-a-h)/(2*r);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function $i(t,e,i,n,o,a){var r=(e-t)*o+t,s=(i-e)*o+e,l=(n-i)*o+i,u=(s-r)*o+r,h=(l-s)*o+s,c=(h-u)*o+u;a[0]=t,a[1]=r,a[2]=u,a[3]=c,a[4]=c,a[5]=h,a[6]=l,a[7]=n}function Ji(t,e,i,n,o,a,r,s,l,u,h){var c,d,f,p,g,m=.005,v=1/0;yb[0]=l,yb[1]=u;for(var y=0;y<1;y+=.05)xb[0]=ji(t,i,o,r,y),xb[1]=ji(e,n,a,s,y),(p=M_(yb,xb))=0&&p=0&&c<=1&&(o[l++]=c);else{var u=r*r-4*a*s;if(Ui(u))(c=-r/(2*a))>=0&&c<=1&&(o[l++]=c);else if(u>0){var h=fb(u),c=(-r+h)/(2*a),d=(-r-h)/(2*a);c>=0&&c<=1&&(o[l++]=c),d>=0&&d<=1&&(o[l++]=d)}}return l}function nn(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function on(t,e,i,n,o){var a=(e-t)*n+t,r=(i-e)*n+e,s=(r-a)*n+a;o[0]=t,o[1]=a,o[2]=s,o[3]=s,o[4]=r,o[5]=i}function an(t,e,i,n,o,a,r,s,l){var u,h=.005,c=1/0;yb[0]=r,yb[1]=s;for(var d=0;d<1;d+=.05)xb[0]=Qi(t,i,o,d),xb[1]=Qi(e,n,a,d),(m=M_(yb,xb))=0&&m1e-4)return s[0]=t-i,s[1]=e-n,l[0]=t+i,void(l[1]=e+n);if(Tb[0]=Mb(o)*i+t,Tb[1]=Sb(o)*n+e,Db[0]=Mb(a)*i+t,Db[1]=Sb(a)*n+e,u(s,Tb,Db),h(l,Tb,Db),(o%=Ib)<0&&(o+=Ib),(a%=Ib)<0&&(a+=Ib),o>a&&!r?a+=Ib:oo&&(Ab[0]=Mb(f)*i+t,Ab[1]=Sb(f)*n+e,u(s,Ab,s),h(l,Ab,l))}function cn(t,e,i,n,o,a,r){if(0===o)return!1;var s=o,l=0,u=t;if(r>e+s&&r>n+s||rt+s&&a>i+s||ae+c&&h>n+c&&h>a+c&&h>s+c||ht+c&&u>i+c&&u>o+c&&u>r+c||ue+u&&l>n+u&&l>a+u||lt+u&&s>i+u&&s>o+u||si||h+uo&&(o+=Ub);var d=Math.atan2(l,s);return d<0&&(d+=Ub),d>=n&&d<=o||d+Ub>=n&&d+Ub<=o}function mn(t,e,i,n,o,a){if(a>e&&a>n||ao?r:0}function vn(t,e){return Math.abs(t-e)e&&u>n&&u>a&&u>s||u1&&yn(),c=ji(e,n,a,s,Kb[0]),p>1&&(d=ji(e,n,a,s,Kb[1]))),2==p?me&&s>n&&s>a||s=0&&u<=1){for(var h=0,c=Qi(e,n,a,u),d=0;di||s<-i)return 0;u=Math.sqrt(i*i-s*s);qb[0]=-u,qb[1]=u;var l=Math.abs(n-o);if(l<1e-4)return 0;if(l%jb<1e-4){n=0,o=jb;p=a?1:-1;return r>=qb[0]+t&&r<=qb[1]+t?p:0}if(a){var u=n;n=pn(o),o=pn(u)}else n=pn(n),o=pn(o);n>o&&(o+=jb);for(var h=0,c=0;c<2;c++){var d=qb[c];if(d+t>r){var f=Math.atan2(s,d),p=a?1:-1;f<0&&(f=jb+f),(f>=n&&f<=o||f+jb>=n&&f+jb<=o)&&(f>Math.PI/2&&f<1.5*Math.PI&&(p=-p),h+=p)}}return h}function bn(t,e,i,n,o){for(var a=0,r=0,s=0,l=0,u=0,h=0;h1&&(i||(a+=mn(r,s,l,u,n,o))),1==h&&(l=r=t[h],u=s=t[h+1]),c){case Xb.M:r=l=t[h++],s=u=t[h++];break;case Xb.L:if(i){if(cn(r,s,t[h],t[h+1],e,n,o))return!0}else a+=mn(r,s,t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case Xb.C:if(i){if(dn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=xn(r,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case Xb.Q:if(i){if(fn(r,s,t[h++],t[h++],t[h],t[h+1],e,n,o))return!0}else a+=_n(r,s,t[h++],t[h++],t[h],t[h+1],n,o)||0;r=t[h++],s=t[h++];break;case Xb.A:var d=t[h++],f=t[h++],p=t[h++],g=t[h++],m=t[h++],v=t[h++],y=(t[h++],1-t[h++]),x=Math.cos(m)*p+d,_=Math.sin(m)*g+f;h>1?a+=mn(r,s,x,_,n,o):(l=x,u=_);var w=(n-d)*g/p+d;if(i){if(gn(d,f,g,m,m+v,y,e,w,o))return!0}else a+=wn(d,f,g,m,m+v,y,w,o);r=Math.cos(m+v)*p+d,s=Math.sin(m+v)*g+f;break;case Xb.R:l=r=t[h++],u=s=t[h++];var x=l+t[h++],_=u+t[h++];if(i){if(cn(l,u,x,u,e,n,o)||cn(x,u,x,_,e,n,o)||cn(x,_,l,_,e,n,o)||cn(l,_,l,u,e,n,o))return!0}else a+=mn(x,u,x,_,n,o),a+=mn(l,_,l,u,n,o);break;case Xb.Z:if(i){if(cn(r,s,l,u,e,n,o))return!0}else a+=mn(r,s,l,u,n,o);r=l,s=u}}return i||vn(s,u)||(a+=mn(r,s,l,u,n,o)||0),0!==a}function Sn(t,e,i){return bn(t,0,!1,e,i)}function Mn(t,e,i,n){return bn(t,e,!0,i,n)}function In(t){$e.call(this,t),this.path=null}function Tn(t,e,i,n,o,a,r,s,l,u,h){var c=l*(uS/180),d=lS(c)*(t-i)/2+sS(c)*(e-n)/2,f=-1*sS(c)*(t-i)/2+lS(c)*(e-n)/2,p=d*d/(r*r)+f*f/(s*s);p>1&&(r*=rS(p),s*=rS(p));var g=(o===a?-1:1)*rS((r*r*(s*s)-r*r*(f*f)-s*s*(d*d))/(r*r*(f*f)+s*s*(d*d)))||0,m=g*r*f/s,v=g*-s*d/r,y=(t+i)/2+lS(c)*m-sS(c)*v,x=(e+n)/2+sS(c)*m+lS(c)*v,_=dS([1,0],[(d-m)/r,(f-v)/s]),w=[(d-m)/r,(f-v)/s],b=[(-1*d-m)/r,(-1*f-v)/s],S=dS(w,b);cS(w,b)<=-1&&(S=uS),cS(w,b)>=1&&(S=0),0===a&&S>0&&(S-=2*uS),1===a&&S<0&&(S+=2*uS),h.addData(u,y,x,r,s,_,S,c,a)}function Dn(t){if(!t)return[];var e,i=t.replace(/-/g," -").replace(/ /g," ").replace(/ /g,",").replace(/,,/g,",");for(e=0;e0&&""===f[0]&&f.shift();for(var p=0;p=2){if(o&&"spline"!==o){var a=_S(n,o,i,e.smoothConstraint);t.moveTo(n[0][0],n[0][1]);for(var r=n.length,s=0;s<(i?r:r-1);s++){var l=a[2*s],u=a[2*s+1],h=n[(s+1)%r];t.bezierCurveTo(l[0],l[1],u[0],u[1],h[0],h[1])}}else{"spline"===o&&(n=xS(n,i)),t.moveTo(n[0][0],n[0][1]);for(var s=1,c=n.length;s=0)&&(n={textFill:null,textStroke:t.textStroke,textStrokeWidth:t.textStrokeWidth},t.textFill="#fff",null==t.textStroke&&(t.textStroke=i.autoColor,null==t.textStrokeWidth&&(t.textStrokeWidth=2))),n}function uo(t){var e=t.insideRollback;e&&(t.textFill=e.textFill,t.textStroke=e.textStroke,t.textStrokeWidth=e.textStrokeWidth)}function ho(t,e){var i=e||e.getModel("textStyle");return P([t.fontStyle||i&&i.getShallow("fontStyle")||"",t.fontWeight||i&&i.getShallow("fontWeight")||"",(t.fontSize||i&&i.getShallow("fontSize")||12)+"px",t.fontFamily||i&&i.getShallow("fontFamily")||"sans-serif"].join(" "))}function co(t,e,i,n,o,a){if("function"==typeof o&&(a=o,o=null),n&&n.isAnimationEnabled()){var r=t?"Update":"",s=n.getShallow("animationDuration"+r),l=n.getShallow("animationEasing"+r),u=n.getShallow("animationDelay"+r);"function"==typeof u&&(u=u(o,n.getAnimationDelayParams?n.getAnimationDelayParams(e,o):null)),"function"==typeof s&&(s=s(o)),s>0?e.animateTo(i,s,u||0,l,a,!!a):(e.stopAnimation(),e.attr(i),a&&a())}else e.stopAnimation(),e.attr(i),a&&a()}function fo(t,e,i,n,o){co(!0,t,e,i,n,o)}function po(t,e,i,n,o){co(!1,t,e,i,n,o)}function go(t,e){for(var i=lt([]);t&&t!==e;)ht(i,t.getLocalTransform(),i),t=t.parent;return i}function mo(t,e,i){return e&&!c(e)&&(e=E_.getLocalTransform(e)),i&&(e=pt([],e)),Q([],t,e)}function vo(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),o=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-o:"bottom"===t?o:0];return a=mo(a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?"bottom":"top"}function yo(t,e,i,n){function o(t){var e={position:W(t.position),rotation:t.rotation};return t.shape&&(e.shape=a({},t.shape)),e}if(t&&e){var r=function(t){var e={};return t.traverse(function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}(t);e.traverse(function(t){if(!t.isGroup&&t.anid){var e=r[t.anid];if(e){var n=o(t);t.attr(o(e)),fo(t,n,i,t.dataIndex)}}})}}function xo(t,e){return f(t,function(t){var i=t[0];i=OS(i,e.x),i=ES(i,e.x+e.width);var n=t[1];return n=OS(n,e.y),n=ES(n,e.y+e.height),[i,n]})}function _o(t,e,i){var n=(e=a({rectHover:!0},e)).style={strokeNoScale:!0};if(i=i||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(n.image=t.slice(8),r(n,i),new Je(e)):Rn(t.replace("path://",""),e,i,"center")}function wo(t,e,i){this.parentModel=e,this.ecModel=i,this.option=t}function bo(t,e,i){for(var n=0;n0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/o*a+i[0]}function Do(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?Io(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t}function Ao(t,e,i){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),i?t:+t}function Co(t){return t.sort(function(t,e){return t-e}),t}function Lo(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}function ko(t){var e=t.toString(),i=e.indexOf("e");if(i>0){var n=+e.slice(i+1);return n<0?-n:0}var o=e.indexOf(".");return o<0?0:e.length-1-o}function Po(t,e){var i=Math.log,n=Math.LN10,o=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n),r=Math.min(Math.max(-o+a,0),20);return isFinite(r)?r:20}function No(t,e,i){if(!t[e])return 0;var n=p(t,function(t,e){return t+(isNaN(e)?0:e)},0);if(0===n)return 0;for(var o=Math.pow(10,i),a=f(t,function(t){return(isNaN(t)?0:t)/n*o*100}),r=100*o,s=f(a,function(t){return Math.floor(t)}),l=p(s,function(t,e){return t+e},0),u=f(a,function(t,e){return t-s[e]});lh&&(h=u[d],c=d);++s[c],u[c]=0,++l}return s[e]/o}function Oo(t){var e=2*Math.PI;return(t%e+e)%e}function Eo(t){return t>-XS&&t=-20?+t.toFixed(n<0?-n:0):t}function Go(t){function e(t,i,n){return t.interval[n]=0}function Fo(t){return isNaN(t)?"-":(t=(t+"").split("."))[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t.length>1?"."+t[1]:"")}function Ho(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}function Zo(t){return null==t?"":(t+"").replace($S,function(t,e){return JS[e]})}function Uo(t,e,i){y(e)||(e=[e]);var n=e.length;if(!n)return"";for(var o=e[0].$vars||[],a=0;a':'':""}function Yo(t,e){return t+="","0000".substr(0,e-t.length)+t}function qo(t,e,i){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var n=Ro(e),o=i?"UTC":"",a=n["get"+o+"FullYear"](),r=n["get"+o+"Month"]()+1,s=n["get"+o+"Date"](),l=n["get"+o+"Hours"](),u=n["get"+o+"Minutes"](),h=n["get"+o+"Seconds"](),c=n["get"+o+"Milliseconds"]();return t=t.replace("MM",Yo(r,2)).replace("M",r).replace("yyyy",a).replace("yy",a%100).replace("dd",Yo(s,2)).replace("d",s).replace("hh",Yo(l,2)).replace("h",l).replace("mm",Yo(u,2)).replace("m",u).replace("ss",Yo(h,2)).replace("s",h).replace("SSS",Yo(c,3))}function Ko(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t}function $o(t,e,i,n,o){var a=0,r=0;null==n&&(n=1/0),null==o&&(o=1/0);var s=0;e.eachChild(function(l,u){var h,c,d=l.position,f=l.getBoundingRect(),p=e.childAt(u+1),g=p&&p.getBoundingRect();if("horizontal"===t){var m=f.width+(g?-g.x+f.x:0);(h=a+m)>n||l.newline?(a=0,h=m,r+=s+i,s=f.height):s=Math.max(s,f.height)}else{var v=f.height+(g?-g.y+f.y:0);(c=r+v)>o||l.newline?(a+=s+i,r=0,c=v,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=a,d[1]=r,"horizontal"===t?a=h+i:r=c+i)})}function Jo(t,e,i){var n=e.width,o=e.height,a=Do(t.x,n),r=Do(t.y,o),s=Do(t.x2,n),l=Do(t.y2,o);return(isNaN(a)||isNaN(parseFloat(t.x)))&&(a=0),(isNaN(s)||isNaN(parseFloat(t.x2)))&&(s=n),(isNaN(r)||isNaN(parseFloat(t.y)))&&(r=0),(isNaN(l)||isNaN(parseFloat(t.y2)))&&(l=o),i=KS(i||0),{width:Math.max(s-a-i[1]-i[3],0),height:Math.max(l-r-i[0]-i[2],0)}}function Qo(t,e,i){i=KS(i||0);var n=e.width,o=e.height,a=Do(t.left,n),r=Do(t.top,o),s=Do(t.right,n),l=Do(t.bottom,o),u=Do(t.width,n),h=Do(t.height,o),c=i[2]+i[0],d=i[1]+i[3],f=t.aspect;switch(isNaN(u)&&(u=n-s-d-a),isNaN(h)&&(h=o-l-c-r),null!=f&&(isNaN(u)&&isNaN(h)&&(f>n/o?u=.8*n:h=.8*o),isNaN(u)&&(u=f*h),isNaN(h)&&(h=u/f)),isNaN(a)&&(a=n-s-u-d),isNaN(r)&&(r=o-l-h-c),t.left||t.right){case"center":a=n/2-u/2-i[3];break;case"right":a=n-u-d}switch(t.top||t.bottom){case"middle":case"center":r=o/2-h/2-i[0];break;case"bottom":r=o-h-c}a=a||0,r=r||0,isNaN(u)&&(u=n-d-a-(s||0)),isNaN(h)&&(h=o-c-r-(l||0));var p=new $t(a+i[3],r+i[0],u,h);return p.margin=i,p}function ta(t,e,i,n,o){var a=!o||!o.hv||o.hv[0],s=!o||!o.hv||o.hv[1],l=o&&o.boundingMode||"all";if(a||s){var u;if("raw"===l)u="group"===t.type?new $t(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(u=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(u=u.clone()).applyTransform(h)}e=Qo(r({width:u.width,height:u.height},e),i,n);var c=t.position,d=a?e.x-u.x:0,f=s?e.y-u.y:0;t.attr("position","raw"===l?[d,f]:[c[0]+d,c[1]+f])}}function ea(t,e){return null!=t[rM[e][0]]||null!=t[rM[e][1]]&&null!=t[rM[e][2]]}function ia(t,e,i){function n(i,n){var r={},l=0,u={},h=0;if(oM(i,function(e){u[e]=t[e]}),oM(i,function(t){o(e,t)&&(r[t]=u[t]=e[t]),a(r,t)&&l++,a(u,t)&&h++}),s[n])return a(e,i[1])?u[i[2]]=null:a(e,i[2])&&(u[i[1]]=null),u;if(2!==h&&l){if(l>=2)return r;for(var c=0;ce)return t[n];return t[i-1]}function ra(t){var e=t.get("coordinateSystem"),i={coordSysName:e,coordSysDims:[],axisMap:R(),categoryAxisMap:R()},n=gM[e];if(n)return n(t,i,i.axisMap,i.categoryAxisMap),i}function sa(t){return"category"===t.get("type")}function la(t){this.fromDataset=t.fromDataset,this.data=t.data||(t.sourceFormat===xM?{}:[]),this.sourceFormat=t.sourceFormat||_M,this.seriesLayoutBy=t.seriesLayoutBy||bM,this.dimensionsDefine=t.dimensionsDefine,this.encodeDefine=t.encodeDefine&&R(t.encodeDefine),this.startIndex=t.startIndex||0,this.dimensionsDetectCount=t.dimensionsDetectCount}function ua(t){var e=t.option.source,i=_M;if(S(e))i=wM;else if(y(e))for(var n=0,o=e.length;n=e:"max"===i?t<=e:t===e}function Oa(t,e){return t.join(",")===e.join(",")}function Ea(t,e){CM(e=e||{},function(e,i){if(null!=e){var n=t[i];if(hM.hasClass(i)){e=Si(e);var o=Di(n=Si(n),e);t[i]=kM(o,function(t){return t.option&&t.exist?PM(t.exist,t.option,!0):t.exist||t.option})}else t[i]=PM(n,e,!0)}})}function Ra(t){var e=t&&t.itemStyle;if(e)for(var i=0,o=RM.length;i=0;p--){var g=t[p];if(s||(d=g.data.rawIndexOf(g.stackedByDimension,c)),d>=0){var m=g.data.getByRawIndex(g.stackResultDimension,d);if(h>=0&&m>0||h<=0&&m<0){h+=m,f=m;break}}}return n[0]=h,n[1]=f,n});r.hostModel.setData(l),e.data=l})}function Ya(t,e){la.isInstance(t)||(t=la.seriesDataToSource(t)),this._source=t;var i=this._data=t.data,n=t.sourceFormat;n===wM&&(this._offset=0,this._dimSize=e,this._data=i),a(this,FM[n===vM?n+"_"+t.seriesLayoutBy:n])}function qa(){return this._data.length}function Ka(t){return this._data[t]}function $a(t){for(var e=0;ee.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function dr(t,e){d(t.CHANGABLE_METHODS,function(i){t.wrapMethod(i,v(fr,e))})}function fr(t){var e=pr(t);e&&e.setOutputEnd(this.count())}function pr(t){var e=(t.ecModel||{}).scheduler,i=e&&e.getPipeline(t.uid);if(i){var n=i.currentTask;if(n){var o=n.agentStubMap;o&&(n=o.get(t.uid))}return n}}function gr(){this.group=new sw,this.uid=Mo("viewChart"),this.renderTask=nr({plan:yr,reset:xr}),this.renderTask.context={view:this}}function mr(t,e){if(t&&(t.trigger(e),"group"===t.type))for(var i=0;i=0?n():c=setTimeout(n,-a),u=o};return d.clear=function(){c&&(clearTimeout(c),c=null)},d.debounceNextCall=function(t){l=t},d}function wr(t,e,i,n){var o=t[e];if(o){var a=o[oI]||o,r=o[rI];if(o[aI]!==i||r!==n){if(null==i||!n)return t[e]=a;(o=t[e]=_r(a,i,"debounce"===n))[oI]=a,o[rI]=n,o[aI]=i}return o}}function br(t,e){var i=t[e];i&&i[oI]&&(t[e]=i[oI])}function Sr(t,e,i,n){this.ecInstance=t,this.api=e,this.unfinished;var i=this._dataProcessorHandlers=i.slice(),n=this._visualHandlers=n.slice();this._allHandlers=i.concat(n),this._stageTaskMap=R()}function Mr(t,e,i,n,o){function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}o=o||{};var r;d(e,function(e,s){if(!o.visualType||o.visualType===e.visualType){var l=t._stageTaskMap.get(e.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,d=h.agentStubMap;d.each(function(t){a(o,t)&&(t.dirty(),c=!0)}),c&&h.dirty(),dI(h,n);var f=t.getPerformArgs(h,o.block);d.each(function(t){t.perform(f)}),r|=h.perform(f)}else u&&u.each(function(s,l){a(o,s)&&s.dirty();var u=t.getPerformArgs(s,o.block);u.skip=!e.performRawSeries&&i.isSeriesFiltered(s.context.model),dI(s,n),r|=s.perform(u)})}}),t.unfinished|=r}function Ir(t,e,i,n,o){function a(i){var a=i.uid,s=r.get(a)||r.set(a,nr({plan:kr,reset:Pr,count:Or}));s.context={model:i,ecModel:n,api:o,useClearVisual:e.isVisual&&!e.isLayout,plan:e.plan,reset:e.reset,scheduler:t},Er(t,i,s)}var r=i.seriesTaskMap||(i.seriesTaskMap=R()),s=e.seriesType,l=e.getTargetSeries;e.createOnAllSeries?n.eachRawSeries(a):s?n.eachRawSeriesByType(s,a):l&&l(n,o).each(a);var u=t._pipelineMap;r.each(function(t,e){u.get(e)||(t.dispose(),r.removeKey(e))})}function Tr(t,e,i,n,o){function a(e){var i=e.uid,n=s.get(i);n||(n=s.set(i,nr({reset:Ar,onDirty:Lr})),r.dirty()),n.context={model:e,overallProgress:h,modifyOutputEnd:c},n.agent=r,n.__block=h,Er(t,e,n)}var r=i.overallTask=i.overallTask||nr({reset:Dr});r.context={ecModel:n,api:o,overallReset:e.overallReset,scheduler:t};var s=r.agentStubMap=r.agentStubMap||R(),l=e.seriesType,u=e.getTargetSeries,h=!0,c=e.modifyOutputEnd;l?n.eachRawSeriesByType(l,a):u?u(n,o).each(a):(h=!1,d(n.getSeries(),a));var f=t._pipelineMap;s.each(function(t,e){f.get(e)||(t.dispose(),r.dirty(),s.removeKey(e))})}function Dr(t){t.overallReset(t.ecModel,t.api,t.payload)}function Ar(t,e){return t.overallProgress&&Cr}function Cr(){this.agent.dirty(),this.getDownstream().dirty()}function Lr(){this.agent&&this.agent.dirty()}function kr(t){return t.plan&&t.plan(t.model,t.ecModel,t.api,t.payload)}function Pr(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=Si(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?f(e,function(t,e){return Nr(e)}):fI}function Nr(t){return function(e,i){var n=i.data,o=i.resetDefines[t];if(o&&o.dataEach)for(var a=e.start;ae.get("hoverLayerThreshold")&&!a_.node&&i.traverse(function(t){t.isGroup||(t.useHoverLayer=!0)})}function is(t,e){var i=t.get("blendMode")||null;e.group.traverse(function(t){t.isGroup||t.style.blend!==i&&t.setStyle("blend",i),t.eachPendingDisplayable&&t.eachPendingDisplayable(function(t){t.setStyle("blend",i)})})}function ns(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function os(t){var e=t._coordSysMgr;return a(new Aa(t),{getCoordinateSystems:m(e.getCoordinateSystems,e),getComponentByElement:function(e){for(;e;){var i=e.__ecComponentInfo;if(null!=i)return t._model.getComponent(i.mainType,i.index);e=e.parent}}})}function as(t){function e(t,e){for(var n=0;n65535?nT:oT}function Cs(t){var e=t.constructor;return e===Array?t.slice():new e(t)}function Ls(t,e){d(aT.concat(e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods,d(rT,function(n){t[n]=i(e[n])}),t._calculationInfo=a(e._calculationInfo)}function ks(t){var e=t._invertedIndicesMap;d(e,function(i,n){var o=t._dimensionInfos[n].ordinalMeta;if(o){i=e[n]=new nT(o.categories.length);for(a=0;a=0?this._indices[t]:-1}function Es(t,e){var i=t._idList[e];return null==i&&(i=Ps(t,t._idDimIdx,e)),null==i&&(i=eT+e),i}function Rs(t){return y(t)||(t=[t]),t}function zs(t,e){var i=t.dimensions,n=new sT(f(i,t.getDimensionInfo,t),t.hostModel);Ls(n,t);for(var o=n._storage={},a=t._storage,r=0;r=0?(o[s]=Bs(a[s]),n._rawExtent[s]=Vs(),n._extent[s]=null):o[s]=a[s])}return n}function Bs(t){for(var e=new Array(t.length),i=0;in&&(r=o.interval=n);var s=o.intervalPrecision=tl(r);return il(o.niceTickExtent=[pT(Math.ceil(t[0]/r)*r,s),pT(Math.floor(t[1]/r)*r,s)],t),o}function tl(t){return ko(t)+2}function el(t,e,i){t[e]=Math.max(Math.min(t[e],i[1]),i[0])}function il(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),el(t,0,e),el(t,1,e),t[0]>t[1]&&(t[0]=t[1])}function nl(t,e,i,n){var o=[];if(!t)return o;e[0]1e4)return[];return e[1]>(o.length?o[o.length-1]:i[1])&&o.push(e[1]),o}function ol(t){return t.get("stack")||vT+t.seriesIndex}function al(t){return t.dim+t.index}function rl(t){var e=[],i=t.axis;if("category"===i.type){for(var n=i.getBandWidth(),o=0;o=0?"p":"n",b=m;p&&(o[r][_]||(o[r][_]={p:m,n:m}),b=o[r][_][w]);var S,M,I,T;if(g)S=b,M=(D=i.dataToPoint([x,_]))[1]+l,I=D[0]-m,T=u,Math.abs(I)=0||i?e.toGlobalCoord(e.dataToCoord(0)):e.getGlobalExtent()[0]}function gl(t,e){return CT(t,AT(e))}function ml(t,e){var i,n,o,a=t.type,r=e.getMin(),s=e.getMax(),l=null!=r,u=null!=s,h=t.getExtent();"ordinal"===a?i=e.getCategories().length:(y(n=e.get("boundaryGap"))||(n=[n||0,n||0]),"boolean"==typeof n[0]&&(n=[0,0]),n[0]=Do(n[0],1),n[1]=Do(n[1],1),o=h[1]-h[0]||Math.abs(h[0])),null==r&&(r="ordinal"===a?i?0:NaN:h[0]-n[0]*o),null==s&&(s="ordinal"===a?i?i-1:NaN:h[1]+n[1]*o),"dataMin"===r?r=h[0]:"function"==typeof r&&(r=r({min:h[0],max:h[1]})),"dataMax"===s?s=h[1]:"function"==typeof s&&(s=s({min:h[0],max:h[1]})),(null==r||!isFinite(r))&&(r=NaN),(null==s||!isFinite(s))&&(s=NaN),t.setBlank(I(r)||I(s)||"ordinal"===a&&!t.getOrdinalMeta().categories.length),e.getNeedCrossZero()&&(r>0&&s>0&&!l&&(r=0),r<0&&s<0&&!u&&(s=0));var c=e.ecModel;if(c&&"time"===a){var f,p=sl("bar",c);if(d(p,function(t){f|=t.getBaseAxis()===e.axis}),f){var g=ll(p),m=vl(r,s,e,g);r=m.min,s=m.max}}return[r,s]}function vl(t,e,i,n){var o=i.axis.getExtent(),a=o[1]-o[0],r=hl(n,i.axis);if(void 0===r)return{min:t,max:e};var s=1/0;d(r,function(t){s=Math.min(t.offset,s)});var l=-1/0;d(r,function(t){l=Math.max(t.offset+t.width,l)}),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/a)-h;return e+=c*(l/u),t-=c*(s/u),{min:t,max:e}}function yl(t,e){var i=ml(t,e),n=null!=e.getMin(),o=null!=e.getMax(),a=e.get("splitNumber");"log"===t.type&&(t.base=e.get("logBase"));var r=t.type;t.setExtent(i[0],i[1]),t.niceExtent({splitNumber:a,fixMin:n,fixMax:o,minInterval:"interval"===r||"time"===r?e.get("minInterval"):null,maxInterval:"interval"===r||"time"===r?e.get("maxInterval"):null});var s=e.get("interval");null!=s&&t.setInterval&&t.setInterval(s)}function xl(t,e){if(e=e||t.get("type"))switch(e){case"category":return new fT(t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),[1/0,-1/0]);case"value":return new mT;default:return(qs.getClass(e)||mT).create(t)}}function _l(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(i>0&&n>0||i<0&&n<0)}function wl(t){var e=t.getLabelModel().get("formatter"),i="category"===t.type?t.scale.getExtent()[0]:null;return"string"==typeof e?e=function(t){return function(e){return t.replace("{value}",null!=e?e:"")}}(e):"function"==typeof e?function(n,o){return null!=i&&(o=n-i),e(bl(t,n),o)}:function(e){return t.scale.getLabel(e)}}function bl(t,e){return"category"===t.type?t.scale.getLabel(e):e}function Sl(t){var e=t.model,i=t.scale;if(e.get("axisLabel.show")&&!i.isBlank()){var n,o,a="category"===t.type,r=i.getExtent();o=a?i.count():(n=i.getTicks()).length;var s,l=t.getLabelModel(),u=wl(t),h=1;o>40&&(h=Math.ceil(o/40));for(var c=0;c>1^-(1&s),l=l>>1^-(1&l),o=s+=o,a=l+=a,n.push([s/i,l/i])}return n}function Pl(t){return"category"===t.type?Ol(t):zl(t)}function Nl(t,e){return"category"===t.type?Rl(t,e):{ticks:t.scale.getTicks()}}function Ol(t){var e=t.getLabelModel(),i=El(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:i.labelCategoryInterval}:i}function El(t,e){var i=Bl(t,"labels"),n=Xl(e),o=Vl(i,n);if(o)return o;var a,r;return a=x(n)?Ul(t,n):Zl(t,r="auto"===n?Wl(t):n),Gl(i,n,{labels:a,labelCategoryInterval:r})}function Rl(t,e){var i=Bl(t,"ticks"),n=Xl(e),o=Vl(i,n);if(o)return o;var a,r;if(e.get("show")&&!t.scale.isBlank()||(a=[]),x(n))a=Ul(t,n,!0);else if("auto"===n){var s=El(t,t.getLabelModel());r=s.labelCategoryInterval,a=f(s.labels,function(t){return t.tickValue})}else a=Zl(t,r=n,!0);return Gl(i,n,{ticks:a,tickCategoryInterval:r})}function zl(t){var e=t.scale.getTicks(),i=wl(t);return{labels:f(e,function(e,n){return{formattedLabel:i(e,n),rawLabel:t.scale.getLabel(e),tickValue:e}})}}function Bl(t,e){return jT(t)[e]||(jT(t)[e]=[])}function Vl(t,e){for(var i=0;i40&&(s=Math.max(1,Math.floor(r/40)));for(var l=a[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(n)),c=Math.abs(u*Math.sin(n)),d=0,f=0;l<=a[1];l+=s){var p=0,g=0,m=me(i(l),e.font,"center","top");p=1.3*m.width,g=1.3*m.height,d=Math.max(d,p,7),f=Math.max(f,g,7)}var v=d/h,y=f/c;isNaN(v)&&(v=1/0),isNaN(y)&&(y=1/0);var x=Math.max(0,Math.floor(Math.min(v,y))),_=jT(t.model),w=_.lastAutoInterval,b=_.lastTickCount;return null!=w&&null!=b&&Math.abs(w-x)<=1&&Math.abs(b-r)<=1&&w>x?x=w:(_.lastTickCount=r,_.lastAutoInterval=x),x}function Hl(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}function Zl(t,e,i){function n(t){l.push(i?t:{formattedLabel:o(t),rawLabel:a.getLabel(t),tickValue:t})}var o=wl(t),a=t.scale,r=a.getExtent(),s=t.getLabelModel(),l=[],u=Math.max((e||0)+1,1),h=r[0],c=a.count();0!==h&&u>1&&c/u>2&&(h=Math.round(Math.ceil(h/u)*u));var d={min:s.get("showMinLabel"),max:s.get("showMaxLabel")};d.min&&h!==r[0]&&n(r[0]);for(var f=h;f<=r[1];f+=u)n(f);return d.max&&f!==r[1]&&n(r[1]),l}function Ul(t,e,i){var n=t.scale,o=wl(t),a=[];return d(n.getTicks(),function(t){var r=n.getLabel(t);e(t,r)&&a.push(i?t:{formattedLabel:o(t),rawLabel:r,tickValue:t})}),a}function Xl(t){var e=t.get("interval");return null==e?"auto":e}function jl(t,e){var i=(t[1]-t[0])/e/2;t[0]+=i,t[1]-=i}function Yl(t,e,i,n,o){function a(t,e){return h?t>e:t0&&(t.coord-=u/(2*(e+1)))}),s={coord:e[r-1].coord+u},e.push(s)}var h=l[0]>l[1];a(e[0].coord,l[0])&&(o?e[0].coord=l[0]:e.shift()),o&&a(l[0],e[0].coord)&&e.unshift({coord:l[0]}),a(l[1],s.coord)&&(o?s.coord=l[1]:e.pop()),o&&a(s.coord,l[1])&&e.push({coord:l[1]})}}function ql(t,e){var i=t.mapDimension("defaultedLabel",!0),n=i.length;if(1===n)return er(t,e,i[0]);if(n){for(var o=[],a=0;a0?i=n[0]:n[1]<0&&(i=n[1]),i}function au(t,e,i,n){var o=NaN;t.stacked&&(o=i.get(i.getCalculationInfo("stackedOverDimension"),n)),isNaN(o)&&(o=t.valueStart);var a=t.baseDataOffset,r=[];return r[a]=i.get(t.baseDim,n),r[1-a]=o,e.dataToPoint(r)}function ru(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}function su(t){return isNaN(t[0])||isNaN(t[1])}function lu(t,e,i,n,o,a,r,s,l,u,h){return"none"!==u&&u?uu.apply(this,arguments):hu.apply(this,arguments)}function uu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(su(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]);else if(l>0){var g=e[c],m="y"===u?1:0,v=(p[m]-g[m])*l;uD(cD,g),cD[m]=g[m]+v,uD(dD,p),dD[m]=p[m]-v,t.bezierCurveTo(cD[0],cD[1],dD[0],dD[1],p[0],p[1])}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function hu(t,e,i,n,o,a,r,s,l,u,h){for(var c=0,d=i,f=0;f=o||d<0)break;if(su(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]),uD(cD,p);else if(l>0){var g=d+a,m=e[g];if(h)for(;m&&su(e[g]);)m=e[g+=a];var v=.5,y=e[c];if(!(m=e[g])||su(m))uD(dD,p);else{su(m)&&!h&&(m=p),U(hD,m,y);var x,_;if("x"===u||"y"===u){var w="x"===u?0:1;x=Math.abs(p[w]-y[w]),_=Math.abs(p[w]-m[w])}else x=S_(p,y),_=S_(p,m);lD(dD,p,hD,-l*(1-(v=_/(_+x))))}rD(cD,cD,s),sD(cD,cD,r),rD(dD,dD,s),sD(dD,dD,r),t.bezierCurveTo(cD[0],cD[1],dD[0],dD[1],p[0],p[1]),lD(cD,p,hD,l*v)}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function cu(t,e){var i=[1/0,1/0],n=[-1/0,-1/0];if(e)for(var o=0;on[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}function du(t,e){if(t.length===e.length){for(var i=0;ie[0]?1:-1;e[0]+=n*i,e[1]-=n*i}return e}function gu(t,e,i){if(!i.valueDim)return[];for(var n=[],o=0,a=e.count();oa[1]&&a.reverse();var r=o.getExtent(),s=Math.PI/180;i&&(a[0]-=.5,a[1]+=.5);var l=new vS({shape:{cx:Ao(t.cx,1),cy:Ao(t.cy,1),r0:Ao(a[0],1),r:Ao(a[1],1),startAngle:-r[0]*s,endAngle:-r[1]*s,clockwise:o.inverse}});return e&&(l.shape.endAngle=-r[0]*s,po(l,{shape:{endAngle:-r[1]*s}},n)),l}function yu(t,e,i,n){return"polar"===t.type?vu(t,e,i,n):mu(t,e,i,n)}function xu(t,e,i){for(var n=e.getBaseAxis(),o="x"===n.dim||"radius"===n.dim?0:1,a=[],r=0;r=0;a--){var r=i[a].dimension,s=t.dimensions[r],l=t.getDimensionInfo(s);if("x"===(n=l&&l.coordDim)||"y"===n){o=i[a];break}}if(o){var u=e.getAxis(n),h=f(o.stops,function(t){return{coord:u.toGlobalCoord(u.dataToCoord(t.value)),color:t.color}}),c=h.length,p=o.outerColors.slice();c&&h[0].coord>h[c-1].coord&&(h.reverse(),p.reverse());var g=h[0].coord-10,m=h[c-1].coord+10,v=m-g;if(v<.001)return"transparent";d(h,function(t){t.offset=(t.coord-g)/v}),h.push({offset:c?h[c-1].offset:.5,color:p[1]||"transparent"}),h.unshift({offset:c?h[0].offset:.5,color:p[0]||"transparent"});var y=new LS(0,0,0,0,h,!0);return y[n]=g,y[n+"2"]=m,y}}}function wu(t,e,i){var n=t.get("showAllSymbol"),o="auto"===n;if(!n||o){var a=i.getAxesByScale("ordinal")[0];if(a&&(!o||!bu(a,e))){var r=e.mapDimension(a.dim),s={};return d(a.getViewLabels(),function(t){s[t.tickValue]=1}),function(t){return!s.hasOwnProperty(e.get(r,t))}}}}function bu(t,e){var i=t.getExtent(),n=Math.abs(i[1]-i[0])/t.scale.count();isNaN(n)&&(n=0);for(var o=e.count(),a=Math.max(1,Math.round(o/5)),r=0;rn)return!1;return!0}function Su(t){return this._axes[t]}function Mu(t){xD.call(this,t)}function Iu(t,e){return e.type||(e.data?"category":"value")}function Tu(t,e,i){return t.getCoordSysModel()===e}function Du(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this.model=t}function Au(t,e,i){i.getAxesOnZeroOf=function(){return n?[n]:[]};var n,o=t[e],a=i.model,r=a.get("axisLine.onZero"),s=a.get("axisLine.onZeroAxisIndex");if(r)if(null==s){for(var l in o)if(o.hasOwnProperty(l)&&Cu(o[l])){n=o[l];break}}else Cu(o[s])&&(n=o[s])}function Cu(t){return t&&"category"!==t.type&&"time"!==t.type&&_l(t)}function Lu(t,e){var i=t.getExtent(),n=i[0]+i[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return n-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return n-t+e}}function ku(t,e){return f(AD,function(e){return t.getReferringComponents(e)[0]})}function Pu(t){return"cartesian2d"===t.get("coordinateSystem")}function Nu(t){var e={componentType:t.mainType};return e[t.mainType+"Index"]=t.componentIndex,e}function Ou(t,e,i,n){var o,a,r=Oo(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return Eo(r-CD/2)?(a=l?"bottom":"top",o="center"):Eo(r-1.5*CD)?(a=l?"top":"bottom",o="center"):(a="middle",o=r<1.5*CD&&r>CD/2?l?"left":"right":l?"right":"left"),{rotation:r,textAlign:o,textVerticalAlign:a}}function Eu(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)}function Ru(t,e,i){var n=t.get("axisLabel.showMinLabel"),o=t.get("axisLabel.showMaxLabel");e=e||[],i=i||[];var a=e[0],r=e[1],s=e[e.length-1],l=e[e.length-2],u=i[0],h=i[1],c=i[i.length-1],d=i[i.length-2];!1===n?(zu(a),zu(u)):Bu(a,r)&&(n?(zu(r),zu(h)):(zu(a),zu(u))),!1===o?(zu(s),zu(c)):Bu(l,s)&&(o?(zu(l),zu(d)):(zu(s),zu(c)))}function zu(t){t&&(t.ignore=!0)}function Bu(t,e,i){var n=t&&t.getBoundingRect().clone(),o=e&&e.getBoundingRect().clone();if(n&&o){var a=lt([]);return dt(a,a,-t.rotation),n.applyTransform(ht([],a,t.getLocalTransform())),o.applyTransform(ht([],a,e.getLocalTransform())),n.intersect(o)}}function Vu(t){return"middle"===t||"center"===t}function Gu(t,e,i){var n=e.axis;if(e.get("axisTick.show")&&!n.scale.isBlank()){for(var o=e.getModel("axisTick"),a=o.getModel("lineStyle"),s=o.get("length"),l=n.getTicksCoords(),u=[],h=[],c=t._transform,d=[],f=0;f=0||t===e}function Yu(t){var e=qu(t);if(e){var i=e.axisPointerModel,n=e.axis.scale,o=i.option,a=i.get("status"),r=i.get("value");null!=r&&(r=n.parse(r));var s=$u(i);null==a&&(o.status=s?"show":"hide");var l=n.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==r||r>l[1])&&(r=l[1]),r0?"bottom":"top":o.width>0?"left":"right";l||ih(t.style,d,n,u,a,i,p),eo(t,d)}function sh(t,e){var i=t.get(HD)||0;return Math.min(i,Math.abs(e.width),Math.abs(e.height))}function lh(t,e,i){var n=t.getData(),o=[],a=n.getLayout("valueAxisHorizontal")?1:0;o[1-a]=n.getLayout("valueAxisStart");var r=new XD({shape:{points:n.getLayout("largePoints")},incremental:!!i,__startPoint:o,__valueIdx:a});e.add(r),uh(r,t,n)}function uh(t,e,i){var n=i.getVisual("borderColor")||i.getVisual("color"),o=e.getModel("itemStyle").getItemStyle(["color","borderColor"]);t.useStyle(o),t.style.fill=null,t.style.stroke=n,t.style.lineWidth=i.getLayout("barWidth")}function hh(t,e,i,n){var o=e.getData(),a=this.dataIndex,r=o.getName(a),s=e.get("selectedOffset");n.dispatchAction({type:"pieToggleSelect",from:t,name:r,seriesId:e.id}),o.each(function(t){ch(o.getItemGraphicEl(t),o.getItemLayout(t),e.isSelected(o.getName(t)),s,i)})}function ch(t,e,i,n,o){var a=(e.startAngle+e.endAngle)/2,r=Math.cos(a),s=Math.sin(a),l=i?n:0,u=[r*l,s*l];o?t.animate().when(200,{position:u}).start("bounceOut"):t.attr("position",u)}function dh(t,e){function i(){a.ignore=a.hoverIgnore,r.ignore=r.hoverIgnore}function n(){a.ignore=a.normalIgnore,r.ignore=r.normalIgnore}sw.call(this);var o=new vS({z2:2}),a=new bS,r=new fS;this.add(o),this.add(a),this.add(r),this.updateData(t,e,!0),this.on("emphasis",i).on("normal",n).on("mouseover",i).on("mouseout",n)}function fh(t,e,i,n,o,a,r){function s(e,i){for(var n=e;n>=0&&(t[n].y-=i,!(n>0&&t[n].y>t[n-1].y+t[n-1].height));n--);}function l(t,e,i,n,o,a){for(var r=e?Number.MAX_VALUE:0,s=0,l=t.length;s=r&&(d=r-10),!e&&d<=r&&(d=r+10),t[s].x=i+d*a,r=d}}t.sort(function(t,e){return t.y-e.y});for(var u,h=0,c=t.length,d=[],f=[],p=0;pe&&a+1t[a].y+t[a].height)return void s(a,n/2);s(i-1,n/2)}(p,c,-u),h=t[p].y+t[p].height;r-h<0&&s(c-1,h-r);for(p=0;p=i?f.push(t[p]):d.push(t[p]);l(d,!1,e,i,n,o),l(f,!0,e,i,n,o)}function ph(t,e,i,n,o,a){for(var r=[],s=[],l=0;l1?(p.width=l,p.height=l/d):(p.height=l,p.width=l*d),p.y=s[1]-p.height/2,p.x=s[0]-p.width/2}else(a=t.getBoxLayoutParams()).aspect=d,p=Qo(a,{width:u,height:h});this.setViewRect(p.x,p.y,p.width,p.height),this.setCenter(t.get("center")),this.setZoom(t.get("zoom"))}function Th(t,e){d(e.get("geoCoord"),function(e,i){t.addGeoCoord(i,e)})}function Dh(t,e,i){Lh(t)[e]=i}function Ah(t,e,i){var n=Lh(t);n[e]===i&&(n[e]=null)}function Ch(t,e){return!!Lh(t)[e]}function Lh(t){return t[xA]||(t[xA]={})}function kh(t){this.pointerChecker,this._zr=t,this._opt={};var e=m,n=e(Ph,this),o=e(Nh,this),a=e(Oh,this),s=e(Eh,this),l=e(Rh,this);D_.call(this),this.setPointerChecker=function(t){this.pointerChecker=t},this.enable=function(e,u){this.disable(),this._opt=r(i(u)||{},{zoomOnMouseWheel:!0,moveOnMouseMove:!0,preventDefaultMouseMove:!0}),null==e&&(e=!0),!0!==e&&"move"!==e&&"pan"!==e||(t.on("mousedown",n),t.on("mousemove",o),t.on("mouseup",a)),!0!==e&&"scale"!==e&&"zoom"!==e||(t.on("mousewheel",s),t.on("pinch",l))},this.disable=function(){t.off("mousedown",n),t.off("mousemove",o),t.off("mouseup",a),t.off("mousewheel",s),t.off("pinch",l)},this.dispose=this.disable,this.isDragging=function(){return this._dragging},this.isPinching=function(){return this._pinching}}function Ph(t){if(!(ci(t)||t.target&&t.target.draggable)){var e=t.offsetX,i=t.offsetY;this.pointerChecker&&this.pointerChecker(t,e,i)&&(this._x=e,this._y=i,this._dragging=!0)}}function Nh(t){if(!ci(t)&&Bh(this,"moveOnMouseMove",t)&&this._dragging&&"pinch"!==t.gestureEvent&&!Ch(this._zr,"globalPan")){var e=t.offsetX,i=t.offsetY,n=this._x,o=this._y,a=e-n,r=i-o;this._x=e,this._y=i,this._opt.preventDefaultMouseMove&&zw(t.event),this.trigger("pan",a,r,n,o,e,i)}}function Oh(t){ci(t)||(this._dragging=!1)}function Eh(t){if(Bh(this,"zoomOnMouseWheel",t)&&0!==t.wheelDelta){var e=t.wheelDelta>0?1.1:1/1.1;zh.call(this,t,e,t.offsetX,t.offsetY)}}function Rh(t){if(!Ch(this._zr,"globalPan")){var e=t.pinchScale>1?1.1:1/1.1;zh.call(this,t,e,t.pinchX,t.pinchY)}}function zh(t,e,i,n){this.pointerChecker&&this.pointerChecker(t,i,n)&&(zw(t.event),this.trigger("zoom",e,i,n))}function Bh(t,e,i){var n=t._opt[e];return n&&(!_(n)||i.event[n+"Key"])}function Vh(t,e,i){var n=t.target,o=n.position;o[0]+=e,o[1]+=i,n.dirty()}function Gh(t,e,i,n){var o=t.target,a=t.zoomLimit,r=o.position,s=o.scale,l=t.zoom=t.zoom||1;if(l*=e,a){var u=a.min||0,h=a.max||1/0;l=Math.max(Math.min(h,l),u)}var c=l/t.zoom;t.zoom=l,r[0]-=(i-r[0])*(c-1),r[1]-=(n-r[1])*(c-1),s[0]*=c,s[1]*=c,o.dirty()}function Wh(t,e,i){var n=e.getComponentByElement(t.topTarget),o=n&&n.coordinateSystem;return n&&n!==i&&!_A[n.mainType]&&o&&o.model!==i}function Fh(t,e){var i=t.getItemStyle(),n=t.get("areaColor");return null!=n&&(i.fill=n),i}function Hh(t,e,i,n,o){i.off("click"),i.off("mousedown"),e.get("selectedMode")&&(i.on("mousedown",function(){t._mouseDownFlag=!0}),i.on("click",function(a){if(t._mouseDownFlag){t._mouseDownFlag=!1;for(var r=a.target;!r.__regions;)r=r.parent;if(r){var s={type:("geo"===e.mainType?"geo":"map")+"ToggleSelect",batch:f(r.__regions,function(t){return{name:t.name,from:o.uid}})};s[e.mainType+"Id"]=e.id,n.dispatchAction(s),Zh(e,i)}}}))}function Zh(t,e){e.eachChild(function(e){d(e.__regions,function(i){e.trigger(t.isSelected(i.name)?"emphasis":"normal")})})}function Uh(t,e){var i=new sw;this._controller=new kh(t.getZr()),this._controllerHost={target:e?i:null},this.group=i,this._updateGroup=e,this._mouseDownFlag}function Xh(t,e,i){var n=t.getZoom(),o=t.getCenter(),a=e.zoom,r=t.dataToPoint(o);if(null!=e.dx&&null!=e.dy){r[0]-=e.dx,r[1]-=e.dy;o=t.pointToData(r);t.setCenter(o)}if(null!=a){if(i){var s=i.min||0,l=i.max||1/0;a=Math.max(Math.min(n*a,l),s)/n}t.scale[0]*=a,t.scale[1]*=a;var u=t.position,h=(e.originX-u[0])*(a-1),c=(e.originY-u[1])*(a-1);u[0]-=h,u[1]-=c,t.updateTransform();o=t.pointToData(r);t.setCenter(o),t.setZoom(a*n)}return{center:t.getCenter(),zoom:t.getZoom()}}function jh(t,e){var i={};return d(t,function(t){t.each(t.mapDimension("value"),function(e,n){var o="ec-"+t.getName(n);i[o]=i[o]||[],isNaN(e)||i[o].push(e)})}),t[0].map(t[0].mapDimension("value"),function(n,o){for(var a="ec-"+t[0].getName(o),r=0,s=1/0,l=-1/0,u=i[a].length,h=0;h=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},n.push(a)}}function ac(t,e){var i=t.isExpand?t.children:[],n=t.parentNode.children,o=t.hierNode.i?n[t.hierNode.i-1]:null;if(i.length){hc(t);var a=(i[0].hierNode.prelim+i[i.length-1].hierNode.prelim)/2;o?(t.hierNode.prelim=o.hierNode.prelim+e(t,o),t.hierNode.modifier=t.hierNode.prelim-a):t.hierNode.prelim=a}else o&&(t.hierNode.prelim=o.hierNode.prelim+e(t,o));t.parentNode.hierNode.defaultAncestor=cc(t,o,t.parentNode.hierNode.defaultAncestor||n[0],e)}function rc(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function sc(t){return arguments.length?t:mc}function lc(t,e){var i={};return t-=Math.PI/2,i.x=e*Math.cos(t),i.y=e*Math.sin(t),i}function uc(t,e){return Qo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function hc(t){for(var e=t.children,i=e.length,n=0,o=0;--i>=0;){var a=e[i];a.hierNode.prelim+=n,a.hierNode.modifier+=n,o+=a.hierNode.change,n+=a.hierNode.shift+o}}function cc(t,e,i,n){if(e){for(var o=t,a=t,r=a.parentNode.children[0],s=e,l=o.hierNode.modifier,u=a.hierNode.modifier,h=r.hierNode.modifier,c=s.hierNode.modifier;s=dc(s),a=fc(a),s&&a;){o=dc(o),r=fc(r),o.hierNode.ancestor=t;var d=s.hierNode.prelim+c-a.hierNode.prelim-u+n(s,a);d>0&&(gc(pc(s,t,i),t,d),u+=d,l+=d),c+=s.hierNode.modifier,u+=a.hierNode.modifier,l+=o.hierNode.modifier,h+=r.hierNode.modifier}s&&!dc(o)&&(o.hierNode.thread=s,o.hierNode.modifier+=c-l),a&&!fc(r)&&(r.hierNode.thread=a,r.hierNode.modifier+=u-h,i=t)}return i}function dc(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function fc(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function pc(t,e,i){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:i}function gc(t,e,i){var n=i/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=n,e.hierNode.shift+=i,e.hierNode.modifier+=i,e.hierNode.prelim+=i,t.hierNode.change+=n}function mc(t,e){return t.parentNode===e.parentNode?1:2}function vc(t,e){var i=t.getItemLayout(e);return i&&!isNaN(i.x)&&!isNaN(i.y)&&"none"!==t.getItemVisual(e,"symbol")}function yc(t,e,i){return i.itemModel=e,i.itemStyle=e.getModel("itemStyle").getItemStyle(),i.hoverItemStyle=e.getModel("emphasis.itemStyle").getItemStyle(),i.lineStyle=e.getModel("lineStyle").getLineStyle(),i.labelModel=e.getModel("label"),i.hoverLabelModel=e.getModel("emphasis.label"),!1===t.isExpand&&0!==t.children.length?i.symbolInnerColor=i.itemStyle.fill:i.symbolInnerColor="#fff",i}function xc(t,e,i,n,o,a){var s=!i,l=t.tree.getNodeByDataIndex(e),a=yc(l,l.getModel(),a),u=t.tree.root,h=l.parentNode===u?l:l.parentNode||l,c=t.getItemGraphicEl(h.dataIndex),d=h.getLayout(),f=c?{x:c.position[0],y:c.position[1],rawX:c.__radialOldRawX,rawY:c.__radialOldRawY}:d,p=l.getLayout();s?(i=new Kl(t,e,a)).attr("position",[f.x,f.y]):i.updateData(t,e,a),i.__radialOldRawX=i.__radialRawX,i.__radialOldRawY=i.__radialRawY,i.__radialRawX=p.rawX,i.__radialRawY=p.rawY,n.add(i),t.setItemGraphicEl(e,i),fo(i,{position:[p.x,p.y]},o);var g=i.getSymbolPath();if("radial"===a.layout){var m,v,y=u.children[0],x=y.getLayout(),_=y.children.length;if(p.x===x.x&&!0===l.isExpand){var w={};w.x=(y.children[0].getLayout().x+y.children[_-1].getLayout().x)/2,w.y=(y.children[0].getLayout().y+y.children[_-1].getLayout().y)/2,(m=Math.atan2(w.y-x.y,w.x-x.x))<0&&(m=2*Math.PI+m),(v=w.xx.x)||(m-=Math.PI);var b=v?"left":"right";g.setStyle({textPosition:b,textRotation:-m,textOrigin:"center",verticalAlign:"middle"})}if(l.parentNode&&l.parentNode!==u){var S=i.__edge;S||(S=i.__edge=new TS({shape:wc(a,f,f),style:r({opacity:0},a.lineStyle)})),fo(S,{shape:wc(a,d,p),style:{opacity:1}},o),n.add(S)}}function _c(t,e,i,n,o,a){for(var r,s=t.tree.getNodeByDataIndex(e),l=t.tree.root,a=yc(s,s.getModel(),a),u=s.parentNode===l?s:s.parentNode||s;null==(r=u.getLayout());)u=u.parentNode===l?u:u.parentNode||u;fo(i,{position:[r.x+1,r.y+1]},o,function(){n.remove(i),t.setItemGraphicEl(e,null)}),i.fadeOut(null,{keepLabel:!0});var h=i.__edge;h&&fo(h,{shape:wc(a,r,r),style:{opacity:0}},o,function(){n.remove(h)})}function wc(t,e,i){var n,o,a,r,s=t.orient;if("radial"===t.layout){var l=e.rawX,u=e.rawY,h=i.rawX,c=i.rawY,d=lc(l,u),f=lc(l,u+(c-u)*t.curvature),p=lc(h,c+(u-c)*t.curvature),g=lc(h,c);return{x1:d.x,y1:d.y,x2:g.x,y2:g.y,cpx1:f.x,cpy1:f.y,cpx2:p.x,cpy2:p.y}}var l=e.x,u=e.y,h=i.x,c=i.y;return"LR"!==s&&"RL"!==s||(n=l+(h-l)*t.curvature,o=u,a=h+(l-h)*t.curvature,r=c),"TB"!==s&&"BT"!==s||(n=l,o=u+(c-u)*t.curvature,a=h,r=c+(u-c)*t.curvature),{x1:l,y1:u,x2:h,y2:c,cpx1:n,cpy1:o,cpx2:a,cpy2:r}}function bc(t,e,i){for(var n,o=[t],a=[];n=o.pop();)if(a.push(n),n.isExpand){var r=n.children;if(r.length)for(var s=0;s=0;a--)n.push(o[a])}}function Mc(t,e){var i=uc(t,e);t.layoutInfo=i;var n=t.get("layout"),o=0,a=0,r=null;"radial"===n?(o=2*Math.PI,a=Math.min(i.height,i.width)/2,r=sc(function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth})):(o=i.width,a=i.height,r=sc());var s=t.getData().tree.root,l=s.children[0];if(l){oc(s),bc(l,ac,r),s.hierNode.modifier=-l.hierNode.prelim,Sc(l,rc);var u=l,h=l,c=l;Sc(l,function(t){var e=t.getLayout().x;eh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)});var d=u===h?1:r(u,h)/2,f=d-u.getLayout().x,p=0,g=0,m=0,v=0;if("radial"===n)p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),Sc(l,function(t){m=(t.getLayout().x+f)*p,v=(t.depth-1)*g;var e=lc(m,v);t.setLayout({x:e.x,y:e.y,rawX:m,rawY:v},!0)});else{var y=t.getOrient();"RL"===y||"LR"===y?(g=a/(h.getLayout().x+d+f),p=o/(c.depth-1||1),Sc(l,function(t){v=(t.getLayout().x+f)*g,m="LR"===y?(t.depth-1)*p:o-(t.depth-1)*p,t.setLayout({x:m,y:v},!0)})):"TB"!==y&&"BT"!==y||(p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),Sc(l,function(t){m=(t.getLayout().x+f)*p,v="TB"===y?(t.depth-1)*g:a-(t.depth-1)*g,t.setLayout({x:m,y:v},!0)}))}}}function Ic(t,e,i){if(t&&l(e,t.type)>=0){var n=i.getData().tree.root,o=t.targetNode;if(o&&n.contains(o))return{node:o};var a=t.targetNodeId;if(null!=a&&(o=n.getNodeById(a)))return{node:o}}}function Tc(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function Dc(t,e){return l(Tc(t),e)>=0}function Ac(t,e){for(var i=[];t;){var n=t.dataIndex;i.push({name:t.name,dataIndex:n,value:e.getRawValue(n)}),t=t.parentNode}return i.reverse(),i}function Cc(t){var e=0;d(t.children,function(t){Cc(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function Lc(t,e){var i=e.get("color");if(i){var n;return d(t=t||[],function(t){var e=new wo(t),i=e.get("color");(e.get("itemStyle.color")||i&&"none"!==i)&&(n=!0)}),n||((t[0]||(t[0]={})).color=i.slice()),t}}function kc(t){this.group=new sw,t.add(this.group)}function Pc(t,e,i,n,o,a){var r=[[o?t:t-IA,e],[t+i,e],[t+i,e+n],[o?t:t-IA,e+n]];return!a&&r.splice(2,0,[t+i+IA,e+n/2]),!o&&r.push([t,e+n/2]),r}function Nc(t,e,i){t.eventData={componentType:"series",componentSubType:"treemap",seriesIndex:e.componentIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:i&&i.dataIndex,name:i&&i.name},treePathInfo:i&&Ac(i,e)}}function Oc(){var t,e=[],i={};return{add:function(t,n,o,a,r){return _(a)&&(r=a,a=0),!i[t.id]&&(i[t.id]=1,e.push({el:t,target:n,time:o,delay:a,easing:r}),!0)},done:function(e){return t=e,this},start:function(){for(var n=e.length,o=0,a=e.length;o=0;a--)null==i[a]&&(delete n[e[a]],e.pop())}function Vc(t,e){var i=t.visual,n=[];w(i)?WA(i,function(t){n.push(t)}):null!=i&&n.push(i);var o={color:1,symbol:1};e||1!==n.length||o.hasOwnProperty(t.type)||(n[1]=n[0]),jc(t,n)}function Gc(t){return{applyVisual:function(e,i,n){e=this.mapValueToVisual(e),n("color",t(i("color"),e))},_doMap:Uc([0,1])}}function Wc(t){var e=this.option.visual;return e[Math.round(To(t,[0,1],[0,e.length-1],!0))]||{}}function Fc(t){return function(e,i,n){n(t,this.mapValueToVisual(e))}}function Hc(t){var e=this.option.visual;return e[this.option.loop&&t!==HA?t%e.length:t]}function Zc(){return this.option.visual[0]}function Uc(t){return{linear:function(e){return To(e,t,this.option.visual,!0)},category:Hc,piecewise:function(e,i){var n=Xc.call(this,i);return null==n&&(n=To(e,t,this.option.visual,!0)),n},fixed:Zc}}function Xc(t){var e=this.option,i=e.pieceList;if(e.hasSpecialVisual){var n=i[ZA.findPieceIndex(t,i)];if(n&&n.visual)return n.visual[this.type]}}function jc(t,e){return t.visual=e,"color"===t.type&&(t.parsedVisual=f(e,function(t){return At(t)})),e}function Yc(t,e,i){return t?e<=i:e=o.length||t===o[t.depth])&&qc(t,id(r,h,t,e,g,a),i,n,o,a)})}else l=$c(h),t.setVisual("color",l)}}function Kc(t,e,i,n){var o=a({},e);return d(["color","colorAlpha","colorSaturation"],function(a){var r=t.get(a,!0);null==r&&i&&(r=i[a]),null==r&&(r=e[a]),null==r&&(r=n.get(a)),null!=r&&(o[a]=r)}),o}function $c(t){var e=Qc(t,"color");if(e){var i=Qc(t,"colorAlpha"),n=Qc(t,"colorSaturation");return n&&(e=Et(e,null,null,n)),i&&(e=Rt(e,i)),e}}function Jc(t,e){return null!=e?Et(e,null,null,t):null}function Qc(t,e){var i=t[e];if(null!=i&&"none"!==i)return i}function td(t,e,i,n,o,a){if(a&&a.length){var r=ed(e,"color")||null!=o.color&&"none"!==o.color&&(ed(e,"colorAlpha")||ed(e,"colorSaturation"));if(r){var s=e.get("visualMin"),l=e.get("visualMax"),u=i.dataExtent.slice();null!=s&&su[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:r.name,dataExtent:u,visual:r.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var d=new ZA(c);return d.__drColorMappingBy=h,d}}}function ed(t,e){var i=t.get(e);return jA(i)&&i.length?{name:e,range:i}:null}function id(t,e,i,n,o,r){var s=a({},e);if(o){var l=o.type,u="color"===l&&o.__drColorMappingBy,h="index"===u?n:"id"===u?r.mapIdToIndex(i.getId()):i.getValue(t.get("visualDimension"));s[l]=o.mapValueToVisual(h)}return s}function nd(t,e,i,n){var o,a;if(!t.isRemoved()){var r=t.getLayout();o=r.width,a=r.height;var s=(f=t.getModel()).get(tC),l=f.get(eC)/2,u=fd(f),h=Math.max(s,u),c=s-l,d=h-l,f=t.getModel();t.setLayout({borderWidth:s,upperHeight:h,upperLabelHeight:u},!0);var p=(o=KA(o-2*c,0))*(a=KA(a-c-d,0)),g=od(t,f,p,e,i,n);if(g.length){var m={x:c,y:d,width:o,height:a},v=$A(o,a),y=1/0,x=[];x.area=0;for(var _=0,w=g.length;_=0;l--){var u=o["asc"===n?r-l-1:l].getValue();u/i*es[1]&&(s[1]=e)})}else s=[NaN,NaN];return{sum:n,dataExtent:s}}function ld(t,e,i){for(var n,o=0,a=1/0,r=0,s=t.length;ro&&(o=n));var l=t.area*t.area,u=e*e*i;return l?KA(u*o/l,l/(u*a)):1/0}function ud(t,e,i,n,o){var a=e===i.width?0:1,r=1-a,s=["x","y"],l=["width","height"],u=i[s[a]],h=e?t.area/e:0;(o||h>i[l[r]])&&(h=i[l[r]]);for(var c=0,d=t.length;cjS&&(u=jS),a=s}u=0?n+=u:n-=u:p>=0?n-=u:n+=u}return n}function Ld(t,e){return t.getVisual("opacity")||t.getModel().get(e)}function kd(t,e,i){var n=t.getGraphicEl(),o=Ld(t,e);null!=i&&(null==o&&(o=1),o*=i),n.downplay&&n.downplay(),n.traverse(function(t){"group"!==t.type&&t.setStyle("opacity",o)})}function Pd(t,e){var i=Ld(t,e),n=t.getGraphicEl();n.highlight&&n.highlight(),n.traverse(function(t){"group"!==t.type&&t.setStyle("opacity",i)})}function Nd(t){return t instanceof Array||(t=[t,t]),t}function Od(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=t.getGraph();i.eachNode(function(t){var e=t.getModel();t.setLayout([+e.get("x"),+e.get("y")])}),Ed(i)}}function Ed(t){t.eachEdge(function(t){var e=t.getModel().get("lineStyle.curveness")||0,i=W(t.node1.getLayout()),n=W(t.node2.getLayout()),o=[i,n];+e&&o.push([(i[0]+n[0])/2-(i[1]-n[1])*e,(i[1]+n[1])/2-(n[0]-i[0])*e]),t.setLayout(o)})}function Rd(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var i=e.getBoundingRect(),n=t.getData(),o=n.graph,a=0,r=n.getSum("value"),s=2*Math.PI/(r||n.count()),l=i.width/2+i.x,u=i.height/2+i.y,h=Math.min(i.width,i.height)/2;o.eachNode(function(t){var e=t.getValue("value");a+=s*(r?e:1)/2,t.setLayout([h*Math.cos(a)+l,h*Math.sin(a)+u]),a+=s*(r?e:1)/2}),n.setLayout({cx:l,cy:u}),o.eachEdge(function(t){var e,i=t.getModel().get("lineStyle.curveness")||0,n=W(t.node1.getLayout()),o=W(t.node2.getLayout()),a=(n[0]+o[0])/2,r=(n[1]+o[1])/2;+i&&(e=[l*(i*=3)+a*(1-i),u*i+r*(1-i)]),t.setLayout([n,o,e])})}}function zd(t,e,i){for(var n=i.rect,o=n.width,a=n.height,r=[n.x+o/2,n.y+a/2],s=null==i.gravity?.1:i.gravity,l=0;l0?-1:i<0?1:e?-1:1}}function Yd(t,e){return Math.min(e[1],Math.max(e[0],t))}function qd(t,e,i){this._axesMap=R(),this._axesLayout={},this.dimensions=t.dimensions,this._rect,this._model=t,this._init(t,e,i)}function Kd(t,e){return OC(EC(t,e[0]),e[1])}function $d(t,e){var i=e.layoutLength/(e.axisCount-1);return{position:i*t,axisNameAvailableWidth:i,axisLabelShow:!0}}function Jd(t,e){var i,n,o=e.layoutLength,a=e.axisExpandWidth,r=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return tqC}function pf(t){var e=t.length-1;return e<0&&(e=0),[t[0],t[e]]}function gf(t,e,i,n){var o=new sw;return o.add(new SS({name:"main",style:xf(i),silent:!0,draggable:!0,cursor:"move",drift:FC(t,e,o,"nswe"),ondragend:FC(df,e,{isEnd:!0})})),HC(n,function(i){o.add(new SS({name:i,style:{opacity:0},draggable:!0,silent:!0,invisible:!0,drift:FC(t,e,o,i),ondragend:FC(df,e,{isEnd:!0})}))}),o}function mf(t,e,i,n){var o=n.brushStyle.lineWidth||0,a=XC(o,KC),r=i[0][0],s=i[1][0],l=r-o/2,u=s-o/2,h=i[0][1],c=i[1][1],d=h-a+o/2,f=c-a+o/2,p=h-r,g=c-s,m=p+o,v=g+o;yf(t,e,"main",r,s,p,g),n.transformable&&(yf(t,e,"w",l,u,a,v),yf(t,e,"e",d,u,a,v),yf(t,e,"n",l,u,m,a),yf(t,e,"s",l,f,m,a),yf(t,e,"nw",l,u,a,a),yf(t,e,"ne",d,u,a,a),yf(t,e,"sw",l,f,a,a),yf(t,e,"se",d,f,a,a))}function vf(t,e){var i=e.__brushOption,n=i.transformable,o=e.childAt(0);o.useStyle(xf(i)),o.attr({silent:!n,cursor:n?"move":"default"}),HC(["w","e","n","s","se","sw","ne","nw"],function(i){var o=e.childOfName(i),a=bf(t,i);o&&o.attr({silent:!n,invisible:!n,cursor:n?QC[a]+"-resize":null})})}function yf(t,e,i,n,o,a,r){var s=e.childOfName(i);s&&s.setShape(Df(Tf(t,e,[[n,o],[n+a,o+r]])))}function xf(t){return r({strokeNoScale:!0},t.brushStyle)}function _f(t,e,i,n){var o=[UC(t,i),UC(e,n)],a=[XC(t,i),XC(e,n)];return[[o[0],a[0]],[o[1],a[1]]]}function wf(t){return go(t.group)}function bf(t,e){if(e.length>1)return("e"===(n=[bf(t,(e=e.split(""))[0]),bf(t,e[1])])[0]||"w"===n[0])&&n.reverse(),n.join("");var i={left:"w",right:"e",top:"n",bottom:"s"},n=vo({w:"left",e:"right",n:"top",s:"bottom"}[e],wf(t));return i[n]}function Sf(t,e,i,n,o,a,r,s){var l=n.__brushOption,u=t(l.range),h=If(i,a,r);HC(o.split(""),function(t){var e=JC[t];u[e[0]][e[1]]+=h[e[0]]}),l.range=e(_f(u[0][0],u[1][0],u[0][1],u[1][1])),sf(i,n),df(i,{isEnd:!1})}function Mf(t,e,i,n,o){var a=e.__brushOption.range,r=If(t,i,n);HC(a,function(t){t[0]+=r[0],t[1]+=r[1]}),sf(t,e),df(t,{isEnd:!1})}function If(t,e,i){var n=t.group,o=n.transformCoordToLocal(e,i),a=n.transformCoordToLocal(0,0);return[o[0]-a[0],o[1]-a[1]]}function Tf(t,e,n){var o=hf(t,e);return o&&!0!==o?o.clipPath(n,t._transform):i(n)}function Df(t){var e=UC(t[0][0],t[1][0]),i=UC(t[0][1],t[1][1]);return{x:e,y:i,width:XC(t[0][0],t[1][0])-e,height:XC(t[0][1],t[1][1])-i}}function Af(t,e,i){if(t._brushType){var n=t._zr,o=t._covers,a=uf(t,e,i);if(!t._dragging)for(var r=0;r=i.length)return e;for(var o=-1,a=e.length,r=i[n++],s={},l={};++o=i.length)return t;var a=[],r=n[o++];return d(t,function(t,i){a.push({key:i,values:e(t,o)})}),r?a.sort(function(t,e){return r(t.key,e.key)}):a}var i=[],n=[];return{key:function(t){return i.push(t),this},sortKeys:function(t){return n[i.length-1]=t,this},entries:function(i){return e(t(i,0),0)}}}function Qf(t,e){return Qo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function tp(t,e,i,n,o,a,r){ip(t,e,i,o),ap(t,e,a,n,r),dp(t)}function ep(t){d(t,function(t){var e=gp(t.outEdges,xp),i=gp(t.inEdges,xp),n=Math.max(e,i);t.setLayout({value:n},!0)})}function ip(t,e,i,n){for(var o=[],a=[],r=[],s=[],l=0,u=0;u0;o--)lp(a,r*=.99),sp(a,n,i),hp(a,r),sp(a,n,i)}function rp(t,e,i,n,o){var a=[];d(e,function(t){var e=t.length,i=0;d(t,function(t){i+=t.getLayout().value});var r=(n-(e-1)*o)/i;a.push(r)}),a.sort(function(t,e){return t-e});var r=a[0];d(e,function(t){d(t,function(t,e){t.setLayout({y:e},!0);var i=t.getLayout().value*r;t.setLayout({dy:i},!0)})}),d(i,function(t){var e=+t.getValue()*r;t.setLayout({dy:e},!0)})}function sp(t,e,i){d(t,function(t){var n,o,a,r=0,s=t.length;for(t.sort(vp),a=0;a0){l=n.getLayout().y+o;n.setLayout({y:l},!0)}r=n.getLayout().y+n.getLayout().dy+e}if((o=r-e-i)>0){var l=n.getLayout().y-o;for(n.setLayout({y:l},!0),r=n.getLayout().y,a=s-2;a>=0;--a)(o=(n=t[a]).getLayout().y+n.getLayout().dy+e-r)>0&&(l=n.getLayout().y-o,n.setLayout({y:l},!0)),r=n.getLayout().y}})}function lp(t,e){d(t.slice().reverse(),function(t){d(t,function(t){if(t.outEdges.length){var i=gp(t.outEdges,up)/gp(t.outEdges,xp),n=t.getLayout().y+(i-mp(t))*e;t.setLayout({y:n},!0)}})})}function up(t){return mp(t.node2)*t.getValue()}function hp(t,e){d(t,function(t){d(t,function(t){if(t.inEdges.length){var i=gp(t.inEdges,cp)/gp(t.inEdges,xp),n=t.getLayout().y+(i-mp(t))*e;t.setLayout({y:n},!0)}})})}function cp(t){return mp(t.node1)*t.getValue()}function dp(t){d(t,function(t){t.outEdges.sort(fp),t.inEdges.sort(pp)}),d(t,function(t){var e=0,i=0;d(t.outEdges,function(t){t.setLayout({sy:e},!0),e+=t.getLayout().dy}),d(t.inEdges,function(t){t.setLayout({ty:i},!0),i+=t.getLayout().dy})})}function fp(t,e){return t.node2.getLayout().y-e.node2.getLayout().y}function pp(t,e){return t.node1.getLayout().y-e.node1.getLayout().y}function gp(t,e){for(var i=0,n=t.length,o=-1;++o0?"P":"N",a=n.getVisual("borderColor"+o)||n.getVisual("color"+o),r=i.getModel(vL).getItemStyle(xL);e.useStyle(r),e.style.fill=null,e.style.stroke=a}function kp(t,e,i,n,o){return i>n?-1:i0?t.get(o,e-1)<=n?1:-1:1}function Pp(t,e){var i,n=t.getBaseAxis(),o="category"===n.type?n.getBandWidth():(i=n.getExtent(),Math.abs(i[1]-i[0])/e.count()),a=Do(D(t.get("barMaxWidth"),o),o),r=Do(D(t.get("barMinWidth"),1),o),s=t.get("barWidth");return null!=s?Do(s,o):Math.max(Math.min(o/2,a),r)}function Np(t){return y(t)||(t=[+t,+t]),t}function Op(t,e){t.eachChild(function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?e.color:null,fill:"fill"===e.brushType?e.color:null}})})}function Ep(t,e){sw.call(this);var i=new Kl(t,e),n=new sw;this.add(i),this.add(n),n.beforeUpdate=function(){this.attr(i.getScale())},this.updateData(t,e)}function Rp(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=f(e,function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),o([e,t[0],t[1]])}))}function zp(t,e,i){sw.call(this),this.add(this.createLine(t,e,i)),this._updateEffectSymbol(t,e)}function Bp(t,e,i){sw.call(this),this._createPolyline(t,e,i)}function Vp(t,e,i){zp.call(this,t,e,i),this._lastFrame=0,this._lastFramePercent=0}function Gp(){this.group=new sw}function Wp(t){return t instanceof Array||(t=[t,t]),t}function Fp(){var t=m_();this.canvas=t,this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={}}function Hp(t,e,i){var n=t[1]-t[0],o=(e=f(e,function(e){return{interval:[(e.interval[0]-t[0])/n,(e.interval[1]-t[0])/n]}})).length,a=0;return function(t){for(n=a;n=0;n--){var r=e[n].interval;if(r[0]<=t&&t<=r[1]){a=n;break}}return n>=0&&n=e[0]&&t<=e[1]}}function Up(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}function Xp(t,e,i,n){var o=t.getItemLayout(e),a=i.get("symbolRepeat"),r=i.get("symbolClip"),s=i.get("symbolPosition")||"start",l=(i.get("symbolRotate")||0)*Math.PI/180||0,u=i.get("symbolPatternSize")||2,h=i.isAnimationEnabled(),c={dataIndex:e,layout:o,itemModel:i,symbolType:t.getItemVisual(e,"symbol")||"circle",color:t.getItemVisual(e,"color"),symbolClip:r,symbolRepeat:a,symbolRepeatDirection:i.get("symbolRepeatDirection"),symbolPatternSize:u,rotation:l,animationModel:h?i:null,hoverAnimation:h&&i.get("hoverAnimation"),z2:i.getShallow("z",!0)||0};jp(i,a,o,n,c),qp(t,e,o,a,r,c.boundingLength,c.pxSign,u,n,c),Kp(i,c.symbolScale,l,n,c);var d=c.symbolSize,f=i.get("symbolOffset");return y(f)&&(f=[Do(f[0],d[0]),Do(f[1],d[1])]),$p(i,d,o,a,r,f,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,n,c),c}function jp(t,e,i,n,o){var a,r=n.valueDim,s=t.get("symbolBoundingData"),l=n.coordSys.getOtherAxis(n.coordSys.getBaseAxis()),u=l.toGlobalCoord(l.dataToCoord(0)),h=1-+(i[r.wh]<=0);if(y(s)){var c=[Yp(l,s[0])-u,Yp(l,s[1])-u];c[1]0?1:a<0?-1:0}function Yp(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function qp(t,e,i,n,o,a,r,s,l,u){var h=l.valueDim,c=l.categoryDim,d=Math.abs(i[c.wh]),f=t.getItemVisual(e,"symbolSize");y(f)?f=f.slice():(null==f&&(f="100%"),f=[f,f]),f[c.index]=Do(f[c.index],d),f[h.index]=Do(f[h.index],n?d:Math.abs(a)),u.symbolSize=f,(u.symbolScale=[f[0]/s,f[1]/s])[h.index]*=(l.isHorizontal?-1:1)*r}function Kp(t,e,i,n,o){var a=t.get(FL)||0;a&&(ZL.attr({scale:e.slice(),rotation:i}),ZL.updateTransform(),a/=ZL.getLineScale(),a*=e[n.valueDim.index]),o.valueLineWidth=a}function $p(t,e,i,n,o,r,s,l,u,h,c,d){var f=c.categoryDim,p=c.valueDim,g=d.pxSign,m=Math.max(e[p.index]+l,0),v=m;if(n){var y=Math.abs(u),x=T(t.get("symbolMargin"),"15%")+"",_=!1;x.lastIndexOf("!")===x.length-1&&(_=!0,x=x.slice(0,x.length-1)),x=Do(x,e[p.index]);var w=Math.max(m+2*x,0),b=_?0:2*x,S=Wo(n),M=S?n:pg((y+b)/w);w=m+2*(x=(y-M*m)/2/(_?M:M-1)),b=_?0:2*x,S||"fixed"===n||(M=h?pg((Math.abs(h)+b)/w):0),v=M*w-b,d.repeatTimes=M,d.symbolMargin=x}var I=g*(v/2),D=d.pathPosition=[];D[f.index]=i[f.wh]/2,D[p.index]="start"===s?I:"end"===s?u-I:u/2,r&&(D[0]+=r[0],D[1]+=r[1]);var A=d.bundlePosition=[];A[f.index]=i[f.xy],A[p.index]=i[p.xy];var C=d.barRectShape=a({},i);C[p.wh]=g*Math.max(Math.abs(i[p.wh]),Math.abs(D[p.index]+I)),C[f.wh]=i[f.wh];var L=d.clipShape={};L[f.xy]=-i[f.xy],L[f.wh]=c.ecSize[f.wh],L[p.xy]=0,L[p.wh]=i[p.wh]}function Jp(t){var e=t.symbolPatternSize,i=Tl(t.symbolType,-e/2,-e/2,e,e,t.color);return i.attr({culling:!0}),"image"!==i.type&&i.setStyle({strokeNoScale:!0}),i}function Qp(t,e,i,n){function o(t){var e=l.slice(),n=i.pxSign,o=t;return("start"===i.symbolRepeatDirection?n>0:n<0)&&(o=h-1-t),e[u.index]=d*(o-h/2+.5)+l[u.index],{position:e,scale:i.symbolScale.slice(),rotation:i.rotation}}var a=t.__pictorialBundle,r=i.symbolSize,s=i.valueLineWidth,l=i.pathPosition,u=e.valueDim,h=i.repeatTimes||0,c=0,d=r[e.valueDim.index]+s+2*i.symbolMargin;for(cg(t,function(t){t.__pictorialAnimationIndex=c,t.__pictorialRepeatTimes=h,c0)],d=t.__pictorialBarRect;ih(d.style,h,a,n,e.seriesModel,o,c),eo(d,h)}function pg(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}function gg(t,e,i){this.dimension="single",this.dimensions=["single"],this._axis=null,this._rect,this._init(t,e,i),this.model=t}function mg(t,e){e=e||{};var i=t.coordinateSystem,n=t.axis,o={},a=n.position,r=n.orient,s=i.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};o.position=["vertical"===r?u.vertical[a]:l[0],"horizontal"===r?u.horizontal[a]:l[3]];var h={horizontal:0,vertical:1};o.rotation=Math.PI/2*h[r];var c={top:-1,bottom:1,right:1,left:-1};o.labelDirection=o.tickDirection=o.nameDirection=c[a],t.get("axisTick.inside")&&(o.tickDirection=-o.tickDirection),T(e.labelInside,t.get("axisLabel.inside"))&&(o.labelDirection=-o.labelDirection);var d=e.rotate;return null==d&&(d=t.get("axisLabel.rotate")),o.labelRotation="top"===a?-d:d,o.z2=1,o}function vg(t,e,i,n,o){var r=t.axis;if(!r.scale.isBlank()&&r.containData(e))if(t.involveSeries){var s=yg(e,t),l=s.payloadBatch,u=s.snapToValue;l[0]&&null==o.seriesIndex&&a(o,l[0]),!n&&t.snap&&r.containData(u)&&null!=u&&(e=u),i.showPointer(t,e,l,o),i.showTooltip(t,s,u)}else i.showPointer(t,e)}function yg(t,e){var i=e.axis,n=i.dim,o=t,a=[],r=Number.MAX_VALUE,s=-1;return $L(e.seriesModels,function(e,l){var u,h,c=e.getData().mapDimension(n,!0);if(e.getAxisTooltipData){var d=e.getAxisTooltipData(c,t,i);h=d.dataIndices,u=d.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===i.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var f=t-u,p=Math.abs(f);p<=r&&((p=0&&s<0)&&(r=p,s=f,o=u,a.length=0),$L(h,function(t){a.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})}))}}),{payloadBatch:a,snapToValue:o}}function xg(t,e,i,n){t[e.key]={value:i,payloadBatch:n}}function _g(t,e,i,n){var o=i.payloadBatch,a=e.axis,r=a.model,s=e.axisPointerModel;if(e.triggerTooltip&&o.length){var l=e.coordSys.model,u=Ju(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:a.dim,axisIndex:r.componentIndex,axisType:r.type,axisId:r.id,value:n,valueLabelOpt:{precision:s.get("label.precision"),formatter:s.get("label.formatter")},seriesDataIndices:o.slice()})}}function wg(t,e,i){var n=i.axesInfo=[];$L(e,function(e,i){var o=e.axisPointerModel.option,a=t[i];a?(!e.useHandle&&(o.status="show"),o.value=a.value,o.seriesDataIndices=(a.payloadBatch||[]).slice()):!e.useHandle&&(o.status="hide"),"show"===o.status&&n.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:o.value})})}function bg(t,e,i,n){if(!Tg(e)&&t.list.length){var o=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};n({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:i.tooltipOption,position:i.position,dataIndexInside:o.dataIndexInside,dataIndex:o.dataIndex,seriesIndex:o.seriesIndex,dataByCoordSys:t.list})}else n({type:"hideTip"})}function Sg(t,e,i){var n=i.getZr(),o=QL(n).axisPointerLastHighlights||{},a=QL(n).axisPointerLastHighlights={};$L(t,function(t,e){var i=t.axisPointerModel.option;"show"===i.status&&$L(i.seriesDataIndices,function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t})});var r=[],s=[];d(o,function(t,e){!a[e]&&s.push(t)}),d(a,function(t,e){!o[e]&&r.push(t)}),s.length&&i.dispatchAction({type:"downplay",escapeConnect:!0,batch:s}),r.length&&i.dispatchAction({type:"highlight",escapeConnect:!0,batch:r})}function Mg(t,e){for(var i=0;i<(t||[]).length;i++){var n=t[i];if(e.axis.dim===n.axisDim&&e.axis.model.componentIndex===n.axisIndex)return n}}function Ig(t){var e=t.axis.model,i={},n=i.axisDim=t.axis.dim;return i.axisIndex=i[n+"AxisIndex"]=e.componentIndex,i.axisName=i[n+"AxisName"]=e.name,i.axisId=i[n+"AxisId"]=e.id,i}function Tg(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function Dg(t,e,i){if(!a_.node){var n=e.getZr();tk(n).records||(tk(n).records={}),Ag(n,e),(tk(n).records[t]||(tk(n).records[t]={})).handler=i}}function Ag(t,e){function i(i,n){t.on(i,function(i){var o=Pg(e);ek(tk(t).records,function(t){t&&n(t,i,o.dispatchAction)}),Cg(o.pendings,e)})}tk(t).initialized||(tk(t).initialized=!0,i("click",v(kg,"click")),i("mousemove",v(kg,"mousemove")),i("globalout",Lg))}function Cg(t,e){var i,n=t.showTip.length,o=t.hideTip.length;n?i=t.showTip[n-1]:o&&(i=t.hideTip[o-1]),i&&(i.dispatchAction=null,e.dispatchAction(i))}function Lg(t,e,i){t.handler("leave",null,i)}function kg(t,e,i,n){e.handler(t,i,n)}function Pg(t){var e={showTip:[],hideTip:[]},i=function(n){var o=e[n.type];o?o.push(n):(n.dispatchAction=i,t.dispatchAction(n))};return{dispatchAction:i,pendings:e}}function Ng(t,e){if(!a_.node){var i=e.getZr();(tk(i).records||{})[t]&&(tk(i).records[t]=null)}}function Og(){}function Eg(t,e,i,n){Rg(nk(i).lastProp,n)||(nk(i).lastProp=n,e?fo(i,n,t):(i.stopAnimation(),i.attr(n)))}function Rg(t,e){if(w(t)&&w(e)){var i=!0;return d(e,function(e,n){i=i&&Rg(t[n],e)}),!!i}return t===e}function zg(t,e){t[e.get("label.show")?"show":"hide"]()}function Bg(t){return{position:t.position.slice(),rotation:t.rotation||0}}function Vg(t,e,i){var n=e.get("z"),o=e.get("zlevel");t&&t.traverse(function(t){"group"!==t.type&&(null!=n&&(t.z=n),null!=o&&(t.zlevel=o),t.silent=i)})}function Gg(t){var e,i=t.get("type"),n=t.getModel(i+"Style");return"line"===i?(e=n.getLineStyle()).fill=null:"shadow"===i&&((e=n.getAreaStyle()).stroke=null),e}function Wg(t,e,i,n,o){var a=Hg(i.get("value"),e.axis,e.ecModel,i.get("seriesDataIndices"),{precision:i.get("label.precision"),formatter:i.get("label.formatter")}),r=i.getModel("label"),s=KS(r.get("padding")||0),l=r.getFont(),u=me(a,l),h=o.position,c=u.width+s[1]+s[3],d=u.height+s[0]+s[2],f=o.align;"right"===f&&(h[0]-=c),"center"===f&&(h[0]-=c/2);var p=o.verticalAlign;"bottom"===p&&(h[1]-=d),"middle"===p&&(h[1]-=d/2),Fg(h,c,d,n);var g=r.get("backgroundColor");g&&"auto"!==g||(g=e.get("axisLine.lineStyle.color")),t.label={shape:{x:0,y:0,width:c,height:d,r:r.get("borderRadius")},position:h.slice(),style:{text:a,textFont:l,textFill:r.getTextColor(),textPosition:"inside",fill:g,stroke:r.get("borderColor")||"transparent",lineWidth:r.get("borderWidth")||0,shadowBlur:r.get("shadowBlur"),shadowColor:r.get("shadowColor"),shadowOffsetX:r.get("shadowOffsetX"),shadowOffsetY:r.get("shadowOffsetY")},z2:10}}function Fg(t,e,i,n){var o=n.getWidth(),a=n.getHeight();t[0]=Math.min(t[0]+e,o)-e,t[1]=Math.min(t[1]+i,a)-i,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}function Hg(t,e,i,n,o){t=e.scale.parse(t);var a=e.scale.getLabel(t,{precision:o.precision}),r=o.formatter;if(r){var s={value:bl(e,t),seriesData:[]};d(n,function(t){var e=i.getSeriesByIndex(t.seriesIndex),n=t.dataIndexInside,o=e&&e.getDataParams(n);o&&s.seriesData.push(o)}),_(r)?a=r.replace("{value}",a):x(r)&&(a=r(s))}return a}function Zg(t,e,i){var n=st();return dt(n,n,i.rotation),ct(n,n,i.position),mo([t.dataToCoord(e),(i.labelOffset||0)+(i.labelDirection||1)*(i.labelMargin||0)],n)}function Ug(t,e,i,n,o,a){var r=LD.innerTextLayout(i.rotation,0,i.labelDirection);i.labelMargin=o.get("label.margin"),Wg(e,n,o,a,{position:Zg(n.axis,t,i),align:r.textAlign,verticalAlign:r.textVerticalAlign})}function Xg(t,e,i){return i=i||0,{x1:t[i],y1:t[1-i],x2:e[i],y2:e[1-i]}}function jg(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}function Yg(t,e,i,n,o,a){return{cx:t,cy:e,r0:i,r:n,startAngle:o,endAngle:a,clockwise:!0}}function qg(t,e){var i={};return i[e.dim+"AxisIndex"]=e.index,t.getCartesian(i)}function Kg(t){return"x"===t.dim?0:1}function $g(t){return t.isHorizontal()?0:1}function Jg(t,e){var i=t.getRect();return[i[lk[e]],i[lk[e]]+i[uk[e]]]}function Qg(t,e,i){var n=new SS({shape:{x:t.x-10,y:t.y-10,width:0,height:t.height+20}});return po(n,{shape:{width:t.width+20,height:t.height+20}},e,i),n}function tm(t,e,i){if(t.count())for(var n,o=e.coordinateSystem,a=e.getLayerSeries(),r=t.mapDimension("single"),s=t.mapDimension("value"),l=f(a,function(e){return f(e.indices,function(e){var i=o.dataToPoint(t.get(r,e));return i[1]=t.get(s,e),i})}),u=em(l),h=u.y0,c=i/u.max,d=a.length,p=a[0].indices.length,g=0;ga&&(a=u),n.push(u)}for(var h=0;ha&&(a=d)}return r.y0=o,r.max=a,r}function im(t){var e=0;d(t.children,function(t){im(t);var i=t.value;y(i)&&(i=i[0]),e+=i});var i=t.value;y(i)&&(i=i[0]),(null==i||isNaN(i))&&(i=e),i<0&&(i=0),y(t.value)?t.value[0]=i:t.value=i}function nm(t,e,i){function n(){r.ignore=r.hoverIgnore}function o(){r.ignore=r.normalIgnore}sw.call(this);var a=new vS({z2:pk});a.seriesIndex=e.seriesIndex;var r=new fS({z2:gk,silent:t.getModel("label").get("silent")});this.add(a),this.add(r),this.updateData(!0,t,"normal",e,i),this.on("emphasis",n).on("normal",o).on("mouseover",n).on("mouseout",o)}function om(t,e,i){var n=t.getVisual("color"),o=t.getVisual("visualMeta");o&&0!==o.length||(n=null);var a=t.getModel("itemStyle").get("color");if(a)return a;if(n)return n;if(0===t.depth)return i.option.color[0];var r=i.option.color.length;return a=i.option.color[am(t)%r]}function am(t){for(var e=t;e.depth>1;)e=e.parentNode;return l(t.getAncestors()[0].children,e)}function rm(t,e,i){return i!==fk.NONE&&(i===fk.SELF?t===e:i===fk.ANCESTOR?t===e||t.isAncestorOf(e):t===e||t.isDescendantOf(e))}function sm(t,e){var i=t.children||[];t.children=lm(i,e),i.length&&d(t.children,function(t){sm(t,e)})}function lm(t,e){if("function"==typeof e)return t.sort(e);var i="asc"===e;return t.sort(function(t,e){var n=(t.getValue()-e.getValue())*(i?1:-1);return 0===n?(t.dataIndex-e.dataIndex)*(i?-1:1):n})}function um(t,e){return e=e||[0,0],f(["x","y"],function(i,n){var o=this.getAxis(i),a=e[n],r=t[n]/2;return"category"===o.type?o.getBandWidth():Math.abs(o.dataToCoord(a-r)-o.dataToCoord(a+r))},this)}function hm(t,e){return e=e||[0,0],f([0,1],function(i){var n=e[i],o=t[i]/2,a=[],r=[];return a[i]=n-o,r[i]=n+o,a[1-i]=r[1-i]=e[1-i],Math.abs(this.dataToPoint(a)[i]-this.dataToPoint(r)[i])},this)}function cm(t,e){var i=this.getAxis(),n=e instanceof Array?e[0]:e,o=(t instanceof Array?t[0]:t)/2;return"category"===i.type?i.getBandWidth():Math.abs(i.dataToCoord(n-o)-i.dataToCoord(n+o))}function dm(t,e){return f(["Radius","Angle"],function(i,n){var o=this["get"+i+"Axis"](),a=e[n],r=t[n]/2,s="dataTo"+i,l="category"===o.type?o.getBandWidth():Math.abs(o[s](a-r)-o[s](a+r));return"Angle"===i&&(l=l*Math.PI/180),l},this)}function fm(t){var e,i=t.type;if("path"===i){var n=t.shape;(e=Rn(n.pathData,null,{x:n.x||0,y:n.y||0,width:n.width||0,height:n.height||0},"center")).__customPathData=t.pathData}else"image"===i?(e=new Je({})).__customImagePath=t.style.image:"text"===i?(e=new fS({})).__customText=t.style.text:e=new(0,BS[i.charAt(0).toUpperCase()+i.slice(1)]);return e.__customGraphicType=i,e.name=t.name,e}function pm(t,e,n,o,a,r){var s={},l=n.style||{};if(n.shape&&(s.shape=i(n.shape)),n.position&&(s.position=n.position.slice()),n.scale&&(s.scale=n.scale.slice()),n.origin&&(s.origin=n.origin.slice()),n.rotation&&(s.rotation=n.rotation),"image"===t.type&&n.style){u=s.style={};d(["x","y","width","height"],function(e){gm(e,u,l,t.style,r)})}if("text"===t.type&&n.style){var u=s.style={};d(["x","y"],function(e){gm(e,u,l,t.style,r)}),!l.hasOwnProperty("textFill")&&l.fill&&(l.textFill=l.fill),!l.hasOwnProperty("textStroke")&&l.stroke&&(l.textStroke=l.stroke)}if("group"!==t.type&&(t.useStyle(l),r)){t.style.opacity=0;var h=l.opacity;null==h&&(h=1),po(t,{style:{opacity:h}},o,e)}r?t.attr(s):fo(t,s,o,e),t.attr({z2:n.z2||0,silent:n.silent}),!1!==n.styleEmphasis&&eo(t,n.styleEmphasis)}function gm(t,e,i,n,o){null==i[t]||o||(e[t]=i[t],i[t]=n[t])}function mm(t,e,i,n){function o(t){null==t&&(t=h),v&&(c=e.getItemModel(t),d=c.getModel(bk),f=c.getModel(Sk),p=e.getItemVisual(t,"color"),v=!1)}var s=t.get("renderItem"),l=t.coordinateSystem,u={};l&&(u=l.prepareCustoms?l.prepareCustoms():Ik[l.type](l));var h,c,d,f,p,g=r({getWidth:n.getWidth,getHeight:n.getHeight,getZr:n.getZr,getDevicePixelRatio:n.getDevicePixelRatio,value:function(t,i){return null==i&&(i=h),e.get(e.getDimension(t||0),i)},style:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(_k).getItemStyle();null!=p&&(r.fill=p);var s=e.getItemVisual(n,"opacity");return null!=s&&(r.opacity=s),no(r,d,null,{autoColor:p,isRectText:!0}),r.text=d.getShallow("show")?D(t.getFormattedLabel(n,"normal"),ql(e,n)):null,i&&a(r,i),r},styleEmphasis:function(i,n){null==n&&(n=h),o(n);var r=c.getModel(wk).getItemStyle();return no(r,f,null,{isRectText:!0},!0),r.text=f.getShallow("show")?A(t.getFormattedLabel(n,"emphasis"),t.getFormattedLabel(n,"normal"),ql(e,n)):null,i&&a(r,i),r},visual:function(t,i){return null==i&&(i=h),e.getItemVisual(i,t)},barLayout:function(t){if(l.getBaseAxis)return rl(r({axis:l.getBaseAxis()},t),n)},currentSeriesIndices:function(){return i.getCurrentSeriesIndices()},font:function(t){return ho(t,i)}},u.api||{}),m={context:{},seriesId:t.id,seriesName:t.name,seriesIndex:t.seriesIndex,coordSys:u.coordSys,dataInsideLength:e.count(),encode:vm(t.getData())},v=!0;return function(t){return h=t,v=!0,s&&s(r({dataIndexInside:t,dataIndex:e.getRawIndex(t)},m),g)||{}}}function vm(t){var e={};return d(t.dimensions,function(i,n){var o=t.getDimensionInfo(i);if(!o.isExtraCoord){var a=o.coordDim;(e[a]=e[a]||[])[o.coordDimIndex]=n}}),e}function ym(t,e,i,n,o,a){return(t=xm(t,e,i,n,o,a))&&a.setItemGraphicEl(e,t),t}function xm(t,e,i,n,o,a){var r=i.type;if(!t||r===t.__customGraphicType||"path"===r&&i.pathData===t.__customPathData||"image"===r&&i.style.image===t.__customImagePath||"text"===r&&i.style.text===t.__customText||(o.remove(t),t=null),null!=r){var s=!t;if(!t&&(t=fm(i)),pm(t,e,i,n,a,s),"group"===r){var l=t.children()||[],u=i.children||[];if(i.diffChildrenByName)_m({oldChildren:l,newChildren:u,dataIndex:e,animatableModel:n,group:t,data:a});else{for(var h=0;hn?t-=l+a:t+=a),null!=r&&(e+u+r>o?e-=u+r:e+=r),[t,e]}function Um(t,e,i,n,o){var a=Xm(i),r=a.width,s=a.height;return t=Math.min(t+r,n)-r,e=Math.min(e+s,o)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function Xm(t){var e=t.clientWidth,i=t.clientHeight;if(document.defaultView&&document.defaultView.getComputedStyle){var n=document.defaultView.getComputedStyle(t);n&&(e+=parseInt(n.paddingLeft,10)+parseInt(n.paddingRight,10)+parseInt(n.borderLeftWidth,10)+parseInt(n.borderRightWidth,10),i+=parseInt(n.paddingTop,10)+parseInt(n.paddingBottom,10)+parseInt(n.borderTopWidth,10)+parseInt(n.borderBottomWidth,10))}return{width:e,height:i}}function jm(t,e,i){var n=i[0],o=i[1],a=0,r=0,s=e.width,l=e.height;switch(t){case"inside":a=e.x+s/2-n/2,r=e.y+l/2-o/2;break;case"top":a=e.x+s/2-n/2,r=e.y-o-5;break;case"bottom":a=e.x+s/2-n/2,r=e.y+l+5;break;case"left":a=e.x-n-5,r=e.y+l/2-o/2;break;case"right":a=e.x+s+5,r=e.y+l/2-o/2}return[a,r]}function Ym(t){return"center"===t||"middle"===t}function qm(t){return t.get("stack")||"__ec_stack_"+t.seriesIndex}function Km(t){return t.dim}function $m(t,e){var i={};d(t,function(t,e){var n=t.getData(),o=t.coordinateSystem.getBaseAxis(),a=o.getExtent(),r="category"===o.type?o.getBandWidth():Math.abs(a[1]-a[0])/n.count(),s=i[Km(o)]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},l=s.stacks;i[Km(o)]=s;var u=qm(t);l[u]||s.autoWidthCount++,l[u]=l[u]||{width:0,maxWidth:0};var h=Do(t.get("barWidth"),r),c=Do(t.get("barMaxWidth"),r),d=t.get("barGap"),f=t.get("barCategoryGap");h&&!l[u].width&&(h=Math.min(s.remainedWidth,h),l[u].width=h,s.remainedWidth-=h),c&&(l[u].maxWidth=c),null!=d&&(s.gap=d),null!=f&&(s.categoryGap=f)});var n={};return d(i,function(t,e){n[e]={};var i=t.stacks,o=t.bandWidth,a=Do(t.categoryGap,o),r=Do(t.gap,1),s=t.remainedWidth,l=t.autoWidthCount,u=(s-a)/(l+(l-1)*r);u=Math.max(u,0),d(i,function(t,e){var i=t.maxWidth;i&&ie[0]&&(e=e.slice().reverse());var n=t.coordToPoint([e[0],i]),o=t.coordToPoint([e[1],i]);return{x1:n[0],y1:n[1],x2:o[0],y2:o[1]}}function av(t){return t.getRadiusAxis().inverse?0:1}function rv(t){var e=t[0],i=t[t.length-1];e&&i&&Math.abs(Math.abs(e.coord-i.coord)-360)<1e-4&&t.pop()}function sv(t,e,i){return{position:[t.cx,t.cy],rotation:i/180*Math.PI,labelDirection:-1,tickDirection:-1,nameDirection:1,labelRotate:e.getModel("axisLabel").get("rotate"),z2:1}}function lv(t,e,i,n,o){var a=e.axis,r=a.dataToCoord(t),s=n.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=n.getRadiusAxis().getExtent();if("radius"===a.dim){var d=st();dt(d,d,s),ct(d,d,[n.cx,n.cy]),l=mo([r,-o],d);var f=e.getModel("axisLabel").get("rotate")||0,p=LD.innerTextLayout(s,f*Math.PI/180,-1);u=p.textAlign,h=p.textVerticalAlign}else{var g=c[1];l=n.coordToPoint([g+o,r]);var m=n.cx,v=n.cy;u=Math.abs(l[0]-m)/g<.3?"center":l[0]>m?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}function uv(t,e){e.update="updateView",cs(e,function(e,i){var n={};return i.eachComponent({mainType:"geo",query:e},function(i){i[t](e.name),d(i.coordinateSystem.regions,function(t){n[t.name]=i.isSelected(t.name)||!1})}),{selected:n,name:e.name}})}function hv(t){var e={};d(t,function(t){e[t]=1}),t.length=0,d(e,function(e,i){t.push(i)})}function cv(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function dv(t,e,n){function o(){var t=function(){};return t.prototype.__hidden=t.prototype,new t}var a={};return tP(e,function(e){var r=a[e]=o();tP(t[e],function(t,o){if(ZA.isValidType(o)){var a={type:o,visual:t};n&&n(a,e),r[o]=new ZA(a),"opacity"===o&&((a=i(a)).type="colorAlpha",r.__hidden.__alphaForOpacity=new ZA(a))}})}),a}function fv(t,e,n){var o;d(n,function(t){e.hasOwnProperty(t)&&cv(e[t])&&(o=!0)}),o&&d(n,function(n){e.hasOwnProperty(n)&&cv(e[n])?t[n]=i(e[n]):delete t[n]})}function pv(t,e,i,n,o,a){function r(t){return i.getItemVisual(h,t)}function s(t,e){i.setItemVisual(h,t,e)}function l(t,l){h=null==a?t:l;var c=i.getRawDataItem(h);if(!c||!1!==c.visualMap)for(var d=n.call(o,t),f=e[d],p=u[d],g=0,m=p.length;g1)return!1;var h=wv(i-t,o-t,n-e,a-e)/l;return!(h<0||h>1)}function _v(t){return t<=1e-6&&t>=-1e-6}function wv(t,e,i,n){return t*n-e*i}function bv(t,e,i){var n=this._targetInfoList=[],o={},a=Mv(e,t);iP(lP,function(t,e){(!i||!i.include||nP(i.include,e)>=0)&&t(a,n,o)})}function Sv(t){return t[0]>t[1]&&t.reverse(),t}function Mv(t,e){return Oi(t,e,{includeMainTypes:rP})}function Iv(t,e,i,n){var o=i.getAxis(["x","y"][t]),a=Sv(f([0,1],function(t){return e?o.coordToData(o.toLocalCoord(n[t])):o.toGlobalCoord(o.dataToCoord(n[t]))})),r=[];return r[t]=a,r[1-t]=[NaN,NaN],{values:a,xyMinMax:r}}function Tv(t,e,i,n){return[e[0]-n[t]*i[0],e[1]-n[t]*i[1]]}function Dv(t,e){var i=Av(t),n=Av(e),o=[i[0]/n[0],i[1]/n[1]];return isNaN(o[0])&&(o[0]=1),isNaN(o[1])&&(o[1]=1),o}function Av(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}function Cv(t,e,i,n,o){if(o){var a=t.getZr();a[gP]||(a[pP]||(a[pP]=Lv),wr(a,pP,i,e)(t,n))}}function Lv(t,e){if(!t.isDisposed()){var i=t.getZr();i[gP]=!0,t.dispatchAction({type:"brushSelect",batch:e}),i[gP]=!1}}function kv(t,e,i,n){for(var o=0,a=e.length;o=0}function Uv(t,e,i){function n(t,e){return l(e.nodes,t)>=0}function o(t,n){var o=!1;return e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]&&(o=!0)})}),o}function a(t,n){n.nodes.push(t),e(function(e){d(i(t,e)||[],function(t){n.records[e.name][t]=!0})})}return function(i){var r={nodes:[],records:{}};if(e(function(t){r.records[t.name]={}}),!i)return r;a(i,r);var s;do{s=!1,t(function(t){!n(t,r)&&o(t,r)&&(a(t,r),s=!0)})}while(s);return r}}function Xv(t,e,i){var n=[1/0,-1/0];return DP(i,function(t){var i=t.getData();i&&DP(i.mapDimension(e,!0),function(t){var e=i.getApproximateExtent(t);e[0]n[1]&&(n[1]=e[1])})}),n[1]0?0:NaN);var r=i.getMax(!0);return null!=r&&"dataMax"!==r&&"function"!=typeof r?e[1]=r:o&&(e[1]=a>0?a-1:NaN),i.get("scale",!0)||(e[0]>0&&(e[0]=0),e[1]<0&&(e[1]=0)),e}function Yv(t,e){var i=t.getAxisModel(),n=t._percentWindow,o=t._valueWindow;if(n){var a=Po(o,[0,500]);a=Math.min(a,20);var r=e||0===n[0]&&100===n[1];i.setRange(r?null:+o[0].toFixed(a),r?null:+o[1].toFixed(a))}}function qv(t){var e=t._minMaxSpan={},i=t._dataZoomModel;DP(["min","max"],function(n){e[n+"Span"]=i.get(n+"Span");var o=i.get(n+"ValueSpan");if(null!=o&&(e[n+"ValueSpan"]=o,null!=(o=t.getAxisModel().axis.scale.parse(o)))){var a=t._dataExtent;e[n+"Span"]=To(a[0]+o,a,[0,100],!0)}})}function Kv(t){var e={};return LP(["start","end","startValue","endValue","throttle"],function(i){t.hasOwnProperty(i)&&(e[i]=t[i])}),e}function $v(t,e){var i=t._rangePropMode,n=t.get("rangeMode");LP([["start","startValue"],["end","endValue"]],function(t,o){var a=null!=e[t[0]],r=null!=e[t[1]];a&&!r?i[o]="percent":!a&&r?i[o]="value":n?i[o]=n[o]:a&&(i[o]="percent")})}function Jv(t){return{x:"y",y:"x",radius:"angle",angle:"radius"}[t]}function Qv(t){return"vertical"===t?"ns-resize":"ew-resize"}function ty(t,e){var i=ny(t),n=e.dataZoomId,o=e.coordId;d(i,function(t,i){var a=t.dataZoomInfos;a[n]&&l(e.allCoordIds,o)<0&&(delete a[n],t.count--)}),ay(i);var a=i[o];a||((a=i[o]={coordId:o,dataZoomInfos:{},count:0}).controller=oy(t,a),a.dispatchAction=v(uy,t)),!a.dataZoomInfos[n]&&a.count++,a.dataZoomInfos[n]=e;var r=hy(a.dataZoomInfos);a.controller.enable(r.controlType,r.opt),a.controller.setPointerChecker(e.containsPoint),wr(a,"dispatchAction",e.throttleRate,"fixRate")}function ey(t,e){var i=ny(t);d(i,function(t){t.controller.dispose();var i=t.dataZoomInfos;i[e]&&(delete i[e],t.count--)}),ay(i)}function iy(t){return t.type+"\0_"+t.id}function ny(t){var e=t.getZr();return e[ZP]||(e[ZP]={})}function oy(t,e){var i=new kh(t.getZr());return i.on("pan",HP(ry,e)),i.on("zoom",HP(sy,e)),i}function ay(t){d(t,function(e,i){e.count||(e.controller.dispose(),delete t[i])})}function ry(t,e,i,n,o,a,r){ly(t,function(s){return s.panGetRange(t.controller,e,i,n,o,a,r)})}function sy(t,e,i,n){ly(t,function(o){return o.zoomGetRange(t.controller,e,i,n)})}function ly(t,e){var i=[];d(t.dataZoomInfos,function(t){var n=e(t);!t.disabled&&n&&i.push({dataZoomId:t.dataZoomId,start:n[0],end:n[1]})}),i.length&&t.dispatchAction(i)}function uy(t,e){t.dispatchAction({type:"dataZoom",batch:e})}function hy(t){var e,i={},n={type_true:2,type_move:1,type_false:0,type_undefined:-1};return d(t,function(t){var o=!t.disabled&&(!t.zoomLock||"move");n["type_"+o]>n["type_"+e]&&(e=o),a(i,t.roamControllerOpt)}),{controlType:e,opt:i}}function cy(t,e){return t&&t.hasOwnProperty&&t.hasOwnProperty(e)}function dy(t,e,i,n){for(var o=e.targetVisuals[n],a=ZA.prepareVisualTypes(o),r={color:t.getData().getVisual("color")},s=0,l=a.length;s=0&&(r[a]=+r[a].toFixed(h)),r}function Dy(t,e){var n=t.getData(),o=t.coordinateSystem;if(e&&!Iy(e)&&!y(e.coord)&&o){var a=o.dimensions,r=Ay(e,n,o,t);if((e=i(e)).type&&MN[e.type]&&r.baseAxis&&r.valueAxis){var s=bN(a,r.baseAxis.dim),l=bN(a,r.valueAxis.dim);e.coord=MN[e.type](n,r.baseDataDim,r.valueDataDim,s,l),e.value=e.coord[l]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)MN[u[h]]&&(u[h]=Py(n,n.mapDimension(a[h]),u[h]));e.coord=u}}return e}function Ay(t,e,i,n){var o={};return null!=t.valueIndex||null!=t.valueDim?(o.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,o.valueAxis=i.getAxis(Cy(n,o.valueDataDim)),o.baseAxis=i.getOtherAxis(o.valueAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim)):(o.baseAxis=n.getBaseAxis(),o.valueAxis=i.getOtherAxis(o.baseAxis),o.baseDataDim=e.mapDimension(o.baseAxis.dim),o.valueDataDim=e.mapDimension(o.valueAxis.dim)),o}function Cy(t,e){var i=t.getData(),n=i.dimensions;e=i.getDimension(e);for(var o=0;o=0)return!0}function sx(t){for(var e=t.split(/\n+/g),i=[],n=f(ax(e.shift()).split(ZN),function(t){return{name:t,data:[]}}),o=0;o=0&&!i[o][n];o--);if(o<0){var a=t.queryComponents({mainType:"dataZoom",subType:"select",id:n})[0];if(a){var r=a.getPercentRange();i[0][n]={dataZoomId:n,start:r[0],end:r[1]}}}}),i.push(e)}function fx(t){var e=mx(t),i=e[e.length-1];e.length>1&&e.pop();var n={};return UN(i,function(t,i){for(var o=e.length-1;o>=0;o--)if(t=e[o][i]){n[i]=t;break}}),n}function px(t){t[XN]=null}function gx(t){return mx(t).length}function mx(t){var e=t[XN];return e||(e=t[XN]=[{}]),e}function vx(t,e,i){(this._brushController=new Qd(i.getZr())).on("brush",m(this._onBrush,this)).mount(),this._isZoomActive}function yx(t){var e={};return d(["xAxisIndex","yAxisIndex"],function(i){e[i]=t[i],null==e[i]&&(e[i]="all"),(!1===e[i]||"none"===e[i])&&(e[i]=[])}),e}function xx(t,e){t.setIconStatus("back",gx(e)>1?"emphasis":"normal")}function _x(t,e,i,n,o){var a=i._isZoomActive;n&&"takeGlobalCursor"===n.type&&(a="dataZoomSelect"===n.key&&n.dataZoomSelectActive),i._isZoomActive=a,t.setIconStatus("zoom",a?"emphasis":"normal");var r=new bv(yx(t.option),e,{include:["grid"]});i._brushController.setPanels(r.makePanelOpts(o,function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"})).enableBrush(!!a&&{brushType:"auto",brushStyle:{lineWidth:0,fill:"rgba(0,0,0,0.2)"}})}function bx(t){this.model=t}function Sx(t){return QN(t)}function Mx(){if(!iO&&nO){iO=!0;var t=nO.styleSheets;t.length<31?nO.createStyleSheet().addRule(".zrvml","behavior:url(#default#VML)"):t[0].addRule(".zrvml","behavior:url(#default#VML)")}}function Ix(t){return parseInt(t,10)}function Tx(t,e){Mx(),this.root=t,this.storage=e;var i=document.createElement("div"),n=document.createElement("div");i.style.cssText="display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;",n.style.cssText="position:absolute;left:0;top:0;",t.appendChild(i),this._vmlRoot=n,this._vmlViewport=i,this.resize();var o=e.delFromStorage,a=e.addToStorage;e.delFromStorage=function(t){o.call(e,t),t&&t.onRemove&&t.onRemove(n)},e.addToStorage=function(t){t.onAdd&&t.onAdd(n),a.call(e,t)},this._firstPaint=!0}function Dx(t){return function(){ew('In IE8.0 VML mode painter not support method "'+t+'"')}}function Ax(t){return document.createElementNS(zO,t)}function Cx(t){return WO(1e4*t)/1e4}function Lx(t){return t-jO}function kx(t,e){var i=e?t.textFill:t.fill;return null!=i&&i!==GO}function Px(t,e){var i=e?t.textStroke:t.stroke;return null!=i&&i!==GO}function Nx(t,e){e&&Ox(t,"transform","matrix("+VO.call(e,",")+")")}function Ox(t,e,i){(!i||"linear"!==i.type&&"radial"!==i.type)&&("string"==typeof i&&i.indexOf("NaN")>-1&&console.log(i),t.setAttribute(e,i))}function Ex(t,e,i){t.setAttributeNS("http://www.w3.org/1999/xlink",e,i)}function Rx(t,e,i){if(kx(e,i)){var n=i?e.textFill:e.fill;n="transparent"===n?GO:n,"none"!==t.getAttribute("clip-path")&&n===GO&&(n="rgba(0, 0, 0, 0.002)"),Ox(t,"fill",n),Ox(t,"fill-opacity",e.opacity)}else Ox(t,"fill",GO);if(Px(e,i)){var o=i?e.textStroke:e.stroke;Ox(t,"stroke",o="transparent"===o?GO:o),Ox(t,"stroke-width",(i?e.textStrokeWidth:e.lineWidth)/(!i&&e.strokeNoScale?e.host.getLineScale():1)),Ox(t,"paint-order",i?"stroke":"fill"),Ox(t,"stroke-opacity",e.opacity),e.lineDash?(Ox(t,"stroke-dasharray",e.lineDash.join(",")),Ox(t,"stroke-dashoffset",WO(e.lineDashOffset||0))):Ox(t,"stroke-dasharray",""),e.lineCap&&Ox(t,"stroke-linecap",e.lineCap),e.lineJoin&&Ox(t,"stroke-linejoin",e.lineJoin),e.miterLimit&&Ox(t,"stroke-miterlimit",e.miterLimit)}else Ox(t,"stroke",GO)}function zx(t){for(var e=[],i=t.data,n=t.len(),o=0;o=UO||!Lx(g)&&(d>-ZO&&d<0||d>ZO)==!!p;var y=Cx(s+u*HO(c)),x=Cx(l+h*FO(c));m&&(d=p?UO-1e-4:1e-4-UO,v=!0,9===o&&e.push("M",y,x));var _=Cx(s+u*HO(c+d)),w=Cx(l+h*FO(c+d));e.push("A",Cx(u),Cx(h),WO(f*XO),+v,+p,_,w);break;case BO.Z:a="Z";break;case BO.R:var _=Cx(i[o++]),w=Cx(i[o++]),b=Cx(i[o++]),S=Cx(i[o++]);e.push("M",_,w,"L",_+b,w,"L",_+b,w+S,"L",_,w+S,"L",_,w)}a&&e.push(a);for(var M=0;M=11)}}(navigator.userAgent),r_={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1,"[object CanvasPattern]":1,"[object Image]":1,"[object Canvas]":1},s_={"[object Int8Array]":1,"[object Uint8Array]":1,"[object Uint8ClampedArray]":1,"[object Int16Array]":1,"[object Uint16Array]":1,"[object Int32Array]":1,"[object Uint32Array]":1,"[object Float32Array]":1,"[object Float64Array]":1},l_=Object.prototype.toString,u_=Array.prototype,h_=u_.forEach,c_=u_.filter,d_=u_.slice,f_=u_.map,p_=u_.reduce,g_={},m_=function(){return g_.createCanvas()};g_.createCanvas=function(){return document.createElement("canvas")};var v_,y_="__ec_primitive__";E.prototype={constructor:E,get:function(t){return this.hasOwnProperty(t)?this[t]:null},set:function(t,e){return this[t]=e},each:function(t,e){void 0!==e&&(t=m(t,e));for(var i in this)this.hasOwnProperty(i)&&t(this[i],i)},removeKey:function(t){delete this[t]}};var x_=(Object.freeze||Object)({$override:e,clone:i,merge:n,mergeAll:o,extend:a,defaults:r,createCanvas:m_,getContext:s,indexOf:l,inherits:u,mixin:h,isArrayLike:c,each:d,map:f,reduce:p,filter:g,find:function(t,e,i){if(t&&e)for(var n=0,o=t.length;n3&&(e=T_.call(e,1));for(var n=this._$handlers[t],o=n.length,a=0;a4&&(e=T_.call(e,1,e.length-1));for(var n=e[e.length-1],o=this._$handlers[t],a=o.length,r=0;r=0;a--){var r;if(n[a]!==i&&!n[a].ignore&&(r=rt(n[a],t,e))&&(!o.topTarget&&(o.topTarget=n[a]),r!==A_)){o.target=n[a];break}}return o}},d(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){L_.prototype[t]=function(e){var i=this.findHover(e.zrX,e.zrY),n=i.target;if("mousedown"===t)this._downEl=n,this._downPoint=[e.zrX,e.zrY],this._upEl=n;else if("mouseup"===t)this._upEl=n;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||S_(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(i,t,e)}}),h(L_,D_),h(L_,it);var k_="undefined"==typeof Float32Array?Array:Float32Array,P_=(Object.freeze||Object)({create:st,identity:lt,copy:ut,mul:ht,translate:ct,rotate:dt,scale:ft,invert:pt,clone:gt}),N_=lt,O_=5e-5,E_=function(t){(t=t||{}).position||(this.position=[0,0]),null==t.rotation&&(this.rotation=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},R_=E_.prototype;R_.transform=null,R_.needLocalTransform=function(){return mt(this.rotation)||mt(this.position[0])||mt(this.position[1])||mt(this.scale[0]-1)||mt(this.scale[1]-1)},R_.updateTransform=function(){var t=this.parent,e=t&&t.transform,i=this.needLocalTransform(),n=this.transform;i||e?(n=n||st(),i?this.getLocalTransform(n):N_(n),e&&(i?ht(n,t.transform,n):ut(n,t.transform)),this.transform=n,this.invTransform=this.invTransform||st(),pt(this.invTransform,n)):n&&N_(n)},R_.getLocalTransform=function(t){return E_.getLocalTransform(this,t)},R_.setTransform=function(t){var e=this.transform,i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},R_.restoreTransform=function(t){var e=t.dpr||1;t.setTransform(e,0,0,e,0,0)};var z_=[];R_.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(ht(z_,t.invTransform,e),e=z_);var i=e[0]*e[0]+e[1]*e[1],n=e[2]*e[2]+e[3]*e[3],o=this.position,a=this.scale;mt(i-1)&&(i=Math.sqrt(i)),mt(n-1)&&(n=Math.sqrt(n)),e[0]<0&&(i=-i),e[3]<0&&(n=-n),o[0]=e[4],o[1]=e[5],a[0]=i,a[1]=n,this.rotation=Math.atan2(-e[1]/n,e[0]/i)}},R_.getGlobalScale=function(){var t=this.transform;if(!t)return[1,1];var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]),i=Math.sqrt(t[2]*t[2]+t[3]*t[3]);return t[0]<0&&(e=-e),t[3]<0&&(i=-i),[e,i]},R_.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&Q(i,i,n),i},R_.transformCoordToGlobal=function(t,e){var i=[t,e],n=this.transform;return n&&Q(i,i,n),i},E_.getLocalTransform=function(t,e){N_(e=e||[]);var i=t.origin,n=t.scale||[1,1],o=t.rotation||0,a=t.position||[0,0];return i&&(e[4]-=i[0],e[5]-=i[1]),ft(e,e,n),o&&dt(e,e,o),i&&(e[4]+=i[0],e[5]+=i[1]),e[4]+=a[0],e[5]+=a[1],e};var B_={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,i=.1;return 0===t?0:1===t?1:(!i||i<1?(i=1,e=.1):e=.4*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-B_.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*B_.bounceIn(2*t):.5*B_.bounceOut(2*t-1)+.5}};vt.prototype={constructor:vt,step:function(t,e){if(this._initialized||(this._startTime=t+this._delay,this._initialized=!0),this._paused)this._pausedTime+=e;else{var i=(t-this._startTime-this._pausedTime)/this._life;if(!(i<0)){i=Math.min(i,1);var n=this.easing,o="string"==typeof n?B_[n]:n,a="function"==typeof o?o(i):i;return this.fire("frame",a),1==i?this.loop?(this.restart(t),"restart"):(this._needsRemove=!0,"destroy"):null}}},restart:function(t){var e=(t-this._startTime-this._pausedTime)%this._life;this._startTime=t-e+this.gap,this._pausedTime=0,this._needsRemove=!1},fire:function(t,e){this[t="on"+t]&&this[t](this._target,e)},pause:function(){this._paused=!0},resume:function(){this._paused=!1}};var V_=function(){this.head=null,this.tail=null,this._len=0},G_=V_.prototype;G_.insert=function(t){var e=new W_(t);return this.insertEntry(e),e},G_.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},G_.remove=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},G_.len=function(){return this._len},G_.clear=function(){this.head=this.tail=null,this._len=0};var W_=function(t){this.value=t,this.next,this.prev},F_=function(t){this._list=new V_,this._map={},this._maxSize=t||10,this._lastRemovedEntry=null},H_=F_.prototype;H_.put=function(t,e){var i=this._list,n=this._map,o=null;if(null==n[t]){var a=i.len(),r=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=i.head;i.remove(s),delete n[s.key],o=s.value,this._lastRemovedEntry=s}r?r.value=e:r=new W_(e),r.key=t,i.insertEntry(r),n[t]=r}return o},H_.get=function(t){var e=this._map[t],i=this._list;if(null!=e)return e!==i.tail&&(i.remove(e),i.insertEntry(e)),e.value},H_.clear=function(){this._list.clear(),this._map={}};var Z_={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},U_=new F_(20),X_=null,j_=Nt,Y_=Ot,q_=(Object.freeze||Object)({parse:At,lift:kt,toHex:Pt,fastLerp:Nt,fastMapToColor:j_,lerp:Ot,mapToColor:Y_,modifyHSL:Et,modifyAlpha:Rt,stringify:zt}),K_=Array.prototype.slice,$_=function(t,e,i,n){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||Bt,this._setter=n||Vt,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};$_.prototype={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var o=this._getter(this._target,n);if(null==o)continue;0!==t&&i[n].push({time:0,value:jt(o)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},pause:function(){for(var t=0;t0&&this.animate(t,!1).when(null==n?500:n,a).delay(o||0),this}};var nw=function(t){E_.call(this,t),D_.call(this,t),iw.call(this,t),this.id=t.id||n_()};nw.prototype={type:"element",name:"",__zr:null,ignore:!1,clipPath:null,isGroup:!1,drift:function(t,e){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.dirty(!1)},beforeUpdate:function(){},afterUpdate:function(){},update:function(){this.updateTransform()},traverse:function(t,e){},attrKV:function(t,e){if("position"===t||"scale"===t||"origin"===t){if(e){var i=this[t];i||(i=this[t]=[]),i[0]=e[0],i[1]=e[1]}}else this[t]=e},hide:function(){this.ignore=!0,this.__zr&&this.__zr.refresh()},show:function(){this.ignore=!1,this.__zr&&this.__zr.refresh()},attr:function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(w(t))for(var i in t)t.hasOwnProperty(i)&&this.attrKV(i,t[i]);return this.dirty(!1),this},setClipPath:function(t){var e=this.__zr;e&&t.addSelfToZr(e),this.clipPath&&this.clipPath!==t&&this.removeClipPath(),this.clipPath=t,t.__zr=e,t.__clipTarget=this,this.dirty(!1)},removeClipPath:function(){var t=this.clipPath;t&&(t.__zr&&t.removeSelfFromZr(t.__zr),t.__zr=null,t.__clipTarget=null,this.clipPath=null,this.dirty(!1))},addSelfToZr:function(t){this.__zr=t;var e=this.animators;if(e)for(var i=0;i=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new $t(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},$t.create=function(t){return new $t(t.x,t.y,t.width,t.height)};var sw=function(t){t=t||{},nw.call(this,t);for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};sw.prototype={constructor:sw,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i=0&&(i.splice(n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToStorage(t),t instanceof sw&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var e=this.__zr,i=this.__storage,n=this._children,o=l(n,t);return o<0?this:(n.splice(o,1),t.parent=null,i&&(i.delFromStorage(t),t instanceof sw&&t.delChildrenFromStorage(i)),e&&e.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;e=0&&(this.delFromStorage(t),this._roots.splice(o,1),t instanceof sw&&t.delChildrenFromStorage(this))}},addToStorage:function(t){return t&&(t.__storage=this,t.dirty(!1)),this},delFromStorage:function(t){return t&&(t.__storage=null),this},dispose:function(){this._renderList=this._roots=null},displayableSortFunc:re};var cw={shadowBlur:1,shadowOffsetX:1,shadowOffsetY:1,textShadowBlur:1,textShadowOffsetX:1,textShadowOffsetY:1,textBoxShadowBlur:1,textBoxShadowOffsetX:1,textBoxShadowOffsetY:1},dw=function(t,e,i){return cw.hasOwnProperty(e)?i*=t.dpr:i},fw=[["shadowBlur",0],["shadowOffsetX",0],["shadowOffsetY",0],["shadowColor","#000"],["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]],pw=function(t,e){this.extendFrom(t,!1),this.host=e};pw.prototype={constructor:pw,host:null,fill:"#000",stroke:null,opacity:1,lineDash:null,lineDashOffset:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,lineWidth:1,strokeNoScale:!1,text:null,font:null,textFont:null,fontStyle:null,fontWeight:null,fontSize:null,fontFamily:null,textTag:null,textFill:"#000",textStroke:null,textWidth:null,textHeight:null,textStrokeWidth:0,textLineHeight:null,textPosition:"inside",textRect:null,textOffset:null,textAlign:null,textVerticalAlign:null,textDistance:5,textShadowColor:"transparent",textShadowBlur:0,textShadowOffsetX:0,textShadowOffsetY:0,textBoxShadowColor:"transparent",textBoxShadowBlur:0,textBoxShadowOffsetX:0,textBoxShadowOffsetY:0,transformText:!1,textRotation:0,textOrigin:null,textBackgroundColor:null,textBorderColor:null,textBorderWidth:0,textBorderRadius:0,textPadding:null,rich:null,truncate:null,blend:null,bind:function(t,e,i){for(var n=this,o=i&&i.style,a=!o,r=0;r0},extendFrom:function(t,e){if(t)for(var i in t)!t.hasOwnProperty(i)||!0!==e&&(!1===e?this.hasOwnProperty(i):null==t[i])||(this[i]=t[i])},set:function(t,e){"string"==typeof t?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(t,e,i){for(var n=("radial"===e.type?le:se)(t,e,i),o=e.colorStops,a=0;a=0&&i.splice(n,1),t.__hoverMir=null},clearHover:function(t){for(var e=this._hoverElements,i=0;i15)break}s.__drawIndex=m,s.__drawIndex0&&t>n[0]){for(r=0;rt);r++);a=i[n[r]]}if(n.splice(r+1,0,t),i[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?s.insertBefore(e.dom,l.nextSibling):s.appendChild(e.dom)}else s.firstChild?s.insertBefore(e.dom,s.firstChild):s.appendChild(e.dom)}else ew("Layer of zlevel "+t+" is not valid")},eachLayer:function(t,e){var i,n,o=this._zlevelList;for(n=0;n0?.01:0),this._needsManuallyCompositing),a.__builtin__||ew("ZLevel "+s+" has been used by unkown layer "+a.id),a!==i&&(a.__used=!0,a.__startIndex!==o&&(a.__dirty=!0),a.__startIndex=o,a.incremental?a.__drawIndex=-1:a.__drawIndex=o,e(o),i=a),r.__dirty&&(a.__dirty=!0,a.incremental&&a.__drawIndex<0&&(a.__drawIndex=o))}e(o),this.eachBuiltinLayer(function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)})},clear:function(){return this.eachBuiltinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},setBackgroundColor:function(t){this._backgroundColor=t},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?n(i[t],e,!0):i[t]=e;for(var o=0;o=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;i1&&n&&n.length>1){var a=di(n)/di(o);!isFinite(a)&&(a=1),e.pinchScale=a;var r=fi(n);return e.pinchX=r[0],e.pinchY=r[1],{type:"pinch",target:t[0].target,event:e}}}}},Ww=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],Fw=["touchstart","touchend","touchmove"],Hw={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},Zw=f(Ww,function(t){var e=t.replace("mouse","pointer");return Hw[e]?e:t}),Uw={mousemove:function(t){t=li(this.dom,t),this.trigger("mousemove",t)},mouseout:function(t){var e=(t=li(this.dom,t)).toElement||t.relatedTarget;if(e!=this.dom)for(;e&&9!=e.nodeType;){if(e===this.dom)return;e=e.parentNode}this.trigger("mouseout",t)},touchstart:function(t){(t=li(this.dom,t)).zrByTouch=!0,this._lastTouchMoment=new Date,gi(this,t,"start"),Uw.mousemove.call(this,t),Uw.mousedown.call(this,t),mi(this)},touchmove:function(t){(t=li(this.dom,t)).zrByTouch=!0,gi(this,t,"change"),Uw.mousemove.call(this,t),mi(this)},touchend:function(t){(t=li(this.dom,t)).zrByTouch=!0,gi(this,t,"end"),Uw.mouseup.call(this,t),+new Date-this._lastTouchMoment<300&&Uw.click.call(this,t),mi(this)},pointerdown:function(t){Uw.mousedown.call(this,t)},pointermove:function(t){vi(t)||Uw.mousemove.call(this,t)},pointerup:function(t){Uw.mouseup.call(this,t)},pointerout:function(t){vi(t)||Uw.mouseout.call(this,t)}};d(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){Uw[t]=function(e){e=li(this.dom,e),this.trigger(t,e)}});var Xw=xi.prototype;Xw.dispose=function(){for(var t=Ww.concat(Fw),e=0;e=0||n&&l(n,r)<0)){var s=e.getShallow(r);null!=s&&(o[t[a][0]]=s)}}return o}},lb=sb([["lineWidth","width"],["stroke","color"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),ub={getLineStyle:function(t){var e=lb(this,t),i=this.getLineDash(e.lineWidth);return i&&(e.lineDash=i),e},getLineDash:function(t){null==t&&(t=1);var e=this.get("type"),i=Math.max(t,2),n=4*t;return"solid"===e||null==e?null:"dashed"===e?[n,n]:[i,i]}},hb=sb([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),cb={getAreaStyle:function(t,e){return hb(this,t,e)}},db=Math.pow,fb=Math.sqrt,pb=1e-8,gb=1e-4,mb=fb(3),vb=1/3,yb=V(),xb=V(),_b=V(),wb=Math.min,bb=Math.max,Sb=Math.sin,Mb=Math.cos,Ib=2*Math.PI,Tb=V(),Db=V(),Ab=V(),Cb=[],Lb=[],kb={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},Pb=[],Nb=[],Ob=[],Eb=[],Rb=Math.min,zb=Math.max,Bb=Math.cos,Vb=Math.sin,Gb=Math.sqrt,Wb=Math.abs,Fb="undefined"!=typeof Float32Array,Hb=function(t){this._saveData=!t,this._saveData&&(this.data=[]),this._ctx=null};Hb.prototype={constructor:Hb,_xi:0,_yi:0,_x0:0,_y0:0,_ux:0,_uy:0,_len:0,_lineDash:null,_dashOffset:0,_dashIdx:0,_dashSum:0,setScale:function(t,e){this._ux=Wb(1/Q_/t)||0,this._uy=Wb(1/Q_/e)||0},getContext:function(){return this._ctx},beginPath:function(t){return this._ctx=t,t&&t.beginPath(),t&&(this.dpr=t.dpr),this._saveData&&(this._len=0),this._lineDash&&(this._lineDash=null,this._dashOffset=0),this},moveTo:function(t,e){return this.addData(kb.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},lineTo:function(t,e){var i=Wb(t-this._xi)>this._ux||Wb(e-this._yi)>this._uy||this._len<5;return this.addData(kb.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,o,a){return this.addData(kb.C,t,e,i,n,o,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,o,a):this._ctx.bezierCurveTo(t,e,i,n,o,a)),this._xi=o,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(kb.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,o,a){return this.addData(kb.A,t,e,i,i,n,o-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,o,a),this._xi=Bb(o)*i+t,this._yi=Vb(o)*i+t,this},arcTo:function(t,e,i,n,o){return this._ctx&&this._ctx.arcTo(t,e,i,n,o),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(kb.R,t,e,i,n),this},closePath:function(){this.addData(kb.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;ie.length&&(this._expandData(),e=this.data);for(var i=0;i0&&f<=t||h<0&&f>=t||0==h&&(c>0&&p<=e||c<0&&p>=e);)f+=h*(i=r[n=this._dashIdx]),p+=c*i,this._dashIdx=(n+1)%g,h>0&&fl||c>0&&pu||s[n%2?"moveTo":"lineTo"](h>=0?Rb(f,t):zb(f,t),c>=0?Rb(p,e):zb(p,e));h=f-t,c=p-e,this._dashOffset=-Gb(h*h+c*c)},_dashedBezierTo:function(t,e,i,n,o,a){var r,s,l,u,h,c=this._dashSum,d=this._dashOffset,f=this._lineDash,p=this._ctx,g=this._xi,m=this._yi,v=ji,y=0,x=this._dashIdx,_=f.length,w=0;for(d<0&&(d=c+d),d%=c,r=0;r<1;r+=.1)s=v(g,t,i,o,r+.1)-v(g,t,i,o,r),l=v(m,e,n,a,r+.1)-v(m,e,n,a,r),y+=Gb(s*s+l*l);for(;x<_&&!((w+=f[x])>d);x++);for(r=(w-d)/y;r<=1;)u=v(g,t,i,o,r),h=v(m,e,n,a,r),x%2?p.moveTo(u,h):p.lineTo(u,h),r+=f[x]/y,x=(x+1)%_;x%2!=0&&p.lineTo(o,a),s=o-u,l=a-h,this._dashOffset=-Gb(s*s+l*l)},_dashedQuadraticTo:function(t,e,i,n){var o=i,a=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,o,a)},toStatic:function(){var t=this.data;t instanceof Array&&(t.length=this._len,Fb&&(this.data=new Float32Array(t)))},getBoundingRect:function(){Pb[0]=Pb[1]=Ob[0]=Ob[1]=Number.MAX_VALUE,Nb[0]=Nb[1]=Eb[0]=Eb[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,n=0,o=0,a=0;al||Wb(r-o)>u||c===h-1)&&(t.lineTo(a,r),n=a,o=r);break;case kb.C:t.bezierCurveTo(s[c++],s[c++],s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case kb.Q:t.quadraticCurveTo(s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case kb.A:var f=s[c++],p=s[c++],g=s[c++],m=s[c++],v=s[c++],y=s[c++],x=s[c++],_=s[c++],w=g>m?g:m,b=g>m?1:g/m,S=g>m?m/g:1,M=v+y;Math.abs(g-m)>.001?(t.translate(f,p),t.rotate(x),t.scale(b,S),t.arc(0,0,w,v,M,1-_),t.scale(1/b,1/S),t.rotate(-x),t.translate(-f,-p)):t.arc(f,p,w,v,M,1-_),1==c&&(e=Bb(v)*g+f,i=Vb(v)*m+p),n=Bb(M)*g+f,o=Vb(M)*m+p;break;case kb.R:e=n=s[c],i=o=s[c+1],t.rect(s[c++],s[c++],s[c++],s[c++]);break;case kb.Z:t.closePath(),n=e,o=i}}}},Hb.CMD=kb;var Zb=2*Math.PI,Ub=2*Math.PI,Xb=Hb.CMD,jb=2*Math.PI,Yb=1e-4,qb=[-1,-1,-1],Kb=[-1,-1],$b=yw.prototype.getCanvasPattern,Jb=Math.abs,Qb=new Hb(!0);In.prototype={constructor:In,type:"path",__dirtyPath:!0,strokeContainThreshold:5,brush:function(t,e){var i=this.style,n=this.path||Qb,o=i.hasStroke(),a=i.hasFill(),r=i.fill,s=i.stroke,l=a&&!!r.colorStops,u=o&&!!s.colorStops,h=a&&!!r.image,c=o&&!!s.image;if(i.bind(t,this,e),this.setTransform(t),this.__dirty){var d;l&&(d=d||this.getBoundingRect(),this._fillGradient=i.getGradient(t,r,d)),u&&(d=d||this.getBoundingRect(),this._strokeGradient=i.getGradient(t,s,d))}l?t.fillStyle=this._fillGradient:h&&(t.fillStyle=$b.call(r,t)),u?t.strokeStyle=this._strokeGradient:c&&(t.strokeStyle=$b.call(s,t));var f=i.lineDash,p=i.lineDashOffset,g=!!t.setLineDash,m=this.getGlobalScale();n.setScale(m[0],m[1]),this.__dirtyPath||f&&!g&&o?(n.beginPath(t),f&&!g&&(n.setLineDash(f),n.setLineDashOffset(p)),this.buildPath(n,this.shape,!1),this.path&&(this.__dirtyPath=!1)):(t.beginPath(),this.path.rebuildPath(t)),a&&n.fill(t),f&&g&&(t.setLineDash(f),t.lineDashOffset=p),o&&n.stroke(t),f&&g&&t.setLineDash([]),null!=i.text&&(this.restoreTransform(t),this.drawRectText(t,this.getBoundingRect()))},buildPath:function(t,e,i){},createPathProxy:function(){this.path=new Hb},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var n=this.path;n||(n=this.path=new Hb),this.__dirtyPath&&(n.beginPath(),this.buildPath(n,this.shape,!1)),t=n.getBoundingRect()}if(this._rect=t,e.hasStroke()){var o=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){o.copy(t);var a=e.lineWidth,r=e.strokeNoScale?this.getLineScale():1;e.hasFill()||(a=Math.max(a,this.strokeContainThreshold||4)),r>1e-10&&(o.width+=a/r,o.height+=a/r,o.x-=a/r/2,o.y-=a/r/2)}return o}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this.getBoundingRect(),o=this.style;if(t=i[0],e=i[1],n.contain(t,e)){var a=this.path.data;if(o.hasStroke()){var r=o.lineWidth,s=o.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(o.hasFill()||(r=Math.max(r,this.strokeContainThreshold)),Mn(a,r/s,t,e)))return!0}if(o.hasFill())return Sn(a,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):$e.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(w(t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&Jb(t[0]-1)>1e-10&&Jb(t[3]-1)>1e-10?Math.sqrt(Jb(t[0]*t[3]-t[2]*t[1])):1}},In.extend=function(t){var e=function(e){In.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var n=this.shape;for(var o in i)!n.hasOwnProperty(o)&&i.hasOwnProperty(o)&&(n[o]=i[o])}t.init&&t.init.call(this,e)};u(e,In);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},u(In,$e);var tS=Hb.CMD,eS=[[],[],[]],iS=Math.sqrt,nS=Math.atan2,oS=function(t,e){var i,n,o,a,r,s,l=t.data,u=tS.M,h=tS.C,c=tS.L,d=tS.R,f=tS.A,p=tS.Q;for(o=0,a=0;o=11?function(){var e,i=this.__clipPaths,n=this.style;if(i)for(var o=0;oi-2?i-1:c+1],u=t[c>i-3?i-1:c+2]);var p=d*d,g=d*p;n.push([kn(s[0],f[0],l[0],u[0],d,p,g),kn(s[1],f[1],l[1],u[1],d,p,g)])}return n},_S=function(t,e,i,n){var o,a,r,s,l=[],u=[],h=[],c=[];if(n){r=[1/0,1/0],s=[-1/0,-1/0];for(var d=0,f=t.length;d=i&&a>=o)return{x:i,y:o,width:n-i,height:a-o}},createIcon:_o,Group:sw,Image:Je,Text:fS,Circle:pS,Sector:vS,Ring:yS,Polygon:wS,Polyline:bS,Rect:SS,Line:MS,BezierCurve:TS,Arc:DS,IncrementalDisplayable:On,CompoundPath:AS,LinearGradient:LS,RadialGradient:kS,BoundingRect:$t}),VS=["textStyle","color"],GS={getTextColor:function(t){var e=this.ecModel;return this.getShallow("color")||(!t&&e?e.get(VS):null)},getFont:function(){return ho({fontStyle:this.getShallow("fontStyle"),fontWeight:this.getShallow("fontWeight"),fontSize:this.getShallow("fontSize"),fontFamily:this.getShallow("fontFamily")},this.ecModel)},getTextRect:function(t){return me(t,this.getFont(),this.getShallow("align"),this.getShallow("verticalAlign")||this.getShallow("baseline"),this.getShallow("padding"),this.getShallow("rich"),this.getShallow("truncateText"))}},WS=sb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"],["textPosition"],["textAlign"]]),FS={getItemStyle:function(t,e){var i=WS(this,t,e),n=this.getBorderLineDash();return n&&(i.lineDash=n),i},getBorderLineDash:function(){var t=this.get("borderType");return"solid"===t||null==t?null:"dashed"===t?[5,5]:[1,1]}},HS=h,ZS=Ni();wo.prototype={constructor:wo,init:null,mergeOption:function(t){n(this.option,t,!0)},get:function(t,e){return null==t?this.option:bo(this.option,this.parsePath(t),!e&&So(this,t))},getShallow:function(t,e){var i=this.option,n=null==i?i:i[t],o=!e&&So(this,t);return null==n&&o&&(n=o.getShallow(t)),n},getModel:function(t,e){var i,n=null==t?this.option:bo(this.option,t=this.parsePath(t));return e=e||(i=So(this,t))&&i.getModel(t),new wo(n,e,this.ecModel)},isEmpty:function(){return null==this.option},restoreData:function(){},clone:function(){return new(0,this.constructor)(i(this.option))},setReadOnly:function(t){},parsePath:function(t){return"string"==typeof t&&(t=t.split(".")),t},customizeGetParent:function(t){ZS(this).getParent=t},isAnimationEnabled:function(){if(!a_.node){if(null!=this.option.animation)return!!this.option.animation;if(this.parentModel)return this.parentModel.isAnimationEnabled()}}},Gi(wo),Wi(wo),HS(wo,ub),HS(wo,cb),HS(wo,GS),HS(wo,FS);var US=0,XS=1e-4,jS=9007199254740991,YS=/^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/,qS=(Object.freeze||Object)({linearMap:To,parsePercent:Do,round:Ao,asc:Co,getPrecision:Lo,getPrecisionSafe:ko,getPixelPrecision:Po,getPercentWithPrecision:No,MAX_SAFE_INTEGER:jS,remRadian:Oo,isRadianAroundZero:Eo,parseDate:Ro,quantity:zo,nice:Vo,quantile:function(t,e){var i=(t.length-1)*e+1,n=Math.floor(i),o=+t[n-1],a=i-n;return a?o+a*(t[n]-o):o},reformIntervals:Go,isNumeric:Wo}),KS=L,$S=/([&<>"'])/g,JS={"&":"&","<":"<",">":">",'"':""","'":"'"},QS=["a","b","c","d","e","f","g"],tM=function(t,e){return"{"+t+(null==e?"":e)+"}"},eM=be,iM=me,nM=(Object.freeze||Object)({addCommas:Fo,toCamelCase:Ho,normalizeCssArray:KS,encodeHTML:Zo,formatTpl:Uo,formatTplSimple:Xo,getTooltipMarker:jo,formatTime:qo,capitalFirst:Ko,truncateText:eM,getTextRect:iM}),oM=d,aM=["left","right","top","bottom","width","height"],rM=[["width","left","right"],["height","top","bottom"]],sM=$o,lM=(v($o,"vertical"),v($o,"horizontal"),{getBoxLayoutParams:function(){return{left:this.get("left"),top:this.get("top"),right:this.get("right"),bottom:this.get("bottom"),width:this.get("width"),height:this.get("height")}}}),uM=Ni(),hM=wo.extend({type:"component",id:"",name:"",mainType:"",subType:"",componentIndex:0,defaultOption:null,ecModel:null,dependentModels:[],uid:null,layoutMode:null,$constructor:function(t,e,i,n){wo.call(this,t,e,i,n),this.uid=Mo("ec_cpt_model")},init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i)},mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,o=i?na(t):{};n(t,e.getTheme().get(this.mainType)),n(t,this.getDefaultOption()),i&&ia(t,o,i)},mergeOption:function(t,e){n(this.option,t,!0);var i=this.layoutMode;i&&ia(this.option,t,i)},optionUpdated:function(t,e){},getDefaultOption:function(){var t=uM(this);if(!t.defaultOption){for(var e=[],i=this.constructor;i;){var o=i.prototype.defaultOption;o&&e.push(o),i=i.superClass}for(var a={},r=e.length-1;r>=0;r--)a=n(a,e[r],!0);t.defaultOption=a}return t.defaultOption},getReferringComponents:function(t){return this.ecModel.queryComponents({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});Zi(hM,{registerWhenExtend:!0}),function(t){var e={};t.registerSubTypeDefaulter=function(t,i){t=Bi(t),e[t.main]=i},t.determineSubType=function(i,n){var o=n.type;if(!o){var a=Bi(i).main;t.hasSubTypes(i)&&e[a]&&(o=e[a](n))}return o}}(hM),function(t,e){function i(t){var i={},a=[];return d(t,function(r){var s=n(i,r),u=o(s.originalDeps=e(r),t);s.entryCount=u.length,0===s.entryCount&&a.push(r),d(u,function(t){l(s.predecessor,t)<0&&s.predecessor.push(t);var e=n(i,t);l(e.successor,t)<0&&e.successor.push(r)})}),{graph:i,noEntryList:a}}function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}function o(t,e){var i=[];return d(t,function(t){l(e,t)>=0&&i.push(t)}),i}t.topologicalTravel=function(t,e,n,o){function a(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}if(t.length){var r=i(e),s=r.graph,l=r.noEntryList,u={};for(d(t,function(t){u[t]=!0});l.length;){var h=l.pop(),c=s[h],f=!!u[h];f&&(n.call(o,h,c.originalDeps.slice()),delete u[h]),d(c.successor,f?function(t){u[t]=!0,a(t)}:a)}d(u,function(){throw new Error("Circle dependency may exists")})}}}(hM,function(t){var e=[];return d(hM.getClassesByMainType(t),function(t){e=e.concat(t.prototype.dependencies||[])}),e=f(e,function(t){return Bi(t).main}),"dataset"!==t&&l(e,"dataset")<=0&&e.unshift("dataset"),e}),h(hM,lM);var cM="";"undefined"!=typeof navigator&&(cM=navigator.platform||"");var dM={color:["#c23531","#2f4554","#61a0a8","#d48265","#91c7ae","#749f83","#ca8622","#bda29a","#6e7074","#546570","#c4ccd3"],gradientColor:["#f6efa6","#d88273","#bf444c"],textStyle:{fontFamily:cM.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,animation:"auto",animationDuration:1e3,animationDurationUpdate:300,animationEasing:"exponentialOut",animationEasingUpdate:"cubicOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},fM=Ni(),pM={clearColorPalette:function(){fM(this).colorIdx=0,fM(this).colorNameMap={}},getColorFromPalette:function(t,e,i){var n=fM(e=e||this),o=n.colorIdx||0,a=n.colorNameMap=n.colorNameMap||{};if(a.hasOwnProperty(t))return a[t];var r=Si(this.get("color",!0)),s=this.get("colorLayer",!0),l=null!=i&&s?aa(s,i):r;if((l=l||r)&&l.length){var u=l[o];return t&&(a[t]=u),n.colorIdx=(o+1)%l.length,u}}},gM={cartesian2d:function(t,e,i,n){var o=t.getReferringComponents("xAxis")[0],a=t.getReferringComponents("yAxis")[0];e.coordSysDims=["x","y"],i.set("x",o),i.set("y",a),sa(o)&&(n.set("x",o),e.firstCategoryDimIndex=0),sa(a)&&(n.set("y",a),e.firstCategoryDimIndex=1)},singleAxis:function(t,e,i,n){var o=t.getReferringComponents("singleAxis")[0];e.coordSysDims=["single"],i.set("single",o),sa(o)&&(n.set("single",o),e.firstCategoryDimIndex=0)},polar:function(t,e,i,n){var o=t.getReferringComponents("polar")[0],a=o.findAxisModel("radiusAxis"),r=o.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],i.set("radius",a),i.set("angle",r),sa(a)&&(n.set("radius",a),e.firstCategoryDimIndex=0),sa(r)&&(n.set("angle",r),e.firstCategoryDimIndex=1)},geo:function(t,e,i,n){e.coordSysDims=["lng","lat"]},parallel:function(t,e,i,n){var o=t.ecModel,a=o.getComponent("parallel",t.get("parallelIndex")),r=e.coordSysDims=a.dimensions.slice();d(a.parallelAxisIndex,function(t,a){var s=o.getComponent("parallelAxis",t),l=r[a];i.set(l,s),sa(s)&&null==e.firstCategoryDimIndex&&(n.set(l,s),e.firstCategoryDimIndex=a)})}},mM="original",vM="arrayRows",yM="objectRows",xM="keyedColumns",_M="unknown",wM="typedArray",bM="column",SM="row";la.seriesDataToSource=function(t){return new la({data:t,sourceFormat:S(t)?wM:mM,fromDataset:!1})},Wi(la);var MM=Ni(),IM="\0_ec_inner",TM=wo.extend({init:function(t,e,i,n){i=i||{},this.option=null,this._theme=new wo(i),this._optionManager=n},setOption:function(t,e){k(!(IM in t),"please use chart.getOption()"),this._optionManager.setOption(t,e),this.resetOption(null)},resetOption:function(t){var e=!1,i=this._optionManager;if(!t||"recreate"===t){var n=i.mountOption("recreate"===t);this.option&&"recreate"!==t?(this.restoreData(),this.mergeOption(n)):Sa.call(this,n),e=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(this.mergeOption(o),e=!0)}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this,this._api);a.length&&d(a,function(t){this.mergeOption(t,e=!0)},this)}return e},mergeOption:function(t){var e=this.option,o=this._componentsMap,r=[];ca(this),d(t,function(t,o){null!=t&&(hM.hasClass(o)?o&&r.push(o):e[o]=null==e[o]?i(t):n(e[o],t,!0))}),hM.topologicalTravel(r,hM.getAllClassMainTypes(),function(i,n){var r=Si(t[i]),s=Di(o.get(i),r);Ai(s),d(s,function(t,e){var n=t.option;w(n)&&(t.keyInfo.mainType=i,t.keyInfo.subType=Ia(i,n,t.exist))});var l=Ma(o,n);e[i]=[],o.set(i,[]),d(s,function(t,n){var r=t.exist,s=t.option;if(k(w(s)||r,"Empty component definition"),s){var u=hM.getClass(i,t.keyInfo.subType,!0);if(r&&r instanceof u)r.name=t.keyInfo.name,r.mergeOption(s,this),r.optionUpdated(s,!1);else{var h=a({dependentModels:l,componentIndex:n},t.keyInfo);a(r=new u(s,this,this,h),h),r.init(s,this,this,h),r.optionUpdated(null,!0)}}else r.mergeOption({},this),r.optionUpdated({},!1);o.get(i)[n]=r,e[i][n]=r.option},this),"series"===i&&Ta(this,o.get("series"))},this),this._seriesIndicesMap=R(this._seriesIndices=this._seriesIndices||[])},getOption:function(){var t=i(this.option);return d(t,function(e,i){if(hM.hasClass(i)){for(var n=(e=Si(e)).length-1;n>=0;n--)Li(e[n])&&e.splice(n,1);t[i]=e}}),delete t[IM],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap.get(t);if(i)return i[e||0]},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,o=t.name,a=this._componentsMap.get(e);if(!a||!a.length)return[];var r;if(null!=i)y(i)||(i=[i]),r=g(f(i,function(t){return a[t]}),function(t){return!!t});else if(null!=n){var s=y(n);r=g(a,function(t){return s&&l(n,t.id)>=0||!s&&t.id===n})}else if(null!=o){var u=y(o);r=g(a,function(t){return u&&l(o,t.name)>=0||!u&&t.name===o})}else r=a.slice();return Da(r,t)},findComponents:function(t){var e=t.query,i=t.mainType,n=function(t){var e=i+"Index",n=i+"Id",o=i+"Name";return!t||null==t[e]&&null==t[n]&&null==t[o]?null:{mainType:i,index:t[e],id:t[n],name:t[o]}}(e);return function(e){return t.filter?g(e,t.filter):e}(Da(n?this.queryComponents(n):this._componentsMap.get(i),t))},eachComponent:function(t,e,i){var n=this._componentsMap;"function"==typeof t?(i=e,e=t,n.each(function(t,n){d(t,function(t,o){e.call(i,n,t,o)})})):_(t)?d(n.get(t),e,i):w(t)&&d(this.findComponents(t),e,i)},getSeriesByName:function(t){return g(this._componentsMap.get("series"),function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap.get("series")[t]},getSeriesByType:function(t){return g(this._componentsMap.get("series"),function(e){return e.subType===t})},getSeries:function(){return this._componentsMap.get("series").slice()},getSeriesCount:function(){return this._componentsMap.get("series").length},eachSeries:function(t,e){d(this._seriesIndices,function(i){var n=this._componentsMap.get("series")[i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){d(this._componentsMap.get("series"),t,e)},eachSeriesByType:function(t,e,i){d(this._seriesIndices,function(n){var o=this._componentsMap.get("series")[n];o.subType===t&&e.call(i,o,n)},this)},eachRawSeriesByType:function(t,e,i){return d(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return null==this._seriesIndicesMap.get(t.componentIndex)},getCurrentSeriesIndices:function(){return(this._seriesIndices||[]).slice()},filterSeries:function(t,e){Ta(this,g(this._componentsMap.get("series"),t,e))},restoreData:function(t){var e=this._componentsMap;Ta(this,e.get("series"));var i=[];e.each(function(t,e){i.push(e)}),hM.topologicalTravel(i,hM.getAllClassMainTypes(),function(i,n){d(e.get(i),function(e){("series"!==i||!wa(e,t))&&e.restoreData()})})}});h(TM,pM);var DM=["getDom","getZr","getWidth","getHeight","getDevicePixelRatio","dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL","getModel","getOption","getViewOfComponentModel","getViewOfSeriesModel"],AM={};Ca.prototype={constructor:Ca,create:function(t,e){var i=[];d(AM,function(n,o){var a=n.create(t,e);i=i.concat(a||[])}),this._coordinateSystems=i},update:function(t,e){d(this._coordinateSystems,function(i){i.update&&i.update(t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},Ca.register=function(t,e){AM[t]=e},Ca.get=function(t){return AM[t]};var CM=d,LM=i,kM=f,PM=n,NM=/^(min|max)?(.+)$/;La.prototype={constructor:La,setOption:function(t,e){t&&d(Si(t.series),function(t){t&&t.data&&S(t.data)&&N(t.data)}),t=LM(t,!0);var i=this._optionBackup,n=ka.call(this,t,e,!i);this._newBaseOption=n.baseOption,i?(Ea(i.baseOption,n.baseOption),n.timelineOptions.length&&(i.timelineOptions=n.timelineOptions),n.mediaList.length&&(i.mediaList=n.mediaList),n.mediaDefault&&(i.mediaDefault=n.mediaDefault)):this._optionBackup=n},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=kM(e.timelineOptions,LM),this._mediaList=kM(e.mediaList,LM),this._mediaDefault=LM(e.mediaDefault),this._currentMediaIndices=[],LM(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i.length){var n=t.getComponent("timeline");n&&(e=LM(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(t){var e=this._api.getWidth(),i=this._api.getHeight(),n=this._mediaList,o=this._mediaDefault,a=[],r=[];if(!n.length&&!o)return r;for(var s=0,l=n.length;s=1)&&(t=1),t}var i=this._upstream,n=t&&t.skip;if(this._dirty&&i){var o=this.context;o.data=o.outputData=i.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this);var a;this._plan&&!n&&(a=this._plan(this.context));var r=e(this._modBy),s=this._modDataCount||0,l=e(t&&t.modBy),u=t&&t.modDataCount||0;r===l&&s===u||(a="reset");var h;(this._dirty||"reset"===a)&&(this._dirty=!1,h=rr(this,n)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=i?i._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var d=this._dueIndex,f=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!n&&(h||d=i?null:t1&&a>0?e:t}};return s}();jM.dirty=function(){this._dirty=!0,this._onDirty&&this._onDirty(this.context)},jM.unfinished=function(){return this._progress&&this._dueIndex1||l&&!r?function(i){function n(t,i){var n=o.getDimensionInfo(i);if(n&&!1!==n.otherDims.tooltip){var a=n.type,l=jo({color:u,type:"subItem"}),h=(r?l+Zo(n.displayName||"-")+": ":"")+Zo("ordinal"===a?t+"":"time"===a?e?"":qo("yyyy/MM/dd hh:mm:ss",t):Fo(t));h&&s.push(h)}}var r=p(i,function(t,e,i){var n=o.getDimensionInfo(i);return t|=n&&!1!==n.tooltip&&null!=n.displayName},0),s=[];return a.length?d(a,function(e){n(er(o,t,e),e)}):d(i,n),(r?"
":"")+s.join(r?"
":", ")}(s):n(r?er(o,t,a[0]):l?s[0]:s),c=jo(u),f=o.getName(t),g=this.name;return Ci(this)||(g=""),g=g?Zo(g)+(e?": ":"
"):"",e?c+g+h:g+c+(f?Zo(f)+": "+h:h)},isAnimationEnabled:function(){if(a_.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){this.dataTask.dirty()},getColorFromPalette:function(t,e,i){var n=this.ecModel,o=pM.getColorFromPalette.call(this,t,e,i);return o||(o=n.getColorFromPalette(t,e,i)),o},coordDimToDataDim:function(t){return this.getRawData().mapDimension(t,!0)},getProgressive:function(){return this.get("progressive")},getProgressiveThreshold:function(){return this.get("progressiveThreshold")},getAxisTooltipData:null,getTooltipPosition:null,pipeTask:null,preventIncremental:null,pipelineContext:null});h(KM,XM),h(KM,pM);var $M=function(){this.group=new sw,this.uid=Mo("viewComponent")};$M.prototype={constructor:$M,init:function(t,e){},render:function(t,e,i,n){},dispose:function(){}};var JM=$M.prototype;JM.updateView=JM.updateLayout=JM.updateVisual=function(t,e,i,n){},Gi($M),Zi($M,{registerWhenExtend:!0});var QM=function(){var t=Ni();return function(e){var i=t(e),n=e.pipelineContext,o=i.large,a=i.progressiveRender,r=i.large=n.large,s=i.progressiveRender=n.progressiveRender;return!!(o^r||a^s)&&"reset"}},tI=Ni(),eI=QM();gr.prototype={type:"chart",init:function(t,e){},render:function(t,e,i,n){},highlight:function(t,e,i,n){vr(t.getData(),n,"emphasis")},downplay:function(t,e,i,n){vr(t.getData(),n,"normal")},remove:function(t,e){this.group.removeAll()},dispose:function(){},incrementalPrepareRender:null,incrementalRender:null,updateTransform:null};var iI=gr.prototype;iI.updateView=iI.updateLayout=iI.updateVisual=function(t,e,i,n){this.render(t,e,i,n)},Gi(gr),Zi(gr,{registerWhenExtend:!0}),gr.markUpdateMethod=function(t,e){tI(t).updateMethod=e};var nI={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},oI="\0__throttleOriginMethod",aI="\0__throttleRate",rI="\0__throttleType",sI={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var i=t.getData(),n=(t.visualColorAccessPath||"itemStyle.color").split("."),o=t.get(n)||t.getColorFromPalette(t.name,null,e.getSeriesCount());if(i.setVisual("color",o),!e.isSeriesFiltered(t)){"function"!=typeof o||o instanceof CS||i.each(function(e){i.setItemVisual(e,"color",o(t.getDataParams(e)))});return{dataEach:i.hasItemOption?function(t,e){var i=t.getItemModel(e).get(n,!0);null!=i&&t.setItemVisual(e,"color",i)}:null}}}},lI={toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}},uI=function(t,e){function i(t,e){if("string"!=typeof t)return t;var i=t;return d(e,function(t,e){i=i.replace(new RegExp("\\{\\s*"+e+"\\s*\\}","g"),t)}),i}function n(t){var e=a.get(t);if(null==e){for(var i=t.split("."),n=lI.aria,o=0;o1?"series.multiple.prefix":"series.single.prefix"),{seriesCount:r}),e.eachSeries(function(t,e){if(e1?"multiple":"single")+".";a=i(a=n(s?u+"withName":u+"withoutName"),{seriesId:t.seriesIndex,seriesName:t.get("name"),seriesType:o(t.subType)});var c=t.getData();window.data=c,c.count()>l?a+=i(n("data.partialData"),{displayCnt:l}):a+=n("data.allData");for(var d=[],p=0;pi.blockIndex?i.step:null,a=n&&n.modDataCount;return{step:o,modBy:null!=a?Math.ceil(a/o):null,modDataCount:a}}},cI.getPipeline=function(t){return this._pipelineMap.get(t)},cI.updateStreamModes=function(t,e){var i=this._pipelineMap.get(t.uid),n=t.getData().count(),o=i.progressiveEnabled&&e.incrementalPrepareRender&&n>=i.threshold,a=t.get("large")&&n>=t.get("largeThreshold"),r="mod"===t.get("progressiveChunkMode")?n:null;t.pipelineContext=i.context={progressiveRender:o,modDataCount:r,large:a}},cI.restorePipelines=function(t){var e=this,i=e._pipelineMap=R();t.eachSeries(function(t){var n=t.getProgressive(),o=t.uid;i.set(o,{id:o,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:n&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(n||700),count:0}),Er(e,t,t.dataTask)})},cI.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.ecInstance.getModel(),i=this.api;d(this._allHandlers,function(n){var o=t.get(n.uid)||t.set(n.uid,[]);n.reset&&Ir(this,n,o,e,i),n.overallReset&&Tr(this,n,o,e,i)},this)},cI.prepareView=function(t,e,i,n){var o=t.renderTask,a=o.context;a.model=e,a.ecModel=i,a.api=n,o.__block=!t.incrementalPrepareRender,Er(this,e,o)},cI.performDataProcessorTasks=function(t,e){Mr(this,this._dataProcessorHandlers,t,e,{block:!0})},cI.performVisualTasks=function(t,e,i){Mr(this,this._visualHandlers,t,e,i)},cI.performSeriesTasks=function(t){var e;t.eachSeries(function(t){e|=t.dataTask.perform()}),this.unfinished|=e},cI.plan=function(){this._pipelineMap.each(function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)})};var dI=cI.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},fI=Nr(0);Sr.wrapStageHandler=function(t,e){return x(t)&&(t={overallReset:t,seriesType:Rr(t)}),t.uid=Mo("stageHandler"),e&&(t.visualType=e),t};var pI,gI={},mI={};zr(gI,TM),zr(mI,Aa),gI.eachSeriesByType=gI.eachRawSeriesByType=function(t){pI=t},gI.eachComponent=function(t){"series"===t.mainType&&t.subType&&(pI=t.subType)};var vI=["#37A2DA","#32C5E9","#67E0E3","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#E062AE","#E690D1","#e7bcf3","#9d96f5","#8378EA","#96BFFF"],yI={color:vI,colorLayer:[["#37A2DA","#ffd85c","#fd7b5f"],["#37A2DA","#67E0E3","#FFDB5C","#ff9f7f","#E062AE","#9d96f5"],["#37A2DA","#32C5E9","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#e7bcf3","#8378EA","#96BFFF"],vI]},xI=["#dd6b66","#759aa0","#e69d87","#8dc1a9","#ea7e53","#eedd78","#73a373","#73b9bc","#7289ab","#91ca8c","#f49f42"],_I={color:xI,backgroundColor:"#333",tooltip:{axisPointer:{lineStyle:{color:"#eee"},crossStyle:{color:"#eee"}}},legend:{textStyle:{color:"#eee"}},textStyle:{color:"#eee"},title:{textStyle:{color:"#eee"}},toolbox:{iconStyle:{normal:{borderColor:"#eee"}}},dataZoom:{textStyle:{color:"#eee"}},visualMap:{textStyle:{color:"#eee"}},timeline:{lineStyle:{color:"#eee"},itemStyle:{normal:{color:xI[1]}},label:{normal:{textStyle:{color:"#eee"}}},controlStyle:{normal:{color:"#eee",borderColor:"#eee"}}},timeAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},logAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},valueAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},categoryAxis:{axisLine:{lineStyle:{color:"#eee"}},axisTick:{lineStyle:{color:"#eee"}},axisLabel:{textStyle:{color:"#eee"}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:"#eee"}}},line:{symbol:"circle"},graph:{color:xI},gauge:{title:{textStyle:{color:"#eee"}}},candlestick:{itemStyle:{normal:{color:"#FD1050",color0:"#0CF49B",borderColor:"#FD1050",borderColor0:"#0CF49B"}}}};_I.categoryAxis.splitLine.show=!1,hM.extend({type:"dataset",defaultOption:{seriesLayoutBy:bM,sourceHeader:null,dimensions:null,source:null},optionUpdated:function(){ua(this)}}),$M.extend({type:"dataset"});var wI=k,bI=d,SI=x,MI=w,II=hM.parseClassType,TI={zrender:"4.0.4"},DI=1e3,AI=1e3,CI=3e3,LI={PROCESSOR:{FILTER:DI,STATISTIC:5e3},VISUAL:{LAYOUT:AI,GLOBAL:2e3,CHART:CI,COMPONENT:4e3,BRUSH:5e3}},kI="__flagInMainProcess",PI="__optionUpdated",NI=/^[a-zA-Z0-9_]+$/;Vr.prototype.on=Br("on"),Vr.prototype.off=Br("off"),Vr.prototype.one=Br("one"),h(Vr,D_);var OI=Gr.prototype;OI._onframe=function(){if(!this._disposed){var t=this._scheduler;if(this[PI]){var e=this[PI].silent;this[kI]=!0,Fr(this),EI.update.call(this),this[kI]=!1,this[PI]=!1,Xr.call(this,e),jr.call(this,e)}else if(t.unfinished){var i=1,n=this._model;this._api;t.unfinished=!1;do{var o=+new Date;t.performSeriesTasks(n),t.performDataProcessorTasks(n),Zr(this,n),t.performVisualTasks(n),Qr(this,this._model,0,"remain"),i-=+new Date-o}while(i>0&&t.unfinished);t.unfinished||this._zr.flush()}}},OI.getDom=function(){return this._dom},OI.getZr=function(){return this._zr},OI.setOption=function(t,e,i){var n;if(MI(e)&&(i=e.lazyUpdate,n=e.silent,e=e.notMerge),this[kI]=!0,!this._model||e){var o=new La(this._api),a=this._theme,r=this._model=new TM(null,null,a,o);r.scheduler=this._scheduler,r.init(null,null,a,o)}this._model.setOption(t,GI),i?(this[PI]={silent:n},this[kI]=!1):(Fr(this),EI.update.call(this),this._zr.flush(),this[PI]=!1,this[kI]=!1,Xr.call(this,n),jr.call(this,n))},OI.setTheme=function(){console.log("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},OI.getModel=function(){return this._model},OI.getOption=function(){return this._model&&this._model.getOption()},OI.getWidth=function(){return this._zr.getWidth()},OI.getHeight=function(){return this._zr.getHeight()},OI.getDevicePixelRatio=function(){return this._zr.painter.dpr||window.devicePixelRatio||1},OI.getRenderedCanvas=function(t){if(a_.canvasSupported)return(t=t||{}).pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor"),this._zr.painter.getRenderedCanvas(t)},OI.getSvgDataUrl=function(){if(a_.svgSupported){var t=this._zr;return d(t.storage.getDisplayList(),function(t){t.stopAnimation(!0)}),t.painter.pathToDataUrl()}},OI.getDataURL=function(t){var e=(t=t||{}).excludeComponents,i=this._model,n=[],o=this;bI(e,function(t){i.eachComponent({mainType:t},function(t){var e=o._componentsMap[t.__viewId];e.group.ignore||(n.push(e),e.group.ignore=!0)})});var a="svg"===this._zr.painter.getType()?this.getSvgDataUrl():this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return bI(n,function(t){t.group.ignore=!1}),a},OI.getConnectedDataURL=function(t){if(a_.canvasSupported){var e=this.group,n=Math.min,o=Math.max;if(XI[e]){var a=1/0,r=1/0,s=-1/0,l=-1/0,u=[],h=t&&t.pixelRatio||1;d(UI,function(h,c){if(h.group===e){var d=h.getRenderedCanvas(i(t)),f=h.getDom().getBoundingClientRect();a=n(f.left,a),r=n(f.top,r),s=o(f.right,s),l=o(f.bottom,l),u.push({dom:d,left:f.left,top:f.top})}});var c=(s*=h)-(a*=h),f=(l*=h)-(r*=h),p=m_();p.width=c,p.height=f;var g=_i(p);return bI(u,function(t){var e=new Je({style:{x:t.left*h-a,y:t.top*h-r,image:t.dom}});g.add(e)}),g.refreshImmediately(),p.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}},OI.convertToPixel=v(Wr,"convertToPixel"),OI.convertFromPixel=v(Wr,"convertFromPixel"),OI.containPixel=function(t,e){var i;return t=Oi(this._model,t),d(t,function(t,n){n.indexOf("Models")>=0&&d(t,function(t){var o=t.coordinateSystem;if(o&&o.containPoint)i|=!!o.containPoint(e);else if("seriesModels"===n){var a=this._chartsMap[t.__viewId];a&&a.containPoint&&(i|=a.containPoint(e,t))}},this)},this),!!i},OI.getVisual=function(t,e){var i=(t=Oi(this._model,t,{defaultMainType:"series"})).seriesModel.getData(),n=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?i.indexOfRawIndex(t.dataIndex):null;return null!=n?i.getItemVisual(n,e):i.getVisual(e)},OI.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},OI.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]};var EI={prepareAndUpdate:function(t){Fr(this),EI.update.call(this,t)},update:function(t){var e=this._model,i=this._api,n=this._zr,o=this._coordSysMgr,a=this._scheduler;if(e){a.restoreData(e,t),a.performSeriesTasks(e),o.create(e,i),a.performDataProcessorTasks(e,t),Zr(this,e),o.update(e,i),Kr(e),a.performVisualTasks(e,t),$r(this,e,i,t);var r=e.get("backgroundColor")||"transparent";if(a_.canvasSupported)n.setBackgroundColor(r);else{var s=At(r);r=zt(s,"rgb"),0===s[3]&&(r="transparent")}ts(e,i)}},updateTransform:function(t){var e=this._model,i=this,n=this._api;if(e){var o=[];e.eachComponent(function(a,r){var s=i.getViewOfComponentModel(r);if(s&&s.__alive)if(s.updateTransform){var l=s.updateTransform(r,e,n,t);l&&l.update&&o.push(s)}else o.push(s)});var a=R();e.eachSeries(function(o){var r=i._chartsMap[o.__viewId];if(r.updateTransform){var s=r.updateTransform(o,e,n,t);s&&s.update&&a.set(o.uid,1)}else a.set(o.uid,1)}),Kr(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0,dirtyMap:a}),Qr(i,e,0,t,a),ts(e,this._api)}},updateView:function(t){var e=this._model;e&&(gr.markUpdateMethod(t,"updateView"),Kr(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0}),$r(this,this._model,this._api,t),ts(e,this._api))},updateVisual:function(t){EI.update.call(this,t)},updateLayout:function(t){EI.update.call(this,t)}};OI.resize=function(t){this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var i=e.resetOption("media"),n=t&&t.silent;this[kI]=!0,i&&Fr(this),EI.update.call(this),this[kI]=!1,Xr.call(this,n),jr.call(this,n)}},OI.showLoading=function(t,e){if(MI(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),ZI[t]){var i=ZI[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},OI.hideLoading=function(){this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null},OI.makeActionFromEvent=function(t){var e=a({},t);return e.type=BI[t.type],e},OI.dispatchAction=function(t,e){MI(e)||(e={silent:!!e}),zI[t.type]&&this._model&&(this[kI]?this._pendingActions.push(t):(Ur.call(this,t,e.silent),e.flush?this._zr.flush(!0):!1!==e.flush&&a_.browser.weChat&&this._throttledZrFlush(),Xr.call(this,e.silent),jr.call(this,e.silent)))},OI.appendData=function(t){var e=t.seriesIndex;this.getModel().getSeriesByIndex(e).appendData(t),this._scheduler.unfinished=!0},OI.on=Br("on"),OI.off=Br("off"),OI.one=Br("one");var RI=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];OI._initEvents=function(){bI(RI,function(t){this._zr.on(t,function(e){var i,n=this.getModel(),o=e.target;if("globalout"===t)i={};else if(o&&null!=o.dataIndex){var r=o.dataModel||n.getSeriesByIndex(o.seriesIndex);i=r&&r.getDataParams(o.dataIndex,o.dataType)||{}}else o&&o.eventData&&(i=a({},o.eventData));i&&(i.event=e,i.type=t,this.trigger(t,i))},this)},this),bI(BI,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},OI.isDisposed=function(){return this._disposed},OI.clear=function(){this.setOption({series:[]},!0)},OI.dispose=function(){if(!this._disposed){this._disposed=!0,Ri(this.getDom(),qI,"");var t=this._api,e=this._model;bI(this._componentsViews,function(i){i.dispose(e,t)}),bI(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete UI[this.id]}},h(Gr,D_);var zI={},BI={},VI=[],GI=[],WI=[],FI=[],HI={},ZI={},UI={},XI={},jI=new Date-0,YI=new Date-0,qI="_echarts_instance_",KI={},$I=rs;ps(2e3,sI),us(GM),hs(5e3,function(t){var e=R();t.eachSeries(function(t){var i=t.get("stack");if(i){var n=e.get(i)||e.set(i,[]),o=t.getData(),a={stackResultDimension:o.getCalculationInfo("stackResultDimension"),stackedOverDimension:o.getCalculationInfo("stackedOverDimension"),stackedDimension:o.getCalculationInfo("stackedDimension"),stackedByDimension:o.getCalculationInfo("stackedByDimension"),isStackedByIndex:o.getCalculationInfo("isStackedByIndex"),data:o,seriesModel:t};if(!a.stackedDimension||!a.isStackedByIndex&&!a.stackedByDimension)return;n.length&&o.setCalculationInfo("stackedOnSeries",n[n.length-1].seriesModel),n.push(a)}}),e.each(ja)}),ms("default",function(t,e){r(e=e||{},{text:"loading",color:"#c23531",textColor:"#000",maskColor:"rgba(255, 255, 255, 0.8)",zlevel:0});var i=new SS({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4}),n=new DS({shape:{startAngle:-hI/2,endAngle:-hI/2+.1,r:10},style:{stroke:e.color,lineCap:"round",lineWidth:5},zlevel:e.zlevel,z:10001}),o=new SS({style:{fill:"none",text:e.text,textPosition:"right",textDistance:10,textFill:e.textColor},zlevel:e.zlevel,z:10001});n.animateShape(!0).when(1e3,{endAngle:3*hI/2}).start("circularInOut"),n.animateShape(!0).when(1e3,{startAngle:3*hI/2}).delay(300).start("circularInOut");var a=new sw;return a.add(n),a.add(o),a.add(i),a.resize=function(){var e=t.getWidth()/2,a=t.getHeight()/2;n.setShape({cx:e,cy:a});var r=n.shape.r;o.setShape({x:e-r,y:a-r,width:2*r,height:2*r}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},a.resize(),a}),cs({type:"highlight",event:"highlight",update:"highlight"},B),cs({type:"downplay",event:"downplay",update:"downplay"},B),ls("light",yI),ls("dark",_I);var JI={};Ss.prototype={constructor:Ss,add:function(t){return this._add=t,this},update:function(t){return this._update=t,this},remove:function(t){return this._remove=t,this},execute:function(){var t=this._old,e=this._new,i={},n=[],o=[];for(Ms(t,{},n,"_oldKeyGetter",this),Ms(e,i,o,"_newKeyGetter",this),a=0;a=e)){for(var i,n=this._chunkSize,o=this._rawData,a=this._storage,r=this.dimensions,s=r.length,l=this._dimensionInfos,u=this._nameList,h=this._idList,c=this._rawExtent,d=this._nameRepeatCount={},f=this._chunkCount,p=f-1,g=0;gC[1]&&(C[1]=A)}if(!o.pure){var L=u[b];if(w&&null==L)if(null!=w.name)u[b]=L=w.name;else if(null!=i){var k=r[i],P=a[k][S];if(P){L=P[M];var N=l[k].ordinalMeta;N&&N.categories.length&&(L=N.categories[L])}}var O=null==w?null:w.id;null==O&&null!=L&&(d[L]=d[L]||0,O=L,d[L]>0&&(O+="__ec__"+d[L]),d[L]++),null!=O&&(h[b]=O)}}!o.persistent&&o.clean&&o.clean(),this._rawCount=this._count=e,this._extent={},ks(this)}},lT.count=function(){return this._count},lT.getIndices=function(){var t=this._indices;if(t){var e=t.constructor,i=this._count;if(e===Array){n=new e(i);for(o=0;o=0&&e=0&&ea&&(a=s)}return i=[o,a],this._extent[t]=i,i},lT.getApproximateExtent=function(t){return t=this.getDimension(t),this._approximateExtent[t]||this.getDataExtent(t)},lT.setApproximateExtent=function(t,e){e=this.getDimension(e),this._approximateExtent[e]=t.slice()},lT.getCalculationInfo=function(t){return this._calculationInfo[t]},lT.setCalculationInfo=function(t,e){tT(t)?a(this._calculationInfo,t):this._calculationInfo[t]=e},lT.getSum=function(t){var e=0;if(this._storage[t])for(var i=0,n=this.count();i=this._rawCount||t<0)return-1;var e=this._indices,i=e[t];if(null!=i&&it))return a;o=a-1}}return-1},lT.indicesOfNearest=function(t,e,i){var n=[];if(!this._storage[t])return n;null==i&&(i=1/0);for(var o=Number.MAX_VALUE,a=-1,r=0,s=this.count();r=0&&a<0)&&(o=u,a=l,n.length=0),n.push(r))}return n},lT.getRawIndex=Ns,lT.getRawDataItem=function(t){if(this._rawData.persistent)return this._rawData.getItem(this.getRawIndex(t));for(var e=[],i=0;i=l&&w<=u||isNaN(w))&&(a[r++]=c),c++;h=!0}else if(2===n){for(var d=this._storage[s],v=this._storage[e[1]],y=t[e[1]][0],x=t[e[1]][1],f=0;f=l&&w<=u||isNaN(w))&&(b>=y&&b<=x||isNaN(b))&&(a[r++]=c),c++}h=!0}}if(!h)if(1===n)for(m=0;m=l&&w<=u||isNaN(w))&&(a[r++]=M)}else for(m=0;mt[I][1])&&(S=!1)}S&&(a[r++]=this.getRawIndex(m))}return rb[1]&&(b[1]=w)}}}return o},lT.downSample=function(t,e,i,n){for(var o=zs(this,[t]),a=o._storage,r=[],s=Math.floor(1/e),l=a[t],u=this.count(),h=this._chunkSize,c=o._rawExtent[t],d=new(As(this))(u),f=0,p=0;pu-p&&(s=u-p,r.length=s);for(var g=0;gc[1]&&(c[1]=x),d[f++]=_}return o._count=f,o._indices=d,o.getRawIndex=Os,o},lT.getItemModel=function(t){var e=this.hostModel;return new wo(this.getRawDataItem(t),e,e&&e.ecModel)},lT.diff=function(t){var e=this;return new Ss(t?t.getIndices():[],this.getIndices(),function(e){return Es(t,e)},function(t){return Es(e,t)})},lT.getVisual=function(t){var e=this._visual;return e&&e[t]},lT.setVisual=function(t,e){if(tT(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},lT.setLayout=function(t,e){if(tT(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},lT.getLayout=function(t){return this._layout[t]},lT.getItemLayout=function(t){return this._itemLayouts[t]},lT.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?a(this._itemLayouts[t]||{},e):e},lT.clearItemLayouts=function(){this._itemLayouts.length=0},lT.getItemVisual=function(t,e,i){var n=this._itemVisuals[t],o=n&&n[e];return null!=o||i?o:this.getVisual(e)},lT.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{},o=this.hasItemVisual;if(this._itemVisuals[t]=n,tT(e))for(var a in e)e.hasOwnProperty(a)&&(n[a]=e[a],o[a]=!0);else n[e]=i,o[e]=!0},lT.clearAllVisual=function(){this._visual={},this._itemVisuals=[],this.hasItemVisual={}};var uT=function(t){t.seriesIndex=this.seriesIndex,t.dataIndex=this.dataIndex,t.dataType=this.dataType};lT.setItemGraphicEl=function(t,e){var i=this.hostModel;e&&(e.dataIndex=t,e.dataType=this.dataType,e.seriesIndex=i&&i.seriesIndex,"group"===e.type&&e.traverse(uT,e)),this._graphicEls[t]=e},lT.getItemGraphicEl=function(t){return this._graphicEls[t]},lT.eachItemGraphicEl=function(t,e){d(this._graphicEls,function(i,n){i&&t&&t.call(e,i,n)})},lT.cloneShallow=function(t){if(!t){var e=f(this.dimensions,this.getDimensionInfo,this);t=new sT(e,this.hostModel)}if(t._storage=this._storage,Ls(t,this),this._indices){var i=this._indices.constructor;t._indices=new i(this._indices)}else t._indices=null;return t.getRawIndex=t._indices?Os:Ns,t},lT.wrapMethod=function(t,e){var i=this[t];"function"==typeof i&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=i.apply(this,arguments);return e.apply(this,[t].concat(C(arguments)))})},lT.TRANSFERABLE_METHODS=["cloneShallow","downSample","map"],lT.CHANGABLE_METHODS=["filterSelf","selectRange"];var hT=function(t,e){return e=e||{},Gs(e.coordDimensions||[],t,{dimsDef:e.dimensionsDefine||t.dimensionsDefine,encodeDef:e.encodeDefine||t.encodeDefine,dimCount:e.dimensionsCount,generateCoord:e.generateCoord,generateCoordCount:e.generateCoordCount})};qs.prototype.parse=function(t){return t},qs.prototype.getSetting=function(t){return this._setting[t]},qs.prototype.contain=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},qs.prototype.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},qs.prototype.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},qs.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},qs.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},qs.prototype.getExtent=function(){return this._extent.slice()},qs.prototype.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},qs.prototype.isBlank=function(){return this._isBlank},qs.prototype.setBlank=function(t){this._isBlank=t},qs.prototype.getLabel=null,Gi(qs),Zi(qs,{registerWhenExtend:!0}),Ks.createByAxisModel=function(t){var e=t.option,i=e.data,n=i&&f(i,Js);return new Ks({categories:n,needCollect:!n,deduplication:!1!==e.dedplication})};var cT=Ks.prototype;cT.getOrdinal=function(t){return $s(this).get(t)},cT.parseAndCollect=function(t){var e,i=this._needCollect;if("string"!=typeof t&&!i)return t;if(i&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var n=$s(this);return null==(e=n.get(t))&&(i?(e=this.categories.length,this.categories[e]=t,n.set(t,e)):e=NaN),e};var dT=qs.prototype,fT=qs.extend({type:"ordinal",init:function(t,e){t&&!y(t)||(t=new Ks({categories:t})),this._ordinalMeta=t,this._extent=e||[0,t.categories.length-1]},parse:function(t){return"string"==typeof t?this._ordinalMeta.getOrdinal(t):Math.round(t)},contain:function(t){return t=this.parse(t),dT.contain.call(this,t)&&null!=this._ordinalMeta.categories[t]},normalize:function(t){return dT.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(dT.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){if(!this.isBlank())return this._ordinalMeta.categories[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},getOrdinalMeta:function(){return this._ordinalMeta},niceTicks:B,niceExtent:B});fT.create=function(){return new fT};var pT=Ao,gT=Ao,mT=qs.extend({type:"interval",_interval:0,_intervalPrecision:2,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),mT.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=tl(t)},getTicks:function(){return nl(this._interval,this._extent,this._niceExtent,this._intervalPrecision)},getLabel:function(t,e){if(null==t)return"";var i=e&&e.precision;return null==i?i=ko(t)||0:"auto"===i&&(i=this._intervalPrecision),t=gT(t,i,!0),Fo(t)},niceTicks:function(t,e,i){t=t||5;var n=this._extent,o=n[1]-n[0];if(isFinite(o)){o<0&&(o=-o,n.reverse());var a=Qs(n,t,e,i);this._intervalPrecision=a.intervalPrecision,this._interval=a.interval,this._niceExtent=a.niceTickExtent}},niceExtent:function(t){var e=this._extent;if(e[0]===e[1])if(0!==e[0]){var i=e[0];t.fixMax?e[0]-=i/2:(e[1]+=i/2,e[0]-=i/2)}else e[1]=1;var n=e[1]-e[0];isFinite(n)||(e[0]=0,e[1]=1),this.niceTicks(t.splitNumber,t.minInterval,t.maxInterval);var o=this._interval;t.fixMin||(e[0]=gT(Math.floor(e[0]/o)*o)),t.fixMax||(e[1]=gT(Math.ceil(e[1]/o)*o))}});mT.create=function(){return new mT};var vT="__ec_stack_",yT="undefined"!=typeof Float32Array?Float32Array:Array,xT={seriesType:"bar",plan:QM(),reset:function(t){if(dl(t)&&fl(t)){var e=t.getData(),i=t.coordinateSystem,n=i.getBaseAxis(),o=i.getOtherAxis(n),a=e.mapDimension(o.dim),r=e.mapDimension(n.dim),s=o.isHorizontal(),l=s?0:1,u=hl(ll([t]),n,t).width;return u>.5||(u=.5),{progress:function(t,e){for(var h,c=new yT(2*t.count),d=[],f=[],p=0;null!=(h=t.next());)f[l]=e.get(a,h),f[1-l]=e.get(r,h),d=i.dataToPoint(f,null,d),c[p++]=d[0],c[p++]=d[1];e.setLayout({largePoints:c,barWidth:u,valueAxisStart:pl(n,o,!1),valueAxisHorizontal:s})}}}}},_T=mT.prototype,wT=Math.ceil,bT=Math.floor,ST=function(t,e,i,n){for(;i>>1;t[o][1]i&&(a=i);var r=IT.length,s=ST(IT,a,0,r),l=IT[Math.min(s,r-1)],u=l[1];"year"===l[0]&&(u*=Vo(o/u/t,!0));var h=this.getSetting("useUTC")?0:60*new Date(+n[0]||+n[1]).getTimezoneOffset()*1e3,c=[Math.round(wT((n[0]-h)/u)*u+h),Math.round(bT((n[1]-h)/u)*u+h)];il(c,n),this._stepLvl=l,this._interval=u,this._niceExtent=c},parse:function(t){return+Ro(t)}});d(["contain","normalize"],function(t){MT.prototype[t]=function(e){return _T[t].call(this,this.parse(e))}});var IT=[["hh:mm:ss",1e3],["hh:mm:ss",5e3],["hh:mm:ss",1e4],["hh:mm:ss",15e3],["hh:mm:ss",3e4],["hh:mm\nMM-dd",6e4],["hh:mm\nMM-dd",3e5],["hh:mm\nMM-dd",6e5],["hh:mm\nMM-dd",9e5],["hh:mm\nMM-dd",18e5],["hh:mm\nMM-dd",36e5],["hh:mm\nMM-dd",72e5],["hh:mm\nMM-dd",216e5],["hh:mm\nMM-dd",432e5],["MM-dd\nyyyy",864e5],["MM-dd\nyyyy",1728e5],["MM-dd\nyyyy",2592e5],["MM-dd\nyyyy",3456e5],["MM-dd\nyyyy",432e6],["MM-dd\nyyyy",5184e5],["week",6048e5],["MM-dd\nyyyy",864e6],["week",12096e5],["week",18144e5],["month",26784e5],["week",36288e5],["month",53568e5],["week",36288e5],["quarter",8208e6],["month",107136e5],["month",13392e6],["half-year",16416e6],["month",214272e5],["month",26784e6],["year",32832e6]];MT.create=function(t){return new MT({useUTC:t.ecModel.get("useUTC")})};var TT=qs.prototype,DT=mT.prototype,AT=ko,CT=Ao,LT=Math.floor,kT=Math.ceil,PT=Math.pow,NT=Math.log,OT=qs.extend({type:"log",base:10,$constructor:function(){qs.apply(this,arguments),this._originalScale=new mT},getTicks:function(){var t=this._originalScale,e=this._extent,i=t.getExtent();return f(DT.getTicks.call(this),function(n){var o=Ao(PT(this.base,n));return o=n===e[0]&&t.__fixMin?gl(o,i[0]):o,o=n===e[1]&&t.__fixMax?gl(o,i[1]):o},this)},getLabel:DT.getLabel,scale:function(t){return t=TT.scale.call(this,t),PT(this.base,t)},setExtent:function(t,e){var i=this.base;t=NT(t)/NT(i),e=NT(e)/NT(i),DT.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,e=TT.getExtent.call(this);e[0]=PT(t,e[0]),e[1]=PT(t,e[1]);var i=this._originalScale,n=i.getExtent();return i.__fixMin&&(e[0]=gl(e[0],n[0])),i.__fixMax&&(e[1]=gl(e[1],n[1])),e},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=NT(t[0])/NT(e),t[1]=NT(t[1])/NT(e),TT.unionExtent.call(this,t)},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(i===1/0||i<=0)){var n=zo(i);for(t/i*n<=.5&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var o=[Ao(kT(e[0]/n)*n),Ao(LT(e[1]/n)*n)];this._interval=n,this._niceExtent=o}},niceExtent:function(t){DT.niceExtent.call(this,t);var e=this._originalScale;e.__fixMin=t.fixMin,e.__fixMax=t.fixMax}});d(["contain","normalize"],function(t){OT.prototype[t]=function(e){return e=NT(e)/NT(this.base),TT[t].call(this,e)}}),OT.create=function(){return new OT};var ET={getMin:function(t){var e=this.option,i=t||null==e.rangeStart?e.min:e.rangeStart;return this.axis&&null!=i&&"dataMin"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getMax:function(t){var e=this.option,i=t||null==e.rangeEnd?e.max:e.rangeEnd;return this.axis&&null!=i&&"dataMax"!==i&&"function"!=typeof i&&!I(i)&&(i=this.axis.scale.parse(i)),i},getNeedCrossZero:function(){var t=this.option;return null==t.rangeStart&&null==t.rangeEnd&&!t.scale},getCoordSysModel:B,setRange:function(t,e){this.option.rangeStart=t,this.option.rangeEnd=e},resetRange:function(){this.option.rangeStart=this.option.rangeEnd=null}},RT=En({type:"triangle",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n+a),t.lineTo(i-o,n+a),t.closePath()}}),zT=En({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,o=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+o,n),t.lineTo(i,n+a),t.lineTo(i-o,n),t.closePath()}}),BT=En({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,o=e.width/5*3,a=Math.max(o,e.height),r=o/2,s=r*r/(a-r),l=n-a+r+s,u=Math.asin(s/r),h=Math.cos(u)*r,c=Math.sin(u),d=Math.cos(u),f=.6*r,p=.7*r;t.moveTo(i-h,l+s),t.arc(i,l,r,Math.PI-u,2*Math.PI+u),t.bezierCurveTo(i+h-c*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-h+c*f,l+s+d*f,i-h,l+s),t.closePath()}}),VT=En({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.height,n=e.width,o=e.x,a=e.y,r=n/3*2;t.moveTo(o,a),t.lineTo(o+r,a+i),t.lineTo(o,a+i/4*3),t.lineTo(o-r,a+i),t.lineTo(o,a),t.closePath()}}),GT={line:function(t,e,i,n,o){o.x1=t,o.y1=e+n/2,o.x2=t+i,o.y2=e+n/2},rect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n},roundRect:function(t,e,i,n,o){o.x=t,o.y=e,o.width=i,o.height=n,o.r=Math.min(i,n)/4},square:function(t,e,i,n,o){var a=Math.min(i,n);o.x=t,o.y=e,o.width=a,o.height=a},circle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.r=Math.min(i,n)/2},diamond:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n},pin:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},arrow:function(t,e,i,n,o){o.x=t+i/2,o.y=e+n/2,o.width=i,o.height=n},triangle:function(t,e,i,n,o){o.cx=t+i/2,o.cy=e+n/2,o.width=i,o.height=n}},WT={};d({line:MS,rect:SS,roundRect:SS,square:SS,circle:pS,diamond:zT,pin:BT,arrow:VT,triangle:RT},function(t,e){WT[e]=new t});var FT=En({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},beforeBrush:function(){var t=this.style;"pin"===this.shape.symbolType&&"inside"===t.textPosition&&(t.textPosition=["50%","40%"],t.textAlign="center",t.textVerticalAlign="middle")},buildPath:function(t,e,i){var n=e.symbolType,o=WT[n];"none"!==e.symbolType&&(o||(o=WT[n="rect"]),GT[n](e.x,e.y,e.width,e.height,o.shape),o.buildPath(t,o.shape,i))}}),HT={isDimensionStacked:Zs,enableDataStack:Hs,getStackedDimension:Us},ZT=(Object.freeze||Object)({createList:function(t){return Xs(t.getSource(),t)},getLayoutRect:Qo,dataStack:HT,createScale:function(t,e){var i=e;wo.isInstance(e)||h(i=new wo(e),ET);var n=xl(i);return n.setExtent(t[0],t[1]),yl(n,i),n},mixinAxisModelCommonMethods:function(t){h(t,ET)},completeDimensions:Gs,createDimensions:hT,createSymbol:Tl}),UT=1e-8;Cl.prototype={constructor:Cl,properties:null,getBoundingRect:function(){var t=this._rect;if(t)return t;for(var e=Number.MAX_VALUE,i=[e,e],n=[-e,-e],o=[],a=[],r=this.geometries,s=0;s0}),function(t){var e=t.properties,i=t.geometry,n=i.coordinates,o=[];"Polygon"===i.type&&o.push({type:"polygon",exterior:n[0],interiors:n.slice(1)}),"MultiPolygon"===i.type&&d(n,function(t){t[0]&&o.push({type:"polygon",exterior:t[0],interiors:t.slice(1)})});var a=new Cl(e.name,o,e.cp);return a.properties=e,a})},jT=Ni(),YT=[0,1],qT=function(t,e,i){this.dim=t,this.scale=e,this._extent=i||[0,0],this.inverse=!1,this.onBand=!1};qT.prototype={constructor:qT,contain:function(t){var e=this._extent,i=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return t>=i&&t<=n},containData:function(t){return this.contain(this.dataToCoord(t))},getExtent:function(){return this._extent.slice()},getPixelPrecision:function(t){return Po(t||this.scale.getExtent(),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,e){var i=this._extent,n=this.scale;return t=n.normalize(t),this.onBand&&"ordinal"===n.type&&jl(i=i.slice(),n.count()),To(t,YT,i,e)},coordToData:function(t,e){var i=this._extent,n=this.scale;this.onBand&&"ordinal"===n.type&&jl(i=i.slice(),n.count());var o=To(t,i,YT,e);return this.scale.scale(o)},pointToData:function(t,e){},getTicksCoords:function(t){var e=(t=t||{}).tickModel||this.getTickModel(),i=Nl(this,e),n=f(i.ticks,function(t){return{coord:this.dataToCoord(t),tickValue:t}},this),o=e.get("alignWithLabel");return Yl(this,n,i.tickCategoryInterval,o,t.clamp),n},getViewLabels:function(){return Pl(this).labels},getLabelModel:function(){return this.model.getModel("axisLabel")},getTickModel:function(){return this.model.getModel("axisTick")},getBandWidth:function(){var t=this._extent,e=this.scale.getExtent(),i=e[1]-e[0]+(this.onBand?1:0);0===i&&(i=1);var n=Math.abs(t[1]-t[0]);return Math.abs(n)/i},isHorizontal:null,getRotate:null,calculateCategoryInterval:function(){return Fl(this)}};var KT=XT,$T={};d(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend","defaults","clone","merge"],function(t){$T[t]=x_[t]}),KM.extend({type:"series.line",dependencies:["grid","polar"],getInitialData:function(t,e){return Xs(this.getSource(),this)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clipOverflow:!0,label:{position:"top"},lineStyle:{width:2,type:"solid"},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}});var JT=Kl.prototype,QT=Kl.getSymbolSize=function(t,e){var i=t.getItemVisual(e,"symbolSize");return i instanceof Array?i.slice():[+i,+i]};JT._createSymbol=function(t,e,i,n,o){this.removeAll();var a=Tl(t,-1,-1,2,2,e.getItemVisual(i,"color"),o);a.attr({z2:100,culling:!0,scale:$l(n)}),a.drift=Jl,this._symbolType=t,this.add(a)},JT.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(t)},JT.getSymbolPath=function(){return this.childAt(0)},JT.getScale=function(){return this.childAt(0).scale},JT.highlight=function(){this.childAt(0).trigger("emphasis")},JT.downplay=function(){this.childAt(0).trigger("normal")},JT.setZ=function(t,e){var i=this.childAt(0);i.zlevel=t,i.z=e},JT.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":"pointer"},JT.updateData=function(t,e,i){this.silent=!1;var n=t.getItemVisual(e,"symbol")||"circle",o=t.hostModel,a=QT(t,e),r=n!==this._symbolType;if(r){var s=t.getItemVisual(e,"symbolKeepAspect");this._createSymbol(n,t,e,a,s)}else(l=this.childAt(0)).silent=!1,fo(l,{scale:$l(a)},o,e);if(this._updateCommon(t,e,a,i),r){var l=this.childAt(0),u=i&&i.fadeIn,h={scale:l.scale.slice()};u&&(h.style={opacity:l.style.opacity}),l.scale=[0,0],u&&(l.style.opacity=0),po(l,h,o,e)}this._seriesModel=o};var tD=["itemStyle"],eD=["emphasis","itemStyle"],iD=["label"],nD=["emphasis","label"];JT._updateCommon=function(t,e,i,n){var o=this.childAt(0),r=t.hostModel,s=t.getItemVisual(e,"color");"image"!==o.type&&o.useStyle({strokeNoScale:!0});var l=n&&n.itemStyle,u=n&&n.hoverItemStyle,h=n&&n.symbolRotate,c=n&&n.symbolOffset,d=n&&n.labelModel,f=n&&n.hoverLabelModel,p=n&&n.hoverAnimation,g=n&&n.cursorStyle;if(!n||t.hasItemOption){var m=n&&n.itemModel?n.itemModel:t.getItemModel(e);l=m.getModel(tD).getItemStyle(["color"]),u=m.getModel(eD).getItemStyle(),h=m.getShallow("symbolRotate"),c=m.getShallow("symbolOffset"),d=m.getModel(iD),f=m.getModel(nD),p=m.getShallow("hoverAnimation"),g=m.getShallow("cursor")}else u=a({},u);var v=o.style;o.attr("rotation",(h||0)*Math.PI/180||0),c&&o.attr("position",[Do(c[0],i[0]),Do(c[1],i[1])]),g&&o.attr("cursor",g),o.setColor(s,n&&n.symbolInnerColor),o.setStyle(l);var y=t.getItemVisual(e,"opacity");null!=y&&(v.opacity=y);var x=t.getItemVisual(e,"liftZ"),_=o.__z2Origin;null!=x?null==_&&(o.__z2Origin=o.z2,o.z2+=x):null!=_&&(o.z2=_,o.__z2Origin=null);var w=n&&n.useNameLabel;io(v,u,d,f,{labelFetcher:r,labelDataIndex:e,defaultText:function(e,i){return w?t.getName(e):ql(t,e)},isRectText:!0,autoColor:s}),o.off("mouseover").off("mouseout").off("emphasis").off("normal"),o.hoverStyle=u,eo(o);var b=$l(i);if(p&&r.isAnimationEnabled()){var S=function(){if(!this.incremental){var t=b[1]/b[0];this.animateTo({scale:[Math.max(1.1*b[0],b[0]+3),Math.max(1.1*b[1],b[1]+3*t)]},400,"elasticOut")}},M=function(){this.incremental||this.animateTo({scale:b},400,"elasticOut")};o.on("mouseover",S).on("mouseout",M).on("emphasis",S).on("normal",M)}},JT.fadeOut=function(t,e){var i=this.childAt(0);this.silent=i.silent=!0,!(e&&e.keepLabel)&&(i.style.text=null),fo(i,{style:{opacity:0},scale:[0,0]},this._seriesModel,this.dataIndex,t)},u(Kl,sw);var oD=Ql.prototype;oD.updateData=function(t,e){e=eu(e);var i=this.group,n=t.hostModel,o=this._data,a=this._symbolCtor,r=iu(t);o||i.removeAll(),t.diff(o).add(function(n){var o=t.getItemLayout(n);if(tu(t,o,n,e)){var s=new a(t,n,r);s.attr("position",o),t.setItemGraphicEl(n,s),i.add(s)}}).update(function(s,l){var u=o.getItemGraphicEl(l),h=t.getItemLayout(s);tu(t,h,s,e)?(u?(u.updateData(t,s,r),fo(u,{position:h},n)):(u=new a(t,s)).attr("position",h),i.add(u),t.setItemGraphicEl(s,u)):i.remove(u)}).remove(function(t){var e=o.getItemGraphicEl(t);e&&e.fadeOut(function(){i.remove(e)})}).execute(),this._data=t},oD.isPersistent=function(){return!0},oD.updateLayout=function(){var t=this._data;t&&t.eachItemGraphicEl(function(e,i){var n=t.getItemLayout(i);e.attr("position",n)})},oD.incrementalPrepareUpdate=function(t){this._seriesScope=iu(t),this._data=null,this.group.removeAll()},oD.incrementalUpdate=function(t,e,i){i=eu(i);for(var n=t.start;n0&&su(i[o-1]);o--);for(;n0&&su(i[a-1]);a--);for(;o=0){var r=o.getItemGraphicEl(a);if(!r){var s=o.getItemLayout(a);if(!s)return;(r=new Kl(o,a)).position=s,r.setZ(t.get("zlevel"),t.get("z")),r.ignore=isNaN(s[0])||isNaN(s[1]),r.__temp=!0,o.setItemGraphicEl(a,r),r.stopSymbolAnimation(!0),this.group.add(r)}r.highlight()}else gr.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var o=t.getData(),a=Pi(o,n);if(null!=a&&a>=0){var r=o.getItemGraphicEl(a);r&&(r.__temp?(o.setItemGraphicEl(a,null),this.group.remove(r)):r.downplay())}else gr.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new fD({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new pD({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_updateAnimation:function(t,e,i,n,o,a){var r=this._polyline,s=this._polygon,l=t.hostModel,u=aD(this._data,t,this._stackedOnPoints,e,this._coordSys,i,this._valueOrigin,a),h=u.current,c=u.stackedOnCurrent,d=u.next,f=u.stackedOnNext;o&&(h=xu(u.current,i,o),c=xu(u.stackedOnCurrent,i,o),d=xu(u.next,i,o),f=xu(u.stackedOnNext,i,o)),r.shape.__points=u.current,r.shape.points=h,fo(r,{shape:{points:d}},l),s&&(s.setShape({points:h,stackedOnPoints:c}),fo(s,{shape:{points:d,stackedOnPoints:f}},l));for(var p=[],g=u.status,m=0;me&&(e=t[i]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,i=0;ie[1]&&e.reverse(),e},getOtherAxis:function(){this.grid.getOtherAxis()},pointToData:function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},toLocalCoord:null,toGlobalCoord:null},u(_D,qT);var wD={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#333",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},bD={};bD.categoryAxis=n({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},wD),bD.valueAxis=n({boundaryGap:[0,0],splitNumber:5},wD),bD.timeAxis=r({scale:!0,min:"dataMin",max:"dataMax"},bD.valueAxis),bD.logAxis=r({scale:!0,logBase:10},bD.valueAxis);var SD=["value","category","time","log"],MD=function(t,e,i,a){d(SD,function(r){e.extend({type:t+"Axis."+r,mergeDefaultAndTheme:function(e,o){var a=this.layoutMode,s=a?na(e):{};n(e,o.getTheme().get(r+"Axis")),n(e,this.getDefaultOption()),e.type=i(t,e),a&&ia(e,s,a)},optionUpdated:function(){"category"===this.option.type&&(this.__ordinalMeta=Ks.createByAxisModel(this))},getCategories:function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},getOrdinalMeta:function(){return this.__ordinalMeta},defaultOption:o([{},bD[r+"Axis"],a],!0)})}),hM.registerSubTypeDefaulter(t+"Axis",v(i,t))},ID=hM.extend({type:"cartesian2dAxis",axis:null,init:function(){ID.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){ID.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){ID.superApply(this,"restoreData",arguments),this.resetRange()},getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"grid",index:this.option.gridIndex,id:this.option.gridId})[0]}});n(ID.prototype,ET);var TD={offset:0};MD("x",ID,Iu,TD),MD("y",ID,Iu,TD),hM.extend({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}});var DD=Du.prototype;DD.type="grid",DD.axisPointerEnabled=!0,DD.getRect=function(){return this._rect},DD.update=function(t,e){var i=this._axesMap;this._updateScale(t,this.model),d(i.x,function(t){yl(t.scale,t.model)}),d(i.y,function(t){yl(t.scale,t.model)}),d(i.x,function(t){Au(i,"y",t)}),d(i.y,function(t){Au(i,"x",t)}),this.resize(this.model,e)},DD.resize=function(t,e,i){function n(){d(a,function(t){var e=t.isHorizontal(),i=e?[0,o.width]:[0,o.height],n=t.inverse?1:0;t.setExtent(i[n],i[1-n]),Lu(t,e?o.x:o.y)})}var o=Qo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;n(),!i&&t.get("containLabel")&&(d(a,function(t){if(!t.model.get("axisLabel.inside")){var e=Sl(t);if(e){var i=t.isHorizontal()?"height":"width",n=t.model.get("axisLabel.margin");o[i]-=e[i]+n,"top"===t.position?o.y+=e.height+n:"left"===t.position&&(o.x+=e.width+n)}}}),n())},DD.getAxis=function(t,e){var i=this._axesMap[t];if(null!=i){if(null==e)for(var n in i)if(i.hasOwnProperty(n))return i[n];return i[e]}},DD.getAxes=function(){return this._axesList.slice()},DD.getCartesian=function(t,e){if(null!=t&&null!=e){var i="x"+t+"y"+e;return this._coordsMap[i]}w(t)&&(e=t.yAxisIndex,t=t.xAxisIndex);for(var n=0,o=this._coordsList;nu[1]?-1:1,c=["start"===o?u[0]-h*l:"end"===o?u[1]+h*l:(u[0]+u[1])/2,Vu(o)?t.labelOffset+r*l:0],d=e.get("nameRotate");null!=d&&(d=d*CD/180);var f;Vu(o)?n=PD(t.rotation,null!=d?d:t.rotation,r):(n=Ou(t,o,d||0,u),null!=(f=t.axisNameAvailableWidth)&&(f=Math.abs(f/Math.sin(n.rotation)),!isFinite(f)&&(f=null)));var p=s.getFont(),g=e.get("nameTruncate",!0)||{},m=g.ellipsis,v=T(t.nameTruncateMaxWidth,g.maxWidth,f),y=null!=m&&null!=v?eM(i,v,p,m,{minChar:2,placeholder:g.placeholder}):i,x=e.get("tooltip",!0),_=e.mainType,w={componentType:_,name:i,$vars:["name"]};w[_+"Index"]=e.componentIndex;var b=new fS({anid:"name",__fullText:i,__truncatedText:y,position:c,rotation:n.rotation,silent:Eu(e),z2:1,tooltip:x&&x.show?a({content:i,formatter:function(){return i},formatterParams:w},x):null});no(b.style,s,{text:y,textFont:p,textFill:s.getTextColor()||e.get("axisLine.lineStyle.color"),textAlign:n.textAlign,textVerticalAlign:n.textVerticalAlign}),e.get("triggerEvent")&&(b.eventData=Nu(e),b.eventData.targetType="axisName",b.eventData.name=i),this._dumbGroup.add(b),b.updateTransform(),this.group.add(b),b.decomposeTransform()}}},PD=LD.innerTextLayout=function(t,e,i){var n,o,a=Oo(e-t);return Eo(a)?(o=i>0?"top":"bottom",n="center"):Eo(a-CD)?(o=i>0?"bottom":"top",n="center"):(o="middle",n=a>0&&a0?"right":"left":i>0?"left":"right"),{rotation:a,textAlign:n,textVerticalAlign:o}},ND=d,OD=v,ED=ys({type:"axis",_axisPointer:null,axisPointerClass:null,render:function(t,e,i,n){this.axisPointerClass&&Yu(t),ED.superApply(this,"render",arguments),Qu(this,t,0,i,0,!0)},updateAxisPointer:function(t,e,i,n,o){Qu(this,t,0,i,0,!1)},remove:function(t,e){var i=this._axisPointer;i&&i.remove(e),ED.superApply(this,"remove",arguments)},dispose:function(t,e){th(this,e),ED.superApply(this,"dispose",arguments)}}),RD=[];ED.registerAxisPointerClass=function(t,e){RD[t]=e},ED.getAxisPointerClass=function(t){return t&&RD[t]};var zD=["axisLine","axisTickLabel","axisName"],BD=["splitArea","splitLine"],VD=ED.extend({type:"cartesianAxis",axisPointerClass:"CartesianAxisPointer",render:function(t,e,i,n){this.group.removeAll();var o=this._axisGroup;if(this._axisGroup=new sw,this.group.add(this._axisGroup),t.get("show")){var a=t.getCoordSysModel(),r=eh(a,t),s=new LD(t,r);d(zD,s.add,s),this._axisGroup.add(s.getGroup()),d(BD,function(e){t.get(e+".show")&&this["_"+e](t,a)},this),yo(o,this._axisGroup,t),VD.superCall(this,"render",t,e,i,n)}},remove:function(){this._splitAreaColors=null},_splitLine:function(t,e){var i=t.axis;if(!i.scale.isBlank()){var n=t.getModel("splitLine"),o=n.getModel("lineStyle"),a=o.get("color");a=y(a)?a:[a];for(var s=e.coordinateSystem.getRect(),l=i.isHorizontal(),u=0,h=i.getTicksCoords({tickModel:n}),c=[],d=[],f=o.getLineStyle(),p=0;p1){var c;"string"==typeof o?c=vD[o]:"function"==typeof o&&(c=o),c&&t.setData(n.downSample(n.mapDimension(s.dim),1/h,c,yD))}}}}}("line"));var GD=KM.extend({type:"series.__base_bar__",getInitialData:function(t,e){return Xs(this.getSource(),this)},getMarkerPosition:function(t){var e=this.coordinateSystem;if(e){var i=e.dataToPoint(e.clampData(t)),n=this.getData(),o=n.getLayout("offset"),a=n.getLayout("size");return i[e.getBaseAxis().isHorizontal()?0:1]+=o+a/2,i}return[NaN,NaN]},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod",itemStyle:{},emphasis:{}}});GD.extend({type:"series.bar",dependencies:["grid","polar"],brushSelector:"rect",getProgressive:function(){return!!this.get("large")&&this.get("progressive")},getProgressiveThreshold:function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t}});var WD=sb([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["stroke","barBorderColor"],["lineWidth","barBorderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),FD={getBarItemStyle:function(t){var e=WD(this,t);if(this.getBorderLineDash){var i=this.getBorderLineDash();i&&(e.lineDash=i)}return e}},HD=["itemStyle","barBorderWidth"];a(wo.prototype,FD),_s({type:"bar",render:function(t,e,i){this._updateDrawMode(t);var n=t.get("coordinateSystem");return"cartesian2d"!==n&&"polar"!==n||(this._isLargeDraw?this._renderLarge(t,e,i):this._renderNormal(t,e,i)),this.group},incrementalPrepareRender:function(t,e,i){this._clear(),this._updateDrawMode(t)},incrementalRender:function(t,e,i,n){this._incrementalRenderLarge(t,e)},_updateDrawMode:function(t){var e=t.pipelineContext.large;(null==this._isLargeDraw||e^this._isLargeDraw)&&(this._isLargeDraw=e,this._clear())},_renderNormal:function(t,e,i){var n,o=this.group,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.getBaseAxis();"cartesian2d"===s.type?n=l.isHorizontal():"polar"===s.type&&(n="angle"===l.dim);var u=t.isAnimationEnabled()?t:null;a.diff(r).add(function(e){if(a.hasValue(e)){var i=a.getItemModel(e),r=UD[s.type](a,e,i),l=ZD[s.type](a,e,i,r,n,u);a.setItemGraphicEl(e,l),o.add(l),rh(l,a,e,i,r,t,n,"polar"===s.type)}}).update(function(e,i){var l=r.getItemGraphicEl(i);if(a.hasValue(e)){var h=a.getItemModel(e),c=UD[s.type](a,e,h);l?fo(l,{shape:c},u,e):l=ZD[s.type](a,e,h,c,n,u,!0),a.setItemGraphicEl(e,l),o.add(l),rh(l,a,e,h,c,t,n,"polar"===s.type)}else o.remove(l)}).remove(function(t){var e=r.getItemGraphicEl(t);"cartesian2d"===s.type?e&&oh(t,u,e):e&&ah(t,u,e)}).execute(),this._data=a},_renderLarge:function(t,e,i){this._clear(),lh(t,this.group)},_incrementalRenderLarge:function(t,e){lh(e,this.group,!0)},dispose:B,remove:function(t){this._clear(t)},_clear:function(t){var e=this.group,i=this._data;t&&t.get("animation")&&i&&!this._isLargeDraw?i.eachItemGraphicEl(function(e){"sector"===e.type?ah(e.dataIndex,t,e):oh(e.dataIndex,t,e)}):e.removeAll(),this._data=null}});var ZD={cartesian2d:function(t,e,i,n,o,r,s){var l=new SS({shape:a({},n)});if(r){var u=l.shape,h=o?"height":"width",c={};u[h]=0,c[h]=n[h],BS[s?"updateProps":"initProps"](l,{shape:c},r,e)}return l},polar:function(t,e,i,n,o,a,s){var l=n.startAngle0?1:-1,r=n.height>0?1:-1;return{x:n.x+a*o/2,y:n.y+r*o/2,width:n.width-a*o,height:n.height-r*o}},polar:function(t,e,i){var n=t.getItemLayout(e);return{cx:n.cx,cy:n.cy,r0:n.r0,r:n.r,startAngle:n.startAngle,endAngle:n.endAngle}}},XD=In.extend({type:"largeBar",shape:{points:[]},buildPath:function(t,e){for(var i=e.points,n=this.__startPoint,o=this.__valueIdx,a=0;a0&&"scale"!==u){var d=o.getItemLayout(0),f=Math.max(i.getWidth(),i.getHeight())/2,p=m(r.removeClipPath,r);r.setClipPath(this._createClipPath(d.cx,d.cy,f,d.startAngle,d.clockwise,p,t))}this._data=o}},dispose:function(){},_createClipPath:function(t,e,i,n,o,a,r){var s=new vS({shape:{cx:t,cy:e,r0:0,r:i,startAngle:n,endAngle:n,clockwise:o}});return po(s,{shape:{endAngle:n+(o?1:-1)*Math.PI*2}},r,a),s},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var $D=function(t,e){d(e,function(e){e.update="updateView",cs(e,function(i,n){var o={};return n.eachComponent({mainType:"series",subType:t,query:i},function(t){t[e.method]&&t[e.method](i.name,i.dataIndex);var n=t.getData();n.each(function(e){var i=n.getName(e);o[i]=t.isSelected(i)||!1})}),{name:i.name,selected:o}})})},JD=function(t){return{getTargetSeries:function(e){var i={},n=R();return e.eachSeriesByType(t,function(t){t.__paletteScope=i,n.set(t.uid,t)}),n},reset:function(t,e){var i=t.getRawData(),n={},o=t.getData();o.each(function(t){var e=o.getRawIndex(t);n[e]=t}),i.each(function(e){var a=n[e],r=null!=a&&o.getItemVisual(a,"color",!0);if(r)i.setItemVisual(e,"color",r);else{var s=i.getItemModel(e).get("itemStyle.color")||t.getColorFromPalette(i.getName(e)||e+"",t.__paletteScope,i.count());i.setItemVisual(e,"color",s),null!=a&&o.setItemVisual(a,"color",s)}})}}},QD=function(t,e,i,n){var o,a,r=t.getData(),s=[],l=!1;r.each(function(i){var n,u,h,c,d=r.getItemLayout(i),f=r.getItemModel(i),p=f.getModel("label"),g=p.get("position")||f.get("emphasis.label.position"),m=f.getModel("labelLine"),v=m.get("length"),y=m.get("length2"),x=(d.startAngle+d.endAngle)/2,_=Math.cos(x),w=Math.sin(x);o=d.cx,a=d.cy;var b="inside"===g||"inner"===g;if("center"===g)n=d.cx,u=d.cy,c="center";else{var S=(b?(d.r+d.r0)/2*_:d.r*_)+o,M=(b?(d.r+d.r0)/2*w:d.r*w)+a;if(n=S+3*_,u=M+3*w,!b){var I=S+_*(v+e-d.r),T=M+w*(v+e-d.r),D=I+(_<0?-1:1)*y,A=T;n=D+(_<0?-5:5),u=A,h=[[S,M],[I,T],[D,A]]}c=b?"center":_>0?"left":"right"}var C=p.getFont(),L=p.get("rotate")?_<0?-x+Math.PI:-x:0,k=me(t.getFormattedLabel(i,"normal")||r.getName(i),C,c,"top");l=!!L,d.label={x:n,y:u,position:g,height:k.height,len:v,len2:y,linePoints:h,textAlign:c,verticalAlign:"middle",rotation:L,inside:b},b||s.push(d.label)}),!l&&t.get("avoidLabelOverlap")&&ph(s,o,a,e,i,n)},tA=2*Math.PI,eA=Math.PI/180,iA=function(t){return{seriesType:t,reset:function(t,e){var i=e.findComponents({mainType:"legend"});if(i&&i.length){var n=t.getData();n.filterSelf(function(t){for(var e=n.getName(t),o=0;o=0;s--){var l=2*s,u=n[l]-a/2,h=n[l+1]-r/2;if(t>=u&&e>=h&&t<=u+a&&e<=h+r)return s}return-1}}),oA=gh.prototype;oA.isPersistent=function(){return!this._incremental},oA.updateData=function(t){this.group.removeAll();var e=new nA({rectHover:!0,cursor:"default"});e.setShape({points:t.getLayout("symbolPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},oA.updateLayout=function(t){if(!this._incremental){var e=t.getLayout("symbolPoints");this.group.eachChild(function(t){if(null!=t.startIndex){var i=2*(t.endIndex-t.startIndex),n=4*t.startIndex*2;e=new Float32Array(e.buffer,n,i)}t.setShape("points",e)})}},oA.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>2e6?(this._incremental||(this._incremental=new On({silent:!0})),this.group.add(this._incremental)):this._incremental=null},oA.incrementalUpdate=function(t,e){var i;this._incremental?(i=new nA,this._incremental.addDisplayable(i,!0)):((i=new nA({rectHover:!0,cursor:"default",startIndex:t.start,endIndex:t.end})).incremental=!0,this.group.add(i)),i.setShape({points:e.getLayout("symbolPoints")}),this._setCommon(i,e,!!this._incremental)},oA._setCommon=function(t,e,i){var n=e.hostModel,o=e.getVisual("symbolSize");t.setShape("size",o instanceof Array?o:[o,o]),t.symbolProxy=Tl(e.getVisual("symbol"),0,0,0,0),t.setColor=t.symbolProxy.setColor;var a=t.shape.size[0]<4;t.useStyle(n.getModel("itemStyle").getItemStyle(a?["color","shadowBlur","shadowColor"]:["color"]));var r=e.getVisual("color");r&&t.setColor(r),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>=0&&(t.dataIndex=i+(t.startIndex||0))}))},oA.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},oA._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()},_s({type:"scatter",render:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).updateData(n),this._finished=!0},incrementalPrepareRender:function(t,e,i){var n=t.getData();this._updateSymbolDraw(n,t).incrementalPrepareUpdate(n),this._finished=!1},incrementalRender:function(t,e,i){this._symbolDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},updateTransform:function(t,e,i){var n=t.getData();if(this.group.dirty(),!this._finished||n.count()>1e4||!this._symbolDraw.isPersistent())return{update:!0};var o=mD().reset(t);o.progress&&o.progress({start:0,end:n.count()},n),this._symbolDraw.updateLayout(n)},_updateSymbolDraw:function(t,e){var i=this._symbolDraw,n=e.pipelineContext.large;return i&&n===this._isLargeDraw||(i&&i.remove(),i=this._symbolDraw=n?new gh:new Ql,this._isLargeDraw=n,this.group.removeAll()),this.group.add(i.group),i},remove:function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},dispose:function(){}}),ps(gD("scatter","circle")),fs(mD("scatter")),u(mh,qT),vh.prototype.getIndicatorAxes=function(){return this._indicatorAxes},vh.prototype.dataToPoint=function(t,e){var i=this._indicatorAxes[e];return this.coordToPoint(i.dataToCoord(t),e)},vh.prototype.coordToPoint=function(t,e){var i=this._indicatorAxes[e].angle;return[this.cx+t*Math.cos(i),this.cy-t*Math.sin(i)]},vh.prototype.pointToData=function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=Math.sqrt(e*e+i*i);e/=n,i/=n;for(var o,a=Math.atan2(-i,e),r=1/0,s=-1,l=0;ln[0]&&isFinite(c)&&isFinite(n[0]))}else{r.getTicks().length-1>a&&(u=i(u));var d=Math.round((n[0]+n[1])/2/u)*u,f=Math.round(a/2);r.setExtent(Ao(d-f*u),Ao(d+(a-f)*u)),r.setInterval(u)}})},vh.dimensions=[],vh.create=function(t,e){var i=[];return t.eachComponent("radar",function(n){var o=new vh(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeriesByType("radar",function(t){"radar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("radarIndex")||0])}),i},Ca.register("radar",vh);var aA=bD.valueAxis,rA=(vs({type:"radar",optionUpdated:function(){var t=this.get("boundaryGap"),e=this.get("splitNumber"),o=this.get("scale"),s=this.get("axisLine"),l=this.get("axisTick"),u=this.get("axisLabel"),h=this.get("name"),c=this.get("name.show"),d=this.get("name.formatter"),p=this.get("nameGap"),g=this.get("triggerEvent"),m=f(this.get("indicator")||[],function(f){null!=f.max&&f.max>0&&!f.min?f.min=0:null!=f.min&&f.min<0&&!f.max&&(f.max=0);var m=h;if(null!=f.color&&(m=r({color:f.color},h)),f=n(i(f),{boundaryGap:t,splitNumber:e,scale:o,axisLine:s,axisTick:l,axisLabel:u,name:f.text,nameLocation:"end",nameGap:p,nameTextStyle:m,triggerEvent:g},!1),c||(f.name=""),"string"==typeof d){var v=f.name;f.name=d.replace("{value}",null!=v?v:"")}else"function"==typeof d&&(f.name=d(f.name,f));var y=a(new wo(f,null,this.ecModel),ET);return y.mainType="radar",y.componentIndex=this.componentIndex,y},this);this.getIndicatorModels=function(){return m}},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"75%",startAngle:90,name:{show:!0},boundaryGap:[0,0],splitNumber:5,nameGap:15,scale:!1,shape:"polygon",axisLine:n({lineStyle:{color:"#bbb"}},aA.axisLine),axisLabel:yh(aA.axisLabel,!1),axisTick:yh(aA.axisTick,!1),splitLine:yh(aA.splitLine,!0),splitArea:yh(aA.splitArea,!0),indicator:[]}}),["axisLine","axisTickLabel","axisName"]);ys({type:"radar",render:function(t,e,i){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},_buildAxes:function(t){var e=t.coordinateSystem;d(f(e.getIndicatorAxes(),function(t){return new LD(t.model,{position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})}),function(t){d(rA,t.add,t),this.group.add(t.getGroup())},this)},_buildSplitLineAndArea:function(t){function e(t,e,i){var n=i%e.length;return t[n]=t[n]||[],n}var i=t.coordinateSystem,n=i.getIndicatorAxes();if(n.length){var o=t.get("shape"),a=t.getModel("splitLine"),s=t.getModel("splitArea"),l=a.getModel("lineStyle"),u=s.getModel("areaStyle"),h=a.get("show"),c=s.get("show"),p=l.get("color"),g=u.get("color");p=y(p)?p:[p],g=y(g)?g:[g];var m=[],v=[];if("circle"===o)for(var x=n[0].getTicksCoords(),_=i.cx,w=i.cy,b=0;b"+f(i,function(i,n){var o=e.get(e.mapDimension(i.dim),t);return Zo(i.name+" : "+o)}).join("
")},defaultOption:{zlevel:0,z:2,coordinateSystem:"radar",legendHoverLink:!0,radarIndex:0,lineStyle:{width:2,type:"solid"},label:{position:"top"},symbol:"emptyCircle",symbolSize:4}});_s({type:"radar",render:function(t,e,n){function o(t,e){var i=t.getItemVisual(e,"symbol")||"circle",n=t.getItemVisual(e,"color");if("none"!==i){var o=xh(t.getItemVisual(e,"symbolSize")),a=Tl(i,-1,-1,2,2,n);return a.attr({style:{strokeNoScale:!0},z2:100,scale:[o[0]/2,o[1]/2]}),a}}function a(e,i,n,a,r,s){n.removeAll();for(var l=0;l"+Zo(n+" : "+i)},getTooltipPosition:function(t){if(null!=t){var e=this.getData().getName(t),i=this.coordinateSystem,n=i.getRegion(e);return n&&i.dataToPoint(n.center)}},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},defaultOption:{zlevel:0,z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:.75,showLegendSymbol:!0,dataRangeHoverLink:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}}}});h(yA,YD);var xA="\0_ec_interaction_mutex";cs({type:"takeGlobalCursor",event:"globalCursorTaken",update:"update"},function(){}),h(kh,D_);var _A={axisPointer:1,tooltip:1,brush:1};Uh.prototype={constructor:Uh,draw:function(t,e,i,n,o){var a="geo"===t.mainType,r=t.getData&&t.getData();a&&e.eachComponent({mainType:"series",subType:"map"},function(e){r||e.getHostGeoModel()!==t||(r=e.getData())});var s=t.coordinateSystem,l=this.group,u=s.scale,h={position:s.position,scale:u};!l.childAt(0)||o?l.attr(h):fo(l,h,t),l.removeAll();var c=["itemStyle"],f=["emphasis","itemStyle"],p=["label"],g=["emphasis","label"],m=R();d(s.regions,function(e){var i=m.get(e.name)||m.set(e.name,new sw),n=new AS({shape:{paths:[]}});i.add(n);var o,s=(C=t.getRegionModel(e.name)||t).getModel(c),h=C.getModel(f),v=Fh(s),y=Fh(h),x=C.getModel(p),_=C.getModel(g);if(r){o=r.indexOfName(e.name);var w=r.getItemVisual(o,"color",!0);w&&(v.fill=w)}d(e.geometries,function(t){if("polygon"===t.type){n.shape.paths.push(new wS({shape:{points:t.exterior}}));for(var e=0;e<(t.interiors?t.interiors.length:0);e++)n.shape.paths.push(new wS({shape:{points:t.interiors[e]}}))}}),n.setStyle(v),n.style.strokeNoScale=!0,n.culling=!0;var b=x.get("show"),S=_.get("show"),M=r&&isNaN(r.get(r.mapDimension("value"),o)),I=r&&r.getItemLayout(o);if(a||M&&(b||S)||I&&I.showLabel){var T,D=a?e.name:o;(!r||o>=0)&&(T=t);var A=new fS({position:e.center.slice(),scale:[1/u[0],1/u[1]],z2:10,silent:!0});io(A.style,A.hoverStyle={},x,_,{labelFetcher:T,labelDataIndex:D,defaultText:e.name,useInsideStyle:!1},{textAlign:"center",textVerticalAlign:"middle"}),i.add(A)}if(r)r.setItemGraphicEl(o,i);else{var C=t.getRegionModel(e.name);n.eventData={componentType:"geo",geoIndex:t.componentIndex,name:e.name,region:C&&C.option||{}}}(i.__regions||(i.__regions=[])).push(e),eo(i,y,{hoverSilentOnTouch:!!t.get("selectedMode")}),l.add(i)}),this._updateController(t,e,i),Hh(this,t,l,i,n),Zh(t,l)},remove:function(){this.group.removeAll(),this._controller.dispose(),this._controllerHost={}},_updateController:function(t,e,i){function n(){var e={type:"geoRoam",componentType:l};return e[l+"Id"]=t.id,e}var o=t.coordinateSystem,r=this._controller,s=this._controllerHost;s.zoomLimit=t.get("scaleLimit"),s.zoom=o.getZoom(),r.enable(t.get("roam")||!1);var l=t.mainType;r.off("pan").on("pan",function(t,e){this._mouseDownFlag=!1,Vh(s,t,e),i.dispatchAction(a(n(),{dx:t,dy:e}))},this),r.off("zoom").on("zoom",function(t,e,o){if(this._mouseDownFlag=!1,Gh(s,t,e,o),i.dispatchAction(a(n(),{zoom:t,originX:e,originY:o})),this._updateGroup){var r=this.group,l=r.scale;r.traverse(function(t){"text"===t.type&&t.attr("scale",[1/l[0],1/l[1]])})}},this),r.setPointerChecker(function(e,n,a){return o.getViewRectAfterRoam().contain(n,a)&&!Wh(e,i,t)})}},_s({type:"map",render:function(t,e,i,n){if(!n||"mapToggleSelect"!==n.type||n.from!==this.uid){var o=this.group;if(o.removeAll(),!t.getHostGeoModel()){if(n&&"geoRoam"===n.type&&"series"===n.componentType&&n.seriesId===t.id)(a=this._mapDraw)&&o.add(a.group);else if(t.needsDrawMap){var a=this._mapDraw||new Uh(i,!0);o.add(a.group),a.draw(t,e,i,this,n),this._mapDraw=a}else this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null;t.get("showLegendSymbol")&&e.getComponent("legend")&&this._renderSymbols(t,e,i)}}},remove:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null,this.group.removeAll()},dispose:function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null},_renderSymbols:function(t,e,i){var n=t.originalData,o=this.group;n.each(n.mapDimension("value"),function(e,i){if(!isNaN(e)){var a=n.getItemLayout(i);if(a&&a.point){var r=a.point,s=a.offset,l=new pS({style:{fill:t.getData().getVisual("color")},shape:{cx:r[0]+9*s,cy:r[1],r:3},silent:!0,z2:s?8:10});if(!s){var u=t.mainSeries.getData(),h=n.getName(i),c=u.indexOfName(h),d=n.getItemModel(i),f=d.getModel("label"),p=d.getModel("emphasis.label"),g=u.getItemGraphicEl(c),m=D(t.getFormattedLabel(i,"normal"),h),v=D(t.getFormattedLabel(i,"emphasis"),m),y=function(){var t=no({},p,{text:p.get("show")?v:null},{isRectText:!0,useInsideStyle:!1},!0);l.style.extendFrom(t),l.__mapOriginalZ2=l.z2,l.z2+=1},x=function(){no(l.style,f,{text:f.get("show")?m:null,textPosition:f.getShallow("position")||"bottom"},{isRectText:!0,useInsideStyle:!1}),null!=l.__mapOriginalZ2&&(l.z2=l.__mapOriginalZ2,l.__mapOriginalZ2=null)};g.on("mouseover",y).on("mouseout",x).on("emphasis",y).on("normal",x),x()}o.add(l)}}})}}),cs({type:"geoRoam",event:"geoRoam",update:"updateTransform"},function(t,e){var i=t.componentType||"series";e.eachComponent({mainType:i,query:t},function(e){var n=e.coordinateSystem;if("geo"===n.type){var o=Xh(n,t,e.get("scaleLimit"));e.setCenter&&e.setCenter(o.center),e.setZoom&&e.setZoom(o.zoom),"series"===i&&d(e.seriesGroup,function(t){t.setCenter(o.center),t.setZoom(o.zoom)})}})});fs(function(t){var e={};t.eachSeriesByType("map",function(i){var n=i.getMapType();if(!i.getHostGeoModel()&&!e[n]){var o={};d(i.seriesGroup,function(e){var i=e.coordinateSystem,n=e.originalData;e.get("showLegendSymbol")&&t.getComponent("legend")&&n.each(n.mapDimension("value"),function(t,e){var a=n.getName(e),r=i.getRegion(a);if(r&&!isNaN(t)){var s=o[a]||0,l=i.dataToPoint(r.center);o[a]=s+1,n.setItemLayout(e,{point:l,offset:s})}})});var a=i.getData();a.each(function(t){var e=a.getName(t),i=a.getItemLayout(t)||{};i.showLabel=!o[e],a.setItemLayout(t,i)}),e[n]=!0}})}),ps(function(t){t.eachSeriesByType("map",function(t){var e=t.get("color"),i=t.getModel("itemStyle"),n=i.get("areaColor"),o=i.get("color")||e[t.seriesIndex%e.length];t.getData().setVisual({areaColor:n,color:o})})}),hs(LI.PROCESSOR.STATISTIC,function(t){var e={};t.eachSeriesByType("map",function(t){var i=t.getHostGeoModel(),n=i?"o"+i.id:"i"+t.getMapType();(e[n]=e[n]||[]).push(t)}),d(e,function(t,e){for(var i=jh(f(t,function(t){return t.getData()}),t[0].get("mapValueCalculation")),n=0;ne&&(e=n.height)}this.height=e+1},getNodeById:function(t){if(this.getId()===t)return this;for(var e=0,i=this.children,n=i.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},getLayout:function(){return this.hostTree.data.getItemLayout(this.dataIndex)},getModel:function(t){if(!(this.dataIndex<0)){var e,i=this.hostTree,n=i.data.getItemModel(this.dataIndex),o=this.getLevelModel();return o||0!==this.children.length&&(0===this.children.length||!1!==this.isExpand)||(e=this.getLeavesModel()),n.getModel(t,(o||e||i.hostModel).getModel(t))}},getLevelModel:function(){return(this.hostTree.levelModels||[])[this.depth]},getLeavesModel:function(){return this.hostTree.leavesModel},setVisual:function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},getVisual:function(t,e){return this.hostTree.data.getItemVisual(this.dataIndex,t,e)},getRawIndex:function(){return this.hostTree.data.getRawIndex(this.dataIndex)},getId:function(){return this.hostTree.data.getId(this.dataIndex)},isAncestorOf:function(t){for(var e=t.parentNode;e;){if(e===this)return!0;e=e.parentNode}return!1},isDescendantOf:function(t){return t!==this&&t.isAncestorOf(this)}},ic.prototype={constructor:ic,type:"tree",eachNode:function(t,e,i){this.root.eachNode(t,e,i)},getNodeByDataIndex:function(t){var e=this.data.getRawIndex(t);return this._nodes[e]},getNodeByName:function(t){return this.root.getNodeByName(t)},update:function(){for(var t=this.data,e=this._nodes,i=0,n=e.length;ia&&(a=t.depth)});var r=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:a;return o.root.eachNode("preorder",function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=r}),o.data},getOrient:function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},formatTooltip:function(t){for(var e=this.getData().tree,i=e.root.children[0],n=e.getNodeByDataIndex(t),o=n.getValue(),a=n.name;n&&n!==i;)a=n.parentNode.name+"."+a,n=n.parentNode;return Zo(a+(isNaN(o)||null==o?"":" : "+o))},defaultOption:{zlevel:0,z:2,left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderColor:"#c23531",borderWidth:1.5},label:{show:!0,color:"#555"},leaves:{label:{show:!0}},animationEasing:"linear",animationDuration:700,animationDurationUpdate:1e3}}),_s({type:"tree",init:function(t,e){this._oldTree,this._mainGroup=new sw,this.group.add(this._mainGroup)},render:function(t,e,i,n){var o=t.getData(),a=t.layoutInfo,r=this._mainGroup,s=t.get("layout");"radial"===s?r.attr("position",[a.x+a.width/2,a.y+a.height/2]):r.attr("position",[a.x,a.y]);var l=this._data,u={expandAndCollapse:t.get("expandAndCollapse"),layout:s,orient:t.getOrient(),curvature:t.get("lineStyle.curveness"),symbolRotate:t.get("symbolRotate"),symbolOffset:t.get("symbolOffset"),hoverAnimation:t.get("hoverAnimation"),useNameLabel:!0,fadeIn:!0};o.diff(l).add(function(e){vc(o,e)&&xc(o,e,null,r,t,u)}).update(function(e,i){var n=l.getItemGraphicEl(i);vc(o,e)?xc(o,e,n,r,t,u):n&&_c(l,i,n,r,t,u)}).remove(function(e){var i=l.getItemGraphicEl(e);i&&_c(l,e,i,r,t,u)}).execute(),!0===u.expandAndCollapse&&o.eachItemGraphicEl(function(e,n){e.off("click").on("click",function(){i.dispatchAction({type:"treeExpandAndCollapse",seriesId:t.id,dataIndex:n})})}),this._data=o},dispose:function(){},remove:function(){this._mainGroup.removeAll(),this._data=null}}),cs({type:"treeExpandAndCollapse",event:"treeExpandAndCollapse",update:"update"},function(t,e){e.eachComponent({mainType:"series",subType:"tree",query:t},function(e){var i=t.dataIndex,n=e.getData().tree.getNodeByDataIndex(i);n.isExpand=!n.isExpand})});ps(gD("tree","circle")),fs(function(t,e){t.eachSeriesByType("tree",function(t){Mc(t,e)})}),KM.extend({type:"series.treemap",layoutMode:"box",dependencies:["grid","polar"],_viewRoot:null,defaultOption:{progressive:0,hoverLayerThreshold:1/0,left:"center",top:"middle",right:null,bottom:null,width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",borderColor:"rgba(255,255,255,0.7)",borderWidth:1,shadowColor:"rgba(150,150,150,1)",shadowBlur:3,shadowOffsetX:0,shadowOffsetY:0,textStyle:{color:"#fff"}},emphasis:{textStyle:{}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",ellipsis:!0},upperLabel:{show:!1,position:[0,"50%"],height:20,color:"#fff",ellipsis:!0,verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],color:"#fff",ellipsis:!0,verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},getInitialData:function(t,e){var i={name:t.name,children:t.data};Cc(i);var n=t.levels||[];n=t.levels=Lc(n,e);var o={};return o.levels=n,ic.createTree(i,this,o).data},optionUpdated:function(){this.resetViewRoot()},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=Fo(y(i)?i[0]:i);return Zo(e.getName(t)+": "+n)},getDataParams:function(t){var e=KM.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(t);return e.treePathInfo=Ac(i,this),e},setLayoutInfo:function(t){this.layoutInfo=this.layoutInfo||{},a(this.layoutInfo,t)},mapIdToIndex:function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=R(),this._idIndexMapCount=0);var i=e.get(t);return null==i&&e.set(t,i=this._idIndexMapCount++),i},getViewRoot:function(){return this._viewRoot},resetViewRoot:function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)}});var IA=5;kc.prototype={constructor:kc,render:function(t,e,i,n){var o=t.getModel("breadcrumb"),a=this.group;if(a.removeAll(),o.get("show")&&i){var r=o.getModel("itemStyle"),s=r.getModel("textStyle"),l={pos:{left:o.get("left"),right:o.get("right"),top:o.get("top"),bottom:o.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:o.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(i,l,s),this._renderContent(t,l,r,s,n),ta(a,l.pos,l.box)}},_prepare:function(t,e,i){for(var n=t;n;n=n.parentNode){var o=n.getModel().get("name"),a=i.getTextRect(o),r=Math.max(a.width+16,e.emptyItemWidth);e.totalWidth+=r+8,e.renderList.push({node:n,text:o,width:r})}},_renderContent:function(t,e,i,n,o){for(var a=0,s=e.emptyItemWidth,l=t.get("breadcrumb.height"),u=Jo(e.pos,e.box),h=e.totalWidth,c=e.renderList,d=c.length-1;d>=0;d--){var f=c[d],p=f.node,g=f.width,m=f.text;h>u.width&&(h-=g-s,g=s,m=null);var y=new wS({shape:{points:Pc(a,0,g,l,d===c.length-1,0===d)},style:r(i.getItemStyle(),{lineJoin:"bevel",text:m,textFill:n.getTextColor(),textFont:n.getFont()}),z:10,onclick:v(o,p)});this.group.add(y),Nc(y,t,p),a+=g+8}},remove:function(){this.group.removeAll()}};var TA=m,DA=sw,AA=SS,CA=d,LA=["label"],kA=["emphasis","label"],PA=["upperLabel"],NA=["emphasis","upperLabel"],OA=10,EA=1,RA=2,zA=sb([["fill","color"],["stroke","strokeColor"],["lineWidth","strokeWidth"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),BA=function(t){var e=zA(t);return e.stroke=e.fill=e.lineWidth=null,e};_s({type:"treemap",init:function(t,e){this._containerGroup,this._storage={nodeGroup:[],background:[],content:[]},this._oldTree,this._breadcrumb,this._controller,this._state="ready"},render:function(t,e,i,n){if(!(l(e.findComponents({mainType:"series",subType:"treemap",query:n}),t)<0)){this.seriesModel=t,this.api=i,this.ecModel=e;var o=Ic(n,["treemapZoomToNode","treemapRootToNode"],t),a=n&&n.type,r=t.layoutInfo,s=!this._oldTree,u=this._storage,h="treemapRootToNode"===a&&o&&u?{rootNodeGroup:u.nodeGroup[o.node.getRawIndex()],direction:n.direction}:null,c=this._giveContainerGroup(r),d=this._doRender(c,t,h);s||a&&"treemapZoomToNode"!==a&&"treemapRootToNode"!==a?d.renderFinally():this._doAnimation(c,d,t,h),this._resetController(i),this._renderBreadcrumb(t,i,o)}},_giveContainerGroup:function(t){var e=this._containerGroup;return e||(e=this._containerGroup=new DA,this._initEvents(e),this.group.add(e)),e.attr("position",[t.x,t.y]),e},_doRender:function(t,e,i){function n(t,e,i,o,a){function r(t){return t.getId()}function s(r,s){var l=null!=r?t[r]:null,u=null!=s?e[s]:null,c=h(l,u,i,a);c&&n(l&&l.viewChildren||[],u&&u.viewChildren||[],c,o,a+1)}o?(e=t,CA(t,function(t,e){!t.isRemoved()&&s(e,e)})):new Ss(e,t,r,r).add(s).update(s).remove(v(s,null)).execute()}var o=e.getData().tree,a=this._oldTree,r={nodeGroup:[],background:[],content:[]},s={nodeGroup:[],background:[],content:[]},l=this._storage,u=[],h=v(Ec,e,s,l,i,r,u);n(o.root?[o.root]:[],a&&a.root?[a.root]:[],t,o===a||!a,0);var c=function(t){var e={nodeGroup:[],background:[],content:[]};return t&&CA(t,function(t,i){var n=e[i];CA(t,function(t){t&&(n.push(t),t.__tmWillDelete=1)})}),e}(l);return this._oldTree=o,this._storage=s,{lastsForAnimation:r,willDeleteEls:c,renderFinally:function(){CA(c,function(t){CA(t,function(t){t.parent&&t.parent.remove(t)})}),CA(u,function(t){t.invisible=!0,t.dirty()})}}},_doAnimation:function(t,e,i,n){if(i.get("animation")){var o=i.get("animationDurationUpdate"),r=i.get("animationEasing"),s=Oc();CA(e.willDeleteEls,function(t,e){CA(t,function(t,i){if(!t.invisible){var a,l=t.parent;if(n&&"drillDown"===n.direction)a=l===n.rootNodeGroup?{shape:{x:0,y:0,width:l.__tmNodeWidth,height:l.__tmNodeHeight},style:{opacity:0}}:{style:{opacity:0}};else{var u=0,h=0;l.__tmWillDelete||(u=l.__tmNodeWidth/2,h=l.__tmNodeHeight/2),a="nodeGroup"===e?{position:[u,h],style:{opacity:0}}:{shape:{x:u,y:h,width:0,height:0},style:{opacity:0}}}a&&s.add(t,a,o,r)}})}),CA(this._storage,function(t,i){CA(t,function(t,n){var l=e.lastsForAnimation[i][n],u={};l&&("nodeGroup"===i?l.old&&(u.position=t.position.slice(),t.attr("position",l.old)):(l.old&&(u.shape=a({},t.shape),t.setShape(l.old)),l.fadein?(t.setStyle("opacity",0),u.style={opacity:1}):1!==t.style.opacity&&(u.style={opacity:1})),s.add(t,u,o,r))})},this),this._state="animating",s.done(TA(function(){this._state="ready",e.renderFinally()},this)).start()}},_resetController:function(t){var e=this._controller;e||((e=this._controller=new kh(t.getZr())).enable(this.seriesModel.get("roam")),e.on("pan",TA(this._onPan,this)),e.on("zoom",TA(this._onZoom,this)));var i=new $t(0,0,t.getWidth(),t.getHeight());e.setPointerChecker(function(t,e,n){return i.contain(e,n)})},_clearController:function(){var t=this._controller;t&&(t.dispose(),t=null)},_onPan:function(t,e){if("animating"!==this._state&&(Math.abs(t)>3||Math.abs(e)>3)){var i=this.seriesModel.getData().tree.root;if(!i)return;var n=i.getLayout();if(!n)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:n.x+t,y:n.y+e,width:n.width,height:n.height}})}},_onZoom:function(t,e,i){if("animating"!==this._state){var n=this.seriesModel.getData().tree.root;if(!n)return;var o=n.getLayout();if(!o)return;var a=new $t(o.x,o.y,o.width,o.height),r=this.seriesModel.layoutInfo;e-=r.x,i-=r.y;var s=st();ct(s,s,[-e,-i]),ft(s,s,[t,t]),ct(s,s,[e,i]),a.applyTransform(s),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:a.x,y:a.y,width:a.width,height:a.height}})}},_initEvents:function(t){t.on("click",function(t){if("ready"===this._state){var e=this.seriesModel.get("nodeClick",!0);if(e){var i=this.findTarget(t.offsetX,t.offsetY);if(i){var n=i.node;if(n.getLayout().isLeafRoot)this._rootToNode(i);else if("zoomToNode"===e)this._zoomToNode(i);else if("link"===e){var o=n.hostTree.data.getItemModel(n.dataIndex),a=o.get("link",!0),r=o.get("target",!0)||"blank";a&&window.open(a,r)}}}}},this)},_renderBreadcrumb:function(t,e,i){i||(i=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(i={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new kc(this.group))).render(t,e,i.node,TA(function(e){"animating"!==this._state&&(Dc(t.getViewRoot(),e)?this._rootToNode({node:e}):this._zoomToNode({node:e}))},this))},remove:function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},dispose:function(){this._clearController()},_zoomToNode:function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},_rootToNode:function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},findTarget:function(t,e){var i;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},function(n){var o=this._storage.background[n.getRawIndex()];if(o){var a=o.transformCoordToLocal(t,e),r=o.shape;if(!(r.x<=a[0]&&a[0]<=r.x+r.width&&r.y<=a[1]&&a[1]<=r.y+r.height))return!1;i={node:n,offsetX:a[0],offsetY:a[1]}}},this),i}});for(var VA=["treemapZoomToNode","treemapRender","treemapMove"],GA=0;GA=0&&t.call(e,i[o],o)},rC.eachEdge=function(t,e){for(var i=this.edges,n=i.length,o=0;o=0&&i[o].node1.dataIndex>=0&&i[o].node2.dataIndex>=0&&t.call(e,i[o],o)},rC.breadthFirstTraverse=function(t,e,i,n){if(gd.isInstance(e)||(e=this._nodesMap[pd(e)]),e){for(var o="out"===i?"outEdges":"in"===i?"inEdges":"edges",a=0;a=0&&i.node2.dataIndex>=0});for(var o=0,a=n.length;o=0&&this[t][e].setItemVisual(this.dataIndex,i,n)},getVisual:function(i,n){return this[t][e].getItemVisual(this.dataIndex,i,n)},setLayout:function(i,n){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,i,n)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}};h(gd,sC("hostGraph","data")),h(md,sC("hostGraph","edgeData")),aC.Node=gd,aC.Edge=md,Wi(gd),Wi(md);var lC=function(t,e,i,n,o){for(var a=new aC(n),r=0;r "+f)),h++)}var p,g=i.get("coordinateSystem");if("cartesian2d"===g||"polar"===g)p=Xs(t,i);else{var m=Ca.get(g),v=m&&"view"!==m.type?m.dimensions||[]:[];l(v,"value")<0&&v.concat(["value"]);var y=hT(t,{coordDimensions:v});(p=new sT(y,i)).initData(t)}var x=new sT(["value"],i);return x.initData(u,s),o&&o(p,x),Yh({mainData:p,struct:a,structAttr:"graph",datas:{node:p,edge:x},datasAttr:{node:"data",edge:"edgeData"}}),a.update(),a},uC=xs({type:"series.graph",init:function(t){uC.superApply(this,"init",arguments),this.legendDataProvider=function(){return this._categoriesData},this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeOption:function(t){uC.superApply(this,"mergeOption",arguments),this.fillDataTextStyle(t.edges||t.links),this._updateCategoriesData()},mergeDefaultAndTheme:function(t){uC.superApply(this,"mergeDefaultAndTheme",arguments),Mi(t,["edgeLabel"],["show"])},getInitialData:function(t,e){var i=t.edges||t.links||[],n=t.data||t.nodes||[],o=this;if(n&&i)return lC(n,i,this,!0,function(t,i){function n(t){return(t=this.parsePath(t))&&"label"===t[0]?r:t&&"emphasis"===t[0]&&"label"===t[1]?l:this.parentModel}t.wrapMethod("getItemModel",function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t});var a=o.getModel("edgeLabel"),r=new wo({label:a.option},a.parentModel,e),s=o.getModel("emphasis.edgeLabel"),l=new wo({emphasis:{label:s.option}},s.parentModel,e);i.wrapMethod("getItemModel",function(t){return t.customizeGetParent(n),t})}).data},getGraph:function(){return this.getData().graph},getEdgeData:function(){return this.getGraph().edgeData},getCategoriesData:function(){return this._categoriesData},formatTooltip:function(t,e,i){if("edge"===i){var n=this.getData(),o=this.getDataParams(t,i),a=n.graph.getEdgeByIndex(t),r=n.getName(a.node1.dataIndex),s=n.getName(a.node2.dataIndex),l=[];return null!=r&&l.push(r),null!=s&&l.push(s),l=Zo(l.join(" > ")),o.value&&(l+=" : "+Zo(o.value)),l}return uC.superApply(this,"formatTooltip",arguments)},_updateCategoriesData:function(){var t=f(this.option.categories||[],function(t){return null!=t.value?t:a({value:0},t)}),e=new sT(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray(function(t){return e.getItemModel(t,!0)})},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},isAnimationEnabled:function(){return uC.superCall(this,"isAnimationEnabled")&&!("force"===this.get("layout")&&this.get("force.layoutAnimation"))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",legendHoverLink:!0,hoverAnimation:!0,layout:null,focusNodeAdjacency:!1,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle"},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,curveness:0,opacity:.5},emphasis:{label:{show:!0}}}}),hC=MS.prototype,cC=TS.prototype,dC=En({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){(vd(e)?hC:cC).buildPath(t,e)},pointAt:function(t){return vd(this.shape)?hC.pointAt.call(this,t):cC.pointAt.call(this,t)},tangentAt:function(t){var e=this.shape,i=vd(e)?[e.x2-e.x1,e.y2-e.y1]:cC.tangentAt.call(this,t);return q(i,i)}}),fC=["fromSymbol","toSymbol"],pC=bd.prototype;pC.beforeUpdate=function(){var t=this,e=t.childOfName("fromSymbol"),i=t.childOfName("toSymbol"),n=t.childOfName("label");if(e||i||!n.ignore){for(var o=1,a=this.parent;a;)a.scale&&(o/=a.scale[0]),a=a.parent;var r=t.childOfName("line");if(this.__dirty||r.__dirty){var s=r.shape.percent,l=r.pointAt(0),u=r.pointAt(s),h=U([],u,l);if(q(h,h),e&&(e.attr("position",l),c=r.tangentAt(0),e.attr("rotation",Math.PI/2-Math.atan2(c[1],c[0])),e.attr("scale",[o*s,o*s])),i){i.attr("position",u);var c=r.tangentAt(1);i.attr("rotation",-Math.PI/2-Math.atan2(c[1],c[0])),i.attr("scale",[o*s,o*s])}if(!n.ignore){n.attr("position",u);var d,f,p,g=5*o;if("end"===n.__position)d=[h[0]*g+u[0],h[1]*g+u[1]],f=h[0]>.8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";else if("middle"===n.__position){var m=s/2,v=[(c=r.tangentAt(m))[1],-c[0]],y=r.pointAt(m);v[1]>0&&(v[0]=-v[0],v[1]=-v[1]),d=[y[0]+v[0]*g,y[1]+v[1]*g],f="center",p="bottom";var x=-Math.atan2(c[1],c[0]);u[0].8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";n.attr({style:{textVerticalAlign:n.__verticalAlign||p,textAlign:n.__textAlign||f},position:d,scale:[o,o]})}}}},pC._createLine=function(t,e,i){var n=t.hostModel,o=_d(t.getItemLayout(e));o.shape.percent=0,po(o,{shape:{percent:1}},n,e),this.add(o);var a=new fS({name:"label"});this.add(a),d(fC,function(i){var n=xd(i,t,e);this.add(n),this[yd(i)]=t.getItemVisual(e,i)},this),this._updateCommonStl(t,e,i)},pC.updateData=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=t.getItemLayout(e),r={shape:{}};wd(r.shape,a),fo(o,r,n,e),d(fC,function(i){var n=t.getItemVisual(e,i),o=yd(i);if(this[o]!==n){this.remove(this.childOfName(i));var a=xd(i,t,e);this.add(a)}this[o]=n},this),this._updateCommonStl(t,e,i)},pC._updateCommonStl=function(t,e,i){var n=t.hostModel,o=this.childOfName("line"),a=i&&i.lineStyle,s=i&&i.hoverLineStyle,l=i&&i.labelModel,u=i&&i.hoverLabelModel;if(!i||t.hasItemOption){var h=t.getItemModel(e);a=h.getModel("lineStyle").getLineStyle(),s=h.getModel("emphasis.lineStyle").getLineStyle(),l=h.getModel("label"),u=h.getModel("emphasis.label")}var c=t.getItemVisual(e,"color"),f=A(t.getItemVisual(e,"opacity"),a.opacity,1);o.useStyle(r({strokeNoScale:!0,fill:"none",stroke:c,opacity:f},a)),o.hoverStyle=s,d(fC,function(t){var e=this.childOfName(t);e&&(e.setColor(c),e.setStyle({opacity:f}))},this);var p,g,m=l.getShallow("show"),v=u.getShallow("show"),y=this.childOfName("label");if((m||v)&&(p=c||"#000",null==(g=n.getFormattedLabel(e,"normal",t.dataType)))){var x=n.getRawValue(e);g=null==x?t.getName(e):isFinite(x)?Ao(x):x}var _=m?g:null,w=v?D(n.getFormattedLabel(e,"emphasis",t.dataType),g):null,b=y.style;null==_&&null==w||(no(y.style,l,{text:_},{autoColor:p}),y.__textAlign=b.textAlign,y.__verticalAlign=b.textVerticalAlign,y.__position=l.get("position")||"middle"),y.hoverStyle=null!=w?{text:w,textFill:u.getTextColor(!0),fontStyle:u.getShallow("fontStyle"),fontWeight:u.getShallow("fontWeight"),fontSize:u.getShallow("fontSize"),fontFamily:u.getShallow("fontFamily")}:{text:null},y.ignore=!m&&!v,eo(this)},pC.highlight=function(){this.trigger("emphasis")},pC.downplay=function(){this.trigger("normal")},pC.updateLayout=function(t,e){this.setLinePoints(t.getItemLayout(e))},pC.setLinePoints=function(t){var e=this.childOfName("line");wd(e.shape,t),e.dirty()},u(bd,sw);var gC=Sd.prototype;gC.isPersistent=function(){return!0},gC.updateData=function(t){var e=this,i=e.group,n=e._lineData;e._lineData=t,n||i.removeAll();var o=Td(t);t.diff(n).add(function(i){Md(e,t,i,o)}).update(function(i,a){Id(e,n,t,a,i,o)}).remove(function(t){i.remove(n.getItemGraphicEl(t))}).execute()},gC.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl(function(e,i){e.updateLayout(t,i)},this)},gC.incrementalPrepareUpdate=function(t){this._seriesScope=Td(t),this._lineData=null,this.group.removeAll()},gC.incrementalUpdate=function(t,e){for(var i=t.start;i=o/3?1:2),l=e.y-n(r)*a*(a>=o/3?1:2);r=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+i(r)*a,e.y+n(r)*a),t.lineTo(e.x+i(e.angle)*o,e.y+n(e.angle)*o),t.lineTo(e.x-i(r)*a,e.y-n(r)*a),t.lineTo(s,l)}}),DC=2*Math.PI,AC=(gr.extend({type:"gauge",render:function(t,e,i){this.group.removeAll();var n=t.get("axisLine.lineStyle.color"),o=Vd(t,i);this._renderMain(t,e,i,n,o)},dispose:function(){},_renderMain:function(t,e,i,n,o){for(var a=this.group,r=t.getModel("axisLine").getModel("lineStyle"),s=t.get("clockwise"),l=-t.get("startAngle")/180*Math.PI,u=-t.get("endAngle")/180*Math.PI,h=(u-l)%DC,c=l,d=r.get("width"),f=0;f=t&&(0===e?0:n[e-1][0]).4?"bottom":"middle",textAlign:D<-.4?"left":D>.4?"right":"center"},{autoColor:P}),silent:!0}))}if(g.get("show")&&T!==v){for(var N=0;N<=y;N++){var D=Math.cos(w),A=Math.sin(w),O=new MS({shape:{x1:D*c+u,y1:A*c+h,x2:D*(c-_)+u,y2:A*(c-_)+h},silent:!0,style:I});"auto"===I.stroke&&O.setStyle({stroke:n((T+N/y)/v)}),l.add(O),w+=S}w-=S}else w+=b}},_renderPointer:function(t,e,i,n,o,a,r,s){var l=this.group,u=this._data;if(t.get("pointer.show")){var h=[+t.get("min"),+t.get("max")],c=[a,r],d=t.getData(),f=d.mapDimension("value");d.diff(u).add(function(e){var i=new TC({shape:{angle:a}});po(i,{shape:{angle:To(d.get(f,e),h,c,!0)}},t),l.add(i),d.setItemGraphicEl(e,i)}).update(function(e,i){var n=u.getItemGraphicEl(i);fo(n,{shape:{angle:To(d.get(f,e),h,c,!0)}},t),l.add(n),d.setItemGraphicEl(e,n)}).remove(function(t){var e=u.getItemGraphicEl(t);l.remove(e)}).execute(),d.eachItemGraphicEl(function(t,e){var i=d.getItemModel(e),a=i.getModel("pointer");t.setShape({x:o.cx,y:o.cy,width:Do(a.get("width"),o.r),r:Do(a.get("length"),o.r)}),t.useStyle(i.getModel("itemStyle").getItemStyle()),"auto"===t.style.fill&&t.setStyle("fill",n(To(d.get(f,e),h,[0,1],!0))),eo(t,i.getModel("emphasis.itemStyle").getItemStyle())}),this._data=d}else u&&u.eachItemGraphicEl(function(t){l.remove(t)})},_renderTitle:function(t,e,i,n,o){var a=t.getData(),r=a.mapDimension("value"),s=t.getModel("title");if(s.get("show")){var l=s.get("offsetCenter"),u=o.cx+Do(l[0],o.r),h=o.cy+Do(l[1],o.r),c=+t.get("min"),d=+t.get("max"),f=n(To(t.getData().get(r,0),[c,d],[0,1],!0));this.group.add(new fS({silent:!0,style:no({},s,{x:u,y:h,text:a.getName(0),textAlign:"center",textVerticalAlign:"middle"},{autoColor:f,forceRich:!0})}))}},_renderDetail:function(t,e,i,n,o){var a=t.getModel("detail"),r=+t.get("min"),s=+t.get("max");if(a.get("show")){var l=a.get("offsetCenter"),u=o.cx+Do(l[0],o.r),h=o.cy+Do(l[1],o.r),c=Do(a.get("width"),o.r),d=Do(a.get("height"),o.r),f=t.getData(),p=f.get(f.mapDimension("value"),0),g=n(To(p,[r,s],[0,1],!0));this.group.add(new fS({silent:!0,style:no({},a,{x:u,y:h,text:Gd(p,a.get("formatter")),textWidth:isNaN(c)?null:c,textHeight:isNaN(d)?null:d,textAlign:"center",textVerticalAlign:"middle"},{autoColor:g,forceRich:!0})}))}}}),xs({type:"series.funnel",init:function(t){AC.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()},this._defaultLabelLine(t)},getInitialData:function(t,e){return jD(this,["value"])},_defaultLabelLine:function(t){Mi(t,"labelLine",["show"]);var e=t.labelLine,i=t.emphasis.labelLine;e.show=e.show&&t.label.show,i.show=i.show&&t.emphasis.label.show},getDataParams:function(t){var e=this.getData(),i=AC.superCall(this,"getDataParams",t),n=e.mapDimension("value"),o=e.getSum(n);return i.percent=o?+(e.get(n,t)/o*100).toFixed(2):0,i.$vars.push("percent"),i},defaultOption:{zlevel:0,z:2,legendHoverLink:!0,left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1,type:"solid"}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}}}})),CC=Wd.prototype,LC=["itemStyle","opacity"];CC.updateData=function(t,e,i){var n=this.childAt(0),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e),l=t.getItemModel(e).get(LC);l=null==l?1:l,n.useStyle({}),i?(n.setShape({points:s.points}),n.setStyle({opacity:0}),po(n,{style:{opacity:l}},o,e)):fo(n,{style:{opacity:l},shape:{points:s.points}},o,e);var u=a.getModel("itemStyle"),h=t.getItemVisual(e,"color");n.setStyle(r({lineJoin:"round",fill:h},u.getItemStyle(["opacity"]))),n.hoverStyle=u.getModel("emphasis").getItemStyle(),this._updateLabel(t,e),eo(this)},CC._updateLabel=function(t,e){var i=this.childAt(1),n=this.childAt(2),o=t.hostModel,a=t.getItemModel(e),r=t.getItemLayout(e).label,s=t.getItemVisual(e,"color");fo(i,{shape:{points:r.linePoints||r.linePoints}},o,e),fo(n,{style:{x:r.x,y:r.y}},o,e),n.attr({rotation:r.rotation,origin:[r.x,r.y],z2:10});var l=a.getModel("label"),u=a.getModel("emphasis.label"),h=a.getModel("labelLine"),c=a.getModel("emphasis.labelLine"),s=t.getItemVisual(e,"color");io(n.style,n.hoverStyle={},l,u,{labelFetcher:t.hostModel,labelDataIndex:e,defaultText:t.getName(e),autoColor:s,useInsideStyle:!!r.inside},{textAlign:r.textAlign,textVerticalAlign:r.verticalAlign}),n.ignore=n.normalIgnore=!l.get("show"),n.hoverIgnore=!u.get("show"),i.ignore=i.normalIgnore=!h.get("show"),i.hoverIgnore=!c.get("show"),i.setStyle({stroke:s}),i.setStyle(h.getModel("lineStyle").getLineStyle()),i.hoverStyle=c.getModel("lineStyle").getLineStyle()},u(Wd,sw);gr.extend({type:"funnel",render:function(t,e,i){var n=t.getData(),o=this._data,a=this.group;n.diff(o).add(function(t){var e=new Wd(n,t);n.setItemGraphicEl(t,e),a.add(e)}).update(function(t,e){var i=o.getItemGraphicEl(e);i.updateData(n,t),a.add(i),n.setItemGraphicEl(t,i)}).remove(function(t){var e=o.getItemGraphicEl(t);a.remove(e)}).execute(),this._data=n},remove:function(){this.group.removeAll(),this._data=null},dispose:function(){}});ps(JD("funnel")),fs(function(t,e,i){t.eachSeriesByType("funnel",function(t){var i=t.getData(),n=i.mapDimension("value"),o=t.get("sort"),a=Fd(t,e),r=Hd(i,o),s=[Do(t.get("minSize"),a.width),Do(t.get("maxSize"),a.width)],l=i.getDataExtent(n),u=t.get("min"),h=t.get("max");null==u&&(u=Math.min(l[0],0)),null==h&&(h=l[1]);var c=t.get("funnelAlign"),d=t.get("gap"),f=(a.height-d*(i.count()-1))/i.count(),p=a.y,g=function(t,e){var o,r=To(i.get(n,t)||0,[u,h],s,!0);switch(c){case"left":o=a.x;break;case"center":o=a.x+(a.width-r)/2;break;case"right":o=a.x+a.width-r}return[[o,e],[o+r,e]]};"ascending"===o&&(f=-f,d=-d,p+=a.height,r=r.reverse());for(var m=0;ma&&(e[1-n]=e[n]+h.sign*a),e},NC=d,OC=Math.min,EC=Math.max,RC=Math.floor,zC=Math.ceil,BC=Ao,VC=Math.PI;qd.prototype={type:"parallel",constructor:qd,_init:function(t,e,i){var n=t.dimensions,o=t.parallelAxisIndex;NC(n,function(t,i){var n=o[i],a=e.getComponent("parallelAxis",n),r=this._axesMap.set(t,new kC(t,xl(a),[0,0],a.get("type"),n)),s="category"===r.type;r.onBand=s&&a.get("boundaryGap"),r.inverse=a.get("inverse"),a.axis=r,r.model=a,r.coordinateSystem=a.coordinateSystem=this},this)},update:function(t,e){this._updateAxesFromSeries(this._model,t)},containPoint:function(t){var e=this._makeLayoutInfo(),i=e.axisBase,n=e.layoutBase,o=e.pixelDimIndex,a=t[1-o],r=t[o];return a>=i&&a<=i+e.axisLength&&r>=n&&r<=n+e.layoutLength},getModel:function(){return this._model},_updateAxesFromSeries:function(t,e){e.eachSeries(function(i){if(t.contains(i,e)){var n=i.getData();NC(this.dimensions,function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(n,n.mapDimension(t)),yl(e.scale,e.model)},this)}},this)},resize:function(t,e){this._rect=Qo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},getRect:function(){return this._rect},_makeLayoutInfo:function(){var t,e=this._model,i=this._rect,n=["x","y"],o=["width","height"],a=e.get("layout"),r="horizontal"===a?0:1,s=i[o[r]],l=[0,s],u=this.dimensions.length,h=Kd(e.get("axisExpandWidth"),l),c=Kd(e.get("axisExpandCount")||0,[0,u]),d=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,f=e.get("axisExpandWindow");f?(t=Kd(f[1]-f[0],l),f[1]=f[0]+t):(t=Kd(h*(c-1),l),(f=[h*(e.get("axisExpandCenter")||RC(u/2))-t/2])[1]=f[0]+t);var p=(s-t)/(u-c);p<3&&(p=0);var g=[RC(BC(f[0]/h,1))+1,zC(BC(f[1]/h,1))-1],m=p/h*f[0];return{layout:a,pixelDimIndex:r,layoutBase:i[n[r]],layoutLength:s,axisBase:i[n[1-r]],axisLength:i[o[1-r]],axisExpandable:d,axisExpandWidth:h,axisCollapseWidth:p,axisExpandWindow:f,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:m}},_layoutAxes:function(){var t=this._rect,e=this._axesMap,i=this.dimensions,n=this._makeLayoutInfo(),o=n.layout;e.each(function(t){var e=[0,n.axisLength],i=t.inverse?1:0;t.setExtent(e[i],e[1-i])}),NC(i,function(e,i){var a=(n.axisExpandable?Jd:$d)(i,n),r={horizontal:{x:a.position,y:n.axisLength},vertical:{x:0,y:a.position}},s={horizontal:VC/2,vertical:0},l=[r[o].x+t.x,r[o].y+t.y],u=s[o],h=st();dt(h,h,u),ct(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:a.axisNameAvailableWidth,axisLabelShow:a.axisLabelShow,nameTruncateMaxWidth:a.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}},this)},getAxis:function(t){return this._axesMap.get(t)},dataToPoint:function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},eachActiveState:function(t,e,i,n){null==i&&(i=0),null==n&&(n=t.count());var o=this._axesMap,a=this.dimensions,r=[],s=[];d(a,function(e){r.push(t.mapDimension(e)),s.push(o.get(e).model)});for(var l=this.hasAxisBrushed(),u=i;uo*(1-h[0])?(l="jump",r=s-o*(1-h[2])):(r=s-o*h[1])>=0&&(r=s-o*(1-h[1]))<=0&&(r=0),(r*=e.axisExpandWidth/u)?PC(r,n,a,"all"):l="none";else{o=n[1]-n[0];(n=[EC(0,a[1]*s/o-o/2)])[1]=OC(a[1],n[0]+o),n[0]=n[1]-o}return{axisExpandWindow:n,behavior:l}}},Ca.register("parallel",{create:function(t,e){var i=[];return t.eachComponent("parallel",function(n,o){var a=new qd(n,t,e);a.name="parallel_"+o,a.resize(n,e),n.coordinateSystem=a,a.model=n,i.push(a)}),t.eachSeries(function(e){if("parallel"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"parallel",index:e.get("parallelIndex"),id:e.get("parallelId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}});var GC=hM.extend({type:"baseParallelAxis",axis:null,activeIntervals:[],getAreaSelectStyle:function(){return sb([["fill","color"],["lineWidth","borderWidth"],["stroke","borderColor"],["width","width"],["opacity","opacity"]])(this.getModel("areaSelectStyle"))},setActiveIntervals:function(t){var e=this.activeIntervals=i(t);if(e)for(var n=e.length-1;n>=0;n--)Co(e[n])},getActiveState:function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(t))return"inactive";if(1===e.length){var i=e[0];if(i[0]<=t&&t<=i[1])return"active"}else for(var n=0,o=e.length;n5)return;var n=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==n.behavior&&this._dispatchExpand({axisExpandWindow:n.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&Ff(this,"mousemove")){var e=this._model,i=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),n=i.behavior;"jump"===n&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===n?null:{axisExpandWindow:i.axisExpandWindow,animation:"jump"===n&&null})}}};us(function(t){Ud(t),Xd(t)}),KM.extend({type:"series.parallel",dependencies:["parallel"],visualColorAccessPath:"lineStyle.color",getInitialData:function(t,e){var i=this.getSource();return Hf(i,this),Xs(i,this)},getRawIndicesByActiveState:function(t){var e=this.coordinateSystem,i=this.getData(),n=[];return e.eachActiveState(i,function(e,o){t===e&&n.push(i.getRawIndex(o))}),n},defaultOption:{zlevel:0,z:2,coordinateSystem:"parallel",parallelIndex:0,label:{show:!1},inactiveOpacity:.05,activeOpacity:1,lineStyle:{width:1,opacity:.45,type:"solid"},emphasis:{label:{show:!1}},progressive:500,smooth:!1,animationEasing:"linear"}});var sL=.3,lL=(gr.extend({type:"parallel",init:function(){this._dataGroup=new sw,this.group.add(this._dataGroup),this._data,this._initialized},render:function(t,e,i,n){var o=this._dataGroup,a=t.getData(),r=this._data,s=t.coordinateSystem,l=s.dimensions,u=Yf(t);if(a.diff(r).add(function(t){qf(jf(a,o,t,l,s),a,t,u)}).update(function(e,i){var o=r.getItemGraphicEl(i),h=Xf(a,e,l,s);a.setItemGraphicEl(e,o),fo(o,{shape:{points:h}},n&&!1===n.animation?null:t,e),qf(o,a,e,u)}).remove(function(t){var e=r.getItemGraphicEl(t);o.remove(e)}).execute(),!this._initialized){this._initialized=!0;var h=Uf(s,t,function(){setTimeout(function(){o.removeClipPath()})});o.setClipPath(h)}this._data=a},incrementalPrepareRender:function(t,e,i){this._initialized=!0,this._data=null,this._dataGroup.removeAll()},incrementalRender:function(t,e,i){for(var n=e.getData(),o=e.coordinateSystem,a=o.dimensions,r=Yf(e),s=t.start;sn&&(n=e)}),d(e,function(e){var o=new ZA({type:"color",mappingMethod:"linear",dataExtent:[i,n],visual:t.get("color")}).mapValueToVisual(e.getLayout().value);e.setVisual("color",o);var a=e.getModel().get("itemStyle.color");null!=a&&e.setVisual("color",a)})}})});var cL={_baseAxisDim:null,getInitialData:function(t,e){var i,n,o=e.getComponent("xAxis",this.get("xAxisIndex")),a=e.getComponent("yAxis",this.get("yAxisIndex")),r=o.get("type"),s=a.get("type");"category"===r?(t.layout="horizontal",i=o.getOrdinalMeta(),n=!0):"category"===s?(t.layout="vertical",i=a.getOrdinalMeta(),n=!0):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],f=[o,a],p=f[u].get("type"),g=f[1-u].get("type"),m=t.data;if(m&&n){var v=[];d(m,function(t,e){var i;t.value&&y(t.value)?(i=t.value.slice(),t.value.unshift(e)):y(t)?(i=t.slice(),t.unshift(e)):i=t,v.push(i)}),t.data=v}var x=this.defaultValueDimensions;return jD(this,{coordDimensions:[{name:h,type:Ts(p),ordinalMeta:i,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:Ts(g),dimsDef:x.slice()}],dimensionsCount:x.length+1})},getBaseAxis:function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis}};h(KM.extend({type:"series.boxplot",dependencies:["xAxis","yAxis","grid"],defaultValueDimensions:[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],dimensions:null,defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:2,shadowOffsetY:2,shadowColor:"rgba(0,0,0,0.4)"}},animationEasing:"elasticOut",animationDuration:800}}),cL,!0);var dL=["itemStyle"],fL=["emphasis","itemStyle"],pL=(gr.extend({type:"boxplot",render:function(t,e,i){var n=t.getData(),o=this.group,a=this._data;this._data||o.removeAll();var r="horizontal"===t.get("layout")?1:0;n.diff(a).add(function(t){if(n.hasValue(t)){var e=_p(n.getItemLayout(t),n,t,r,!0);n.setItemGraphicEl(t,e),o.add(e)}}).update(function(t,e){var i=a.getItemGraphicEl(e);if(n.hasValue(t)){var s=n.getItemLayout(t);i?wp(s,i,n,t):i=_p(s,n,t,r),o.add(i),n.setItemGraphicEl(t,i)}else o.remove(i)}).remove(function(t){var e=a.getItemGraphicEl(t);e&&o.remove(e)}).execute(),this._data=n},remove:function(t){var e=this.group,i=this._data;this._data=null,i&&i.eachItemGraphicEl(function(t){t&&e.remove(t)})},dispose:B}),In.extend({type:"boxplotBoxPath",shape:{},buildPath:function(t,e){var i=e.points,n=0;for(t.moveTo(i[n][0],i[n][1]),n++;n<4;n++)t.lineTo(i[n][0],i[n][1]);for(t.closePath();n0?ML:IL)}function n(t,e){return e.get(t>0?bL:SL)}var o=t.getData(),a=t.pipelineContext.large;if(o.setVisual({legendSymbol:"roundRect",colorP:i(1,t),colorN:i(-1,t),borderColorP:n(1,t),borderColorN:n(-1,t)}),!e.isSeriesFiltered(t))return!a&&{progress:function(t,e){for(var o;null!=(o=t.next());){var a=e.getItemModel(o),r=e.getItemLayout(o).sign;e.setItemVisual(o,{color:i(r,a),borderColor:n(r,a)})}}}}},DL="undefined"!=typeof Float32Array?Float32Array:Array,AL={seriesType:"candlestick",plan:QM(),reset:function(t){var e=t.coordinateSystem,i=t.getData(),n=Pp(t,i),o=0,a=1,r=["x","y"],s=i.mapDimension(r[o]),l=i.mapDimension(r[a],!0),u=l[0],h=l[1],c=l[2],d=l[3];if(i.setLayout({candleWidth:n,isSimpleBox:n<=1.3}),!(null==s||l.length<4))return{progress:t.pipelineContext.large?function(t,i){for(var n,r,l=new DL(5*t.count),f=0,p=[],g=[];null!=(r=t.next());){var m=i.get(s,r),v=i.get(u,r),y=i.get(h,r),x=i.get(c,r),_=i.get(d,r);isNaN(m)||isNaN(x)||isNaN(_)?(l[f++]=NaN,f+=4):(l[f++]=kp(i,r,v,y,h),p[o]=m,p[a]=x,n=e.dataToPoint(p,null,g),l[f++]=n?n[0]:NaN,l[f++]=n?n[1]:NaN,p[a]=_,n=e.dataToPoint(p,null,g),l[f++]=n?n[1]:NaN)}i.setLayout("largePoints",l)}:function(t,i){function r(t,i){var n=[];return n[o]=i,n[a]=t,isNaN(i)||isNaN(t)?[NaN,NaN]:e.dataToPoint(n)}function l(t,e,i){var a=e.slice(),r=e.slice();a[o]=Fn(a[o]+n/2,1,!1),r[o]=Fn(r[o]-n/2,1,!0),i?t.push(a,r):t.push(r,a)}function f(t){return t[o]=Fn(t[o],1),t}for(var p;null!=(p=t.next());){var g=i.get(s,p),m=i.get(u,p),v=i.get(h,p),y=i.get(c,p),x=i.get(d,p),_=Math.min(m,v),w=Math.max(m,v),b=r(_,g),S=r(w,g),M=r(y,g),I=r(x,g),T=[];l(T,S,0),l(T,b,1),T.push(f(I),f(S),f(M),f(b)),i.setItemLayout(p,{sign:kp(i,p,m,v,h),initBaseline:m>v?S[a]:b[a],ends:T,brushRect:function(t,e,i){var s=r(t,i),l=r(e,i);return s[o]-=n/2,l[o]-=n/2,{x:s[0],y:s[1],width:a?n:l[0]-s[0],height:a?l[1]-s[1]:n}}(y,x,g)})}}}}};us(function(t){t&&y(t.series)&&d(t.series,function(t){w(t)&&"k"===t.type&&(t.type="candlestick")})}),ps(TL),fs(AL),KM.extend({type:"series.effectScatter",dependencies:["grid","polar"],getInitialData:function(t,e){return Xs(this.getSource(),this)},brushSelector:"point",defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,effectType:"ripple",progressive:0,showEffectOn:"render",rippleEffect:{period:4,scale:2.5,brushType:"fill"},symbolSize:10}});var CL=Ep.prototype;CL.stopEffectAnimation=function(){this.childAt(1).removeAll()},CL.startEffectAnimation=function(t){for(var e=t.symbolType,i=t.color,n=this.childAt(1),o=0;o<3;o++){var a=Tl(e,-1,-1,2,2,i);a.attr({style:{strokeNoScale:!0},z2:99,silent:!0,scale:[.5,.5]});var r=-o/3*t.period+t.effectOffset;a.animate("",!0).when(t.period,{scale:[t.rippleScale/2,t.rippleScale/2]}).delay(r).start(),a.animateStyle(!0).when(t.period,{opacity:0}).delay(r).start(),n.add(a)}Op(n,t)},CL.updateEffectAnimation=function(t){for(var e=this._effectCfg,i=this.childAt(1),n=["symbolType","period","rippleScale"],o=0;o "))},preventIncremental:function(){return!!this.get("effect.show")},getProgressive:function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},getProgressiveThreshold:function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},defaultOption:{coordinateSystem:"geo",zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,label:{show:!1,position:"end"},lineStyle:{opacity:.5}}}),NL=zp.prototype;NL.createLine=function(t,e,i){return new bd(t,e,i)},NL._updateEffectSymbol=function(t,e){var i=t.getItemModel(e).getModel("effect"),n=i.get("symbolSize"),o=i.get("symbol");y(n)||(n=[n,n]);var a=i.get("color")||t.getItemVisual(e,"color"),r=this.childAt(1);this._symbolType!==o&&(this.remove(r),(r=Tl(o,-.5,-.5,1,1,a)).z2=100,r.culling=!0,this.add(r)),r&&(r.setStyle("shadowColor",a),r.setStyle(i.getItemStyle(["color"])),r.attr("scale",n),r.setColor(a),r.attr("scale",n),this._symbolType=o,this._updateEffectAnimation(t,i,e))},NL._updateEffectAnimation=function(t,e,i){var n=this.childAt(1);if(n){var o=this,a=t.getItemLayout(i),r=1e3*e.get("period"),s=e.get("loop"),l=e.get("constantSpeed"),u=T(e.get("delay"),function(e){return e/t.count()*r/3}),h="function"==typeof u;if(n.ignore=!0,this.updateAnimationPoints(n,a),l>0&&(r=this.getLineLength(n)/l*1e3),r!==this._period||s!==this._loop){n.stopAnimation();var c=u;h&&(c=u(i)),n.__t>0&&(c=-r*n.__t),n.__t=0;var d=n.animate("",s).when(r,{__t:1}).delay(c).during(function(){o.updateSymbolPosition(n)});s||d.done(function(){o.remove(n)}),d.start()}this._period=r,this._loop=s}},NL.getLineLength=function(t){return S_(t.__p1,t.__cp1)+S_(t.__cp1,t.__p2)},NL.updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},NL.updateData=function(t,e,i){this.childAt(0).updateData(t,e,i),this._updateEffectSymbol(t,e)},NL.updateSymbolPosition=function(t){var e=t.__p1,i=t.__p2,n=t.__cp1,o=t.__t,a=t.position,r=Qi,s=tn;a[0]=r(e[0],n[0],i[0],o),a[1]=r(e[1],n[1],i[1],o);var l=s(e[0],n[0],i[0],o),u=s(e[1],n[1],i[1],o);t.rotation=-Math.atan2(u,l)-Math.PI/2,t.ignore=!1},NL.updateLayout=function(t,e){this.childAt(0).updateLayout(t,e);var i=t.getItemModel(e).getModel("effect");this._updateEffectAnimation(t,i,e)},u(zp,sw);var OL=Bp.prototype;OL._createPolyline=function(t,e,i){var n=t.getItemLayout(e),o=new bS({shape:{points:n}});this.add(o),this._updateCommonStl(t,e,i)},OL.updateData=function(t,e,i){var n=t.hostModel;fo(this.childAt(0),{shape:{points:t.getItemLayout(e)}},n,e),this._updateCommonStl(t,e,i)},OL._updateCommonStl=function(t,e,i){var n=this.childAt(0),o=t.getItemModel(e),a=t.getItemVisual(e,"color"),s=i&&i.lineStyle,l=i&&i.hoverLineStyle;i&&!t.hasItemOption||(s=o.getModel("lineStyle").getLineStyle(),l=o.getModel("emphasis.lineStyle").getLineStyle()),n.useStyle(r({strokeNoScale:!0,fill:"none",stroke:a},s)),n.hoverStyle=l,eo(this)},OL.updateLayout=function(t,e){this.childAt(0).setShape("points",t.getItemLayout(e))},u(Bp,sw);var EL=Vp.prototype;EL.createLine=function(t,e,i){return new Bp(t,e,i)},EL.updateAnimationPoints=function(t,e){this._points=e;for(var i=[0],n=0,o=1;o=0&&!(n[r]<=e);r--);r=Math.min(r,o-2)}else{for(var r=a;re);r++);r=Math.min(r-1,o-2)}J(t.position,i[r],i[r+1],(e-n[r])/(n[r+1]-n[r]));var s=i[r+1][0]-i[r][0],l=i[r+1][1]-i[r][1];t.rotation=-Math.atan2(l,s)-Math.PI/2,this._lastFrame=r,this._lastFramePercent=e,t.ignore=!1}},u(Vp,zp);var RL=En({shape:{polyline:!1,curveness:0,segs:[]},buildPath:function(t,e){var i=e.segs,n=e.curveness;if(e.polyline)for(r=0;r0){t.moveTo(i[r++],i[r++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*n,d=(l+h)/2-(u-s)*n;t.quadraticCurveTo(c,d,u,h)}else t.lineTo(u,h)}},findDataIndex:function(t,e){var i=this.shape,n=i.segs,o=i.curveness;if(i.polyline)for(var a=0,r=0;r0)for(var l=n[r++],u=n[r++],h=1;h0){if(fn(l,u,(l+c)/2-(u-d)*o,(u+d)/2-(c-l)*o,c,d))return a}else if(cn(l,u,c,d))return a;a++}return-1}}),zL=Gp.prototype;zL.isPersistent=function(){return!this._incremental},zL.updateData=function(t){this.group.removeAll();var e=new RL({rectHover:!0,cursor:"default"});e.setShape({segs:t.getLayout("linesPoints")}),this._setCommon(e,t),this.group.add(e),this._incremental=null},zL.incrementalPrepareUpdate=function(t){this.group.removeAll(),this._clearIncremental(),t.count()>5e5?(this._incremental||(this._incremental=new On({silent:!0})),this.group.add(this._incremental)):this._incremental=null},zL.incrementalUpdate=function(t,e){var i=new RL;i.setShape({segs:e.getLayout("linesPoints")}),this._setCommon(i,e,!!this._incremental),this._incremental?this._incremental.addDisplayable(i,!0):(i.rectHover=!0,i.cursor="default",i.__startIndex=t.start,this.group.add(i))},zL.remove=function(){this._clearIncremental(),this._incremental=null,this.group.removeAll()},zL._setCommon=function(t,e,i){var n=e.hostModel;t.setShape({polyline:n.get("polyline"),curveness:n.get("lineStyle.curveness")}),t.useStyle(n.getModel("lineStyle").getLineStyle()),t.style.strokeNoScale=!0;var o=e.getVisual("color");o&&t.setStyle("stroke",o),t.setStyle("fill"),i||(t.seriesIndex=n.seriesIndex,t.on("mousemove",function(e){t.dataIndex=null;var i=t.findDataIndex(e.offsetX,e.offsetY);i>0&&(t.dataIndex=i+t.__startIndex)}))},zL._clearIncremental=function(){var t=this._incremental;t&&t.clearDisplaybles()};var BL={seriesType:"lines",plan:QM(),reset:function(t){var e=t.coordinateSystem,i=t.get("polyline"),n=t.pipelineContext.large;return{progress:function(o,a){var r=[];if(n){var s,l=o.end-o.start;if(i){for(var u=0,h=o.start;h0){var I=a(v)?s:l;v>0&&(v=v*S+b),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(y,0,0),h},_getBrush:function(){var t=this._brushCanvas||(this._brushCanvas=m_()),e=this.pointSize+this.blurSize,i=2*e;t.width=i,t.height=i;var n=t.getContext("2d");return n.clearRect(0,0,i,i),n.shadowOffsetX=i,n.shadowBlur=this.blurSize,n.shadowColor="#000",n.beginPath(),n.arc(-e,e,this.pointSize,0,2*Math.PI,!0),n.closePath(),n.fill(),t},_getGradient:function(t,e,i){for(var n=this._gradientPixels,o=n[i]||(n[i]=new Uint8ClampedArray(1024)),a=[0,0,0,0],r=0,s=0;s<256;s++)e[i](s/255,!0,a),o[r++]=a[0],o[r++]=a[1],o[r++]=a[2],o[r++]=a[3];return o}},_s({type:"heatmap",render:function(t,e,i){var n;e.eachComponent("visualMap",function(e){e.eachTargetSeries(function(i){i===t&&(n=e)})}),this.group.removeAll(),this._incrementalDisplayable=null;var o=t.coordinateSystem;"cartesian2d"===o.type||"calendar"===o.type?this._renderOnCartesianAndCalendar(t,i,0,t.getData().count()):Up(o)&&this._renderOnGeo(o,t,n,i)},incrementalPrepareRender:function(t,e,i){this.group.removeAll()},incrementalRender:function(t,e,i,n){e.coordinateSystem&&this._renderOnCartesianAndCalendar(e,n,t.start,t.end,!0)},_renderOnCartesianAndCalendar:function(t,e,i,n,o){var r,s,l=t.coordinateSystem;if("cartesian2d"===l.type){var u=l.getAxis("x"),h=l.getAxis("y");r=u.getBandWidth(),s=h.getBandWidth()}for(var c=this.group,d=t.getData(),f=t.getModel("itemStyle").getItemStyle(["color"]),p=t.getModel("emphasis.itemStyle").getItemStyle(),g=t.getModel("label"),m=t.getModel("emphasis.label"),v=l.type,y="cartesian2d"===v?[d.mapDimension("x"),d.mapDimension("y"),d.mapDimension("value")]:[d.mapDimension("time"),d.mapDimension("value")],x=i;x=e.y&&t[1]<=e.y+e.height:i.contain(i.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},pointToData:function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},dataToPoint:function(t){var e=this.getAxis(),i=this.getRect(),n=[],o="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),n[o]=e.toGlobalCoord(e.dataToCoord(+t)),n[1-o]=0===o?i.y+i.height/2:i.x+i.width/2,n}},Ca.register("single",{create:function(t,e){var i=[];return t.eachComponent("singleAxis",function(n,o){var a=new gg(n,t,e);a.name="single_"+o,a.resize(n,e),n.coordinateSystem=a,i.push(a)}),t.eachSeries(function(e){if("singleAxis"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"singleAxis",index:e.get("singleAxisIndex"),id:e.get("singleAxisId")})[0];e.coordinateSystem=i&&i.coordinateSystem}}),i},dimensions:gg.prototype.dimensions});var XL=["axisLine","axisTickLabel","axisName"],jL=ED.extend({type:"singleAxis",axisPointerClass:"SingleAxisPointer",render:function(t,e,i,n){var o=this.group;o.removeAll();var a=mg(t),r=new LD(t,a);d(XL,r.add,r),o.add(r.getGroup()),t.get("splitLine.show")&&this._splitLine(t),jL.superCall(this,"render",t,e,i,n)},_splitLine:function(t){var e=t.axis;if(!e.scale.isBlank()){var i=t.getModel("splitLine"),n=i.getModel("lineStyle"),o=n.get("width"),a=n.get("color");a=a instanceof Array?a:[a];for(var r=t.coordinateSystem.getRect(),s=e.isHorizontal(),l=[],u=0,h=e.getTicksCoords({tickModel:i}),c=[],d=[],f=0;f=0)&&i({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})})},remove:function(t,e){Ng(e.getZr(),"axisPointer"),ik.superApply(this._model,"remove",arguments)},dispose:function(t,e){Ng("axisPointer",e),ik.superApply(this._model,"dispose",arguments)}}),nk=Ni(),ok=i,ak=m;(Og.prototype={_group:null,_lastGraphicKey:null,_handle:null,_dragging:!1,_lastValue:null,_lastStatus:null,_payloadInfo:null,animationThreshold:15,render:function(t,e,i,n){var o=e.get("value"),a=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=i,n||this._lastValue!==o||this._lastStatus!==a){this._lastValue=o,this._lastStatus=a;var r=this._group,s=this._handle;if(!a||"hide"===a)return r&&r.hide(),void(s&&s.hide());r&&r.show(),s&&s.show();var l={};this.makeElOption(l,o,t,e,i);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(i),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(r){var c=v(Eg,e,h);this.updatePointerEl(r,l,c,e),this.updateLabelEl(r,l,c,e)}else r=this._group=new sw,this.createPointerEl(r,l,t,e),this.createLabelEl(r,l,t,e),i.getZr().add(r);Vg(r,e,!0),this._renderHandle(o)}},remove:function(t){this.clear(t)},dispose:function(t){this.clear(t)},determineAnimation:function(t,e){var i=e.get("animation"),n=t.axis,o="category"===n.type,a=e.get("snap");if(!a&&!o)return!1;if("auto"===i||null==i){var r=this.animationThreshold;if(o&&n.getBandWidth()>r)return!0;if(a){var s=qu(t).seriesDataCount,l=n.getExtent();return Math.abs(l[0]-l[1])/s>r}return!1}return!0===i},makeElOption:function(t,e,i,n,o){},createPointerEl:function(t,e,i,n){var o=e.pointer;if(o){var a=nk(t).pointerEl=new BS[o.type](ok(e.pointer));t.add(a)}},createLabelEl:function(t,e,i,n){if(e.label){var o=nk(t).labelEl=new SS(ok(e.label));t.add(o),zg(o,n)}},updatePointerEl:function(t,e,i){var n=nk(t).pointerEl;n&&(n.setStyle(e.pointer.style),i(n,{shape:e.pointer.shape}))},updateLabelEl:function(t,e,i,n){var o=nk(t).labelEl;o&&(o.setStyle(e.label.style),i(o,{shape:e.label.shape,position:e.label.position}),zg(o,n))},_renderHandle:function(t){if(!this._dragging&&this.updateHandleTransform){var e=this._axisPointerModel,i=this._api.getZr(),n=this._handle,o=e.getModel("handle"),a=e.get("status");if(!o.get("show")||!a||"hide"===a)return n&&i.remove(n),void(this._handle=null);var r;this._handle||(r=!0,n=this._handle=_o(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){zw(t.event)},onmousedown:ak(this._onHandleDragMove,this,0,0),drift:ak(this._onHandleDragMove,this),ondragend:ak(this._onHandleDragEnd,this)}),i.add(n)),Vg(n,e,!1);var s=["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"];n.setStyle(o.getItemStyle(null,s));var l=o.get("size");y(l)||(l=[l,l]),n.attr("scale",[l[0]/2,l[1]/2]),wr(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,r)}},_moveHandleToValue:function(t,e){Eg(this._axisPointerModel,!e&&this._moveAnimation,this._handle,Bg(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},_onHandleDragMove:function(t,e){var i=this._handle;if(i){this._dragging=!0;var n=this.updateHandleTransform(Bg(i),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=n,i.stopAnimation(),i.attr(Bg(n)),nk(i).lastProp=null,this._doDispatchAxisPointer()}},_doDispatchAxisPointer:function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},_onHandleDragEnd:function(t){if(this._dragging=!1,this._handle){var e=this._axisPointerModel.get("value");this._moveHandleToValue(e),this._api.dispatchAction({type:"hideTip"})}},getHandleTransform:null,updateHandleTransform:null,clear:function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),i=this._group,n=this._handle;e&&i&&(this._lastGraphicKey=null,i&&e.remove(i),n&&e.remove(n),this._group=null,this._handle=null,this._payloadInfo=null)},doClear:function(){},buildLabel:function(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}}).constructor=Og,Gi(Og);var rk=Og.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.grid,s=n.get("type"),l=qg(r,a).getOtherAxis(a).getGlobalExtent(),u=a.toGlobalCoord(a.dataToCoord(e,!0));if(s&&"none"!==s){var h=Gg(n),c=sk[s](a,u,l,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Ug(e,t,eh(r.model,i),i,n,o)},getHandleTransform:function(t,e,i){var n=eh(e.axis.grid.model,e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Zg(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.grid,r=o.getGlobalExtent(!0),s=qg(a,o).getOtherAxis(o).getGlobalExtent(),l="x"===o.dim?0:1,u=t.position;u[l]+=e[l],u[l]=Math.min(r[1],u[l]),u[l]=Math.max(r[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];var d=[{verticalAlign:"middle"},{align:"center"}];return{position:u,rotation:t.rotation,cursorPoint:c,tooltipOption:d[l]}}}),sk={line:function(t,e,i,n){var o=Xg([e,i[0]],[e,i[1]],Kg(t));return Gn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=Math.max(1,t.getBandWidth()),a=i[1]-i[0];return{type:"Rect",shape:jg([e-o/2,i[0]],[o,a],Kg(t))}}};ED.registerAxisPointerClass("CartesianAxisPointer",rk),us(function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!y(e)&&(t.axisPointer.link=[e])}}),hs(LI.PROCESSOR.STATISTIC,function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=Fu(t,e)}),cs({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},function(t,e,i){var n=t.currTrigger,o=[t.x,t.y],a=t,r=t.dispatchAction||m(i.dispatchAction,i),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){Tg(o)&&(o=KL({seriesIndex:a.seriesIndex,dataIndex:a.dataIndex},e).point);var l=Tg(o),u=a.axesInfo,h=s.axesInfo,c="leave"===n||Tg(o),d={},f={},p={list:[],map:{}},g={showPointer:JL(xg,f),showTooltip:JL(_g,p)};$L(s.coordSysMap,function(t,e){var i=l||t.containPoint(o);$L(s.coordSysAxesInfo[e],function(t,e){var n=t.axis,a=Mg(u,t);if(!c&&i&&(!u||a)){var r=a&&a.value;null!=r||l||(r=n.pointToData(o)),null!=r&&vg(t,r,g,!1,d)}})});var v={};return $L(h,function(t,e){var i=t.linkGroup;i&&!f[e]&&$L(i.axesInfo,function(e,n){var o=f[n];if(e!==t&&o){var a=o.value;i.mapper&&(a=t.axis.scale.parse(i.mapper(a,Ig(e),Ig(t)))),v[t.key]=a}})}),$L(v,function(t,e){vg(h[e],t,g,!0,d)}),wg(f,h,d),bg(p,o,t,r),Sg(h,0,i),d}});var lk=["x","y"],uk=["width","height"],hk=Og.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.coordinateSystem,s=Jg(r,1-$g(a)),l=r.dataToPoint(e)[0],u=n.get("type");if(u&&"none"!==u){var h=Gg(n),c=ck[u](a,l,s,h);c.style=h,t.graphicKey=c.type,t.pointer=c}Ug(e,t,mg(i),i,n,o)},getHandleTransform:function(t,e,i){var n=mg(e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Zg(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.coordinateSystem,r=$g(o),s=Jg(a,r),l=t.position;l[r]+=e[r],l[r]=Math.min(s[1],l[r]),l[r]=Math.max(s[0],l[r]);var u=Jg(a,1-r),h=(u[1]+u[0])/2,c=[h,h];return c[r]=l[r],{position:l,rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}}}),ck={line:function(t,e,i,n){var o=Xg([e,i[0]],[e,i[1]],$g(t));return Gn({shape:o,style:n}),{type:"Line",shape:o}},shadow:function(t,e,i,n){var o=t.getBandWidth(),a=i[1]-i[0];return{type:"Rect",shape:jg([e-o/2,i[0]],[o,a],$g(t))}}};ED.registerAxisPointerClass("SingleAxisPointer",hk),ys({type:"single"});var dk=KM.extend({type:"series.themeRiver",dependencies:["singleAxis"],nameMap:null,init:function(t){dk.superApply(this,"init",arguments),this.legendDataProvider=function(){return this.getRawData()}},fixData:function(t){for(var e=t.length,i=f(Jf().key(function(t){return t[2]}).entries(t),function(t){return{name:t.key,dataList:t.values}}),n=i.length,o=-1,a=-1,r=0;ro&&(o=s,a=r)}for(var l=0;lMath.PI/2?"right":"left"):x&&"center"!==x?"left"===x?(f=u.r0+y,p>Math.PI/2&&(x="right")):"right"===x&&(f=u.r-y,p>Math.PI/2&&(x="left")):(f=(u.r+u.r0)/2,x="center"),d.attr("style",{text:l,textAlign:x,textVerticalAlign:n("verticalAlign")||"middle",opacity:n("opacity")});var _=f*g+u.cx,w=f*m+u.cy;d.attr("position",[_,w]);var b=n("rotate"),S=0;"radial"===b?(S=-p)<-Math.PI/2&&(S+=Math.PI):"tangential"===b?(S=Math.PI/2-p)>Math.PI/2?S-=Math.PI:S<-Math.PI/2&&(S+=Math.PI):"number"==typeof b&&(S=b*Math.PI/180),d.attr("rotation",S)},mk._initEvents=function(t,e,i,n){t.off("mouseover").off("mouseout").off("emphasis").off("normal");var o=this,a=function(){o.onEmphasis(n)},r=function(){o.onNormal()};i.isAnimationEnabled()&&t.on("mouseover",a).on("mouseout",r).on("emphasis",a).on("normal",r).on("downplay",function(){o.onDownplay()}).on("highlight",function(){o.onHighlight()})},u(nm,sw);gr.extend({type:"sunburst",init:function(){},render:function(t,e,i,n){function o(i,n){if(c||!i||i.getValue()||(i=null),i!==l&&n!==l)if(n&&n.piece)i?(n.piece.updateData(!1,i,"normal",t,e),s.setItemGraphicEl(i.dataIndex,n.piece)):a(n);else if(i){var o=new nm(i,t,e);h.add(o),s.setItemGraphicEl(i.dataIndex,o)}}function a(t){t&&t.piece&&(h.remove(t.piece),t.piece=null)}var r=this;this.seriesModel=t,this.api=i,this.ecModel=e;var s=t.getData(),l=s.tree.root,u=t.getViewRoot(),h=this.group,c=t.get("renderLabelForZeroData"),d=[];u.eachNode(function(t){d.push(t)});var f=this._oldChildren||[];if(function(t,e){function i(t){return t.getId()}function n(i,n){o(null==i?null:t[i],null==n?null:e[n])}0===t.length&&0===e.length||new Ss(e,t,i,i).add(n).update(n).remove(v(n,null)).execute()}(d,f),function(i,n){if(n.depth>0){r.virtualPiece?r.virtualPiece.updateData(!1,i,"normal",t,e):(r.virtualPiece=new nm(i,t,e),h.add(r.virtualPiece)),n.piece._onclickEvent&&n.piece.off("click",n.piece._onclickEvent);var o=function(t){r._rootToNode(n.parentNode)};n.piece._onclickEvent=o,r.virtualPiece.on("click",o)}else r.virtualPiece&&(h.remove(r.virtualPiece),r.virtualPiece=null)}(l,u),n&&n.highlight&&n.highlight.piece){var p=t.getShallow("highlightPolicy");n.highlight.piece.onEmphasis(p)}else if(n&&n.unhighlight){var g=this.virtualPiece;!g&&l.children.length&&(g=l.children[0].piece),g&&g.onNormal()}this._initEvents(),this._oldChildren=d},dispose:function(){},_initEvents:function(){var t=this,e=function(e){var i=!1;t.seriesModel.getViewRoot().eachNode(function(n){if(!i&&n.piece&&n.piece.childAt(0)===e.target){var o=n.getModel().get("nodeClick");if("rootToNode"===o)t._rootToNode(n);else if("link"===o){var a=n.getModel(),r=a.get("link");if(r){var s=a.get("target",!0)||"_blank";window.open(r,s)}}i=!0}})};this.group._onclickEvent&&this.group.off("click",this.group._onclickEvent),this.group.on("click",e),this.group._onclickEvent=e},_rootToNode:function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:"sunburstRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},containPoint:function(t,e){var i=e.getData().getItemLayout(0);if(i){var n=t[0]-i.cx,o=t[1]-i.cy,a=Math.sqrt(n*n+o*o);return a<=i.r&&a>=i.r0}}});var vk="sunburstRootToNode";cs({type:vk,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=Ic(t,[vk],e);if(n){var o=e.getViewRoot();o&&(t.direction=Dc(o,n.node)?"rollUp":"drillDown"),e.resetViewRoot(n.node)}})});var yk="sunburstHighlight";cs({type:yk,update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){var n=Ic(t,[yk],e);n&&(t.highlight=n.node)})});cs({type:"sunburstUnhighlight",update:"updateView"},function(t,e){e.eachComponent({mainType:"series",subType:"sunburst",query:t},function(e,i){t.unhighlight=!0})});var xk=Math.PI/180;ps(v(JD,"sunburst")),fs(v(function(t,e,i,n){e.eachSeriesByType(t,function(t){var e=t.get("center"),n=t.get("radius");y(n)||(n=[0,n]),y(e)||(e=[e,e]);var o=i.getWidth(),a=i.getHeight(),r=Math.min(o,a),s=Do(e[0],o),l=Do(e[1],a),u=Do(n[0],r/2),h=Do(n[1],r/2),c=-t.get("startAngle")*xk,f=t.get("minAngle")*xk,p=t.getData().tree.root,g=t.getViewRoot(),m=g.depth,v=t.get("sort");null!=v&&sm(g,v);var x=0;d(g.children,function(t){!isNaN(t.getValue())&&x++});var _=g.getValue(),w=Math.PI/(_||x)*2,b=g.depth>0,S=g.height-(b?-1:1),M=(h-u)/(S||1),I=t.get("clockwise"),T=t.get("stillShowZeroSum"),D=I?1:-1,A=function(t,e){if(t){var i=e;if(t!==p){var n=t.getValue(),o=0===_&&T?w:n*w;on[1]&&n.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:n[1],r0:n[0]},api:{coord:m(function(n){var o=e.dataToRadius(n[0]),a=i.dataToAngle(n[1]),r=t.coordToPoint([o,a]);return r.push(o,a*Math.PI/180),r}),size:m(dm,t)}}},calendar:function(t){var e=t.getRect(),i=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:i.start,end:i.end,weeks:i.weeks,dayCount:i.allDay}},api:{coord:function(e,i){return t.dataToPoint(e,i)}}}}};xs({type:"series.custom",dependencies:["grid","polar","geo","singleAxis","calendar"],defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0},getInitialData:function(t,e){return Xs(this.getSource(),this)}}),_s({type:"custom",_data:null,render:function(t,e,i){var n=this._data,o=t.getData(),a=this.group,r=mm(t,o,e,i);this.group.removeAll(),o.diff(n).add(function(e){ym(null,e,r(e),t,a,o)}).update(function(e,i){ym(n.getItemGraphicEl(i),e,r(e),t,a,o)}).remove(function(t){var e=n.getItemGraphicEl(t);e&&a.remove(e)}).execute(),this._data=o},incrementalPrepareRender:function(t,e,i){this.group.removeAll(),this._data=null},incrementalRender:function(t,e,i,n){for(var o=e.getData(),a=mm(e,o,i,n),r=t.start;r=0;l--)null==o[l]?o.splice(l,1):delete o[l].$action},_flatten:function(t,e,i){d(t,function(t){if(t){i&&(t.parentOption=i),e.push(t);var n=t.children;"group"===t.type&&n&&this._flatten(n,e,t),delete t.children}},this)},useElOptionsToUpdate:function(){var t=this._elOptionsToUpdate;return this._elOptionsToUpdate=null,t}});ys({type:"graphic",init:function(t,e){this._elMap=R(),this._lastGraphicModel},render:function(t,e,i){t!==this._lastGraphicModel&&this._clear(),this._lastGraphicModel=t,this._updateElements(t,i),this._relocate(t,i)},_updateElements:function(t,e){var i=t.useElOptionsToUpdate();if(i){var n=this._elMap,o=this.group;d(i,function(t){var e=t.$action,i=t.id,a=n.get(i),r=t.parentId,s=null!=r?n.get(r):o;if("text"===t.type){var l=t.style;t.hv&&t.hv[1]&&(l.textVerticalAlign=l.textBaseline=null),!l.hasOwnProperty("textFill")&&l.fill&&(l.textFill=l.fill),!l.hasOwnProperty("textStroke")&&l.stroke&&(l.textStroke=l.stroke)}var u=Tm(t);e&&"merge"!==e?"replace"===e?(Im(a,n),Mm(i,s,u,n)):"remove"===e&&Im(a,n):a?a.attr(u):Mm(i,s,u,n);var h=n.get(i);h&&(h.__ecGraphicWidth=t.width,h.__ecGraphicHeight=t.height)})}},_relocate:function(t,e){for(var i=t.option.elements,n=this.group,o=this._elMap,a=i.length-1;a>=0;a--){var r=i[a],s=o.get(r.id);if(s){var l=s.parent;ta(s,r,l===n?{width:e.getWidth(),height:e.getHeight()}:{width:l.__ecGraphicWidth||0,height:l.__ecGraphicHeight||0},null,{hv:r.hv,boundingMode:r.bounding})}}},_clear:function(){var t=this._elMap;t.each(function(e){Im(e,t)}),this._elMap=R()},dispose:function(){this._clear()}});var Dk=vs({type:"legend.plain",dependencies:["series"],layoutMode:{type:"box",ignoreSize:!0},init:function(t,e,i){this.mergeDefaultAndTheme(t,i),t.selected=t.selected||{}},mergeOption:function(t){Dk.superCall(this,"mergeOption",t)},optionUpdated:function(){this._updateData(this.ecModel);var t=this._data;if(t[0]&&"single"===this.get("selectedMode")){for(var e=!1,i=0;i=0},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",textStyle:{color:"#333"},selectedMode:!0,tooltip:{show:!1}}});cs("legendToggleSelect","legendselectchanged",v(km,"toggleSelected")),cs("legendSelect","legendselected",v(km,"select")),cs("legendUnSelect","legendunselected",v(km,"unSelect"));var Ak=v,Ck=d,Lk=sw,kk=ys({type:"legend.plain",newlineDisabled:!1,init:function(){this.group.add(this._contentGroup=new Lk),this._backgroundEl},getContentGroup:function(){return this._contentGroup},render:function(t,e,i){if(this.resetInner(),t.get("show",!0)){var n=t.get("align");n&&"auto"!==n||(n="right"===t.get("left")&&"vertical"===t.get("orient")?"right":"left"),this.renderInner(n,t,e,i);var o=t.getBoxLayoutParams(),a={width:i.getWidth(),height:i.getHeight()},s=t.get("padding"),l=Qo(o,a,s),u=this.layoutInner(t,n,l),h=Qo(r({width:u.width,height:u.height},o),a,s);this.group.attr("position",[h.x-u.x,h.y-u.y]),this.group.add(this._backgroundEl=Nm(u,t))}},resetInner:function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl)},renderInner:function(t,e,i,n){var o=this.getContentGroup(),a=R(),r=e.get("selectedMode"),s=[];i.eachRawSeries(function(t){!t.get("legendHoverLink")&&s.push(t.id)}),Ck(e.getData(),function(l,u){var h=l.get("name");if(this.newlineDisabled||""!==h&&"\n"!==h){var c=i.getSeriesByName(h)[0];if(!a.get(h))if(c){var d=c.getData(),f=d.getVisual("color");"function"==typeof f&&(f=f(c.getDataParams(0)));var p=d.getVisual("legendSymbol")||"roundRect",g=d.getVisual("symbol");this._createItem(h,u,l,e,p,g,t,f,r).on("click",Ak(Om,h,n)).on("mouseover",Ak(Em,c,null,n,s)).on("mouseout",Ak(Rm,c,null,n,s)),a.set(h,!0)}else i.eachRawSeries(function(i){if(!a.get(h)&&i.legendDataProvider){var o=i.legendDataProvider(),c=o.indexOfName(h);if(c<0)return;var d=o.getItemVisual(c,"color");this._createItem(h,u,l,e,"roundRect",null,t,d,r).on("click",Ak(Om,h,n)).on("mouseover",Ak(Em,i,h,n,s)).on("mouseout",Ak(Rm,i,h,n,s)),a.set(h,!0)}},this)}else o.add(new Lk({newline:!0}))},this)},_createItem:function(t,e,i,n,o,r,s,l,u){var h=n.get("itemWidth"),c=n.get("itemHeight"),d=n.get("inactiveColor"),f=n.get("symbolKeepAspect"),p=n.isSelected(t),g=new Lk,m=i.getModel("textStyle"),v=i.get("icon"),y=i.getModel("tooltip"),x=y.parentModel;if(o=v||o,g.add(Tl(o,0,0,h,c,p?l:d,null==f||f)),!v&&r&&(r!==o||"none"==r)){var _=.8*c;"none"===r&&(r="circle"),g.add(Tl(r,(h-_)/2,(c-_)/2,_,_,p?l:d,null==f||f))}var w="left"===s?h+5:-5,b=s,S=n.get("formatter"),M=t;"string"==typeof S&&S?M=S.replace("{name}",null!=t?t:""):"function"==typeof S&&(M=S(t)),g.add(new fS({style:no({},m,{text:M,x:w,y:c/2,textFill:p?m.getTextColor():d,textAlign:b,textVerticalAlign:"middle"})}));var I=new SS({shape:g.getBoundingRect(),invisible:!0,tooltip:y.get("show")?a({content:t,formatter:x.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:n.componentIndex,name:t,$vars:["name"]}},y.option):null});return g.add(I),g.eachChild(function(t){t.silent=!0}),I.silent=!u,this.getContentGroup().add(g),eo(g),g.__legendDataIndex=e,g},layoutInner:function(t,e,i){var n=this.getContentGroup();sM(t.get("orient"),n,t.get("itemGap"),i.width,i.height);var o=n.getBoundingRect();return n.attr("position",[-o.x,-o.y]),this.group.getBoundingRect()}});hs(function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var i=0;ii[s],f=[-h.x,-h.y];f[r]=n.position[r];var p=[0,0],g=[-c.x,-c.y],m=D(t.get("pageButtonGap",!0),t.get("itemGap",!0));d&&("end"===t.get("pageButtonPosition",!0)?g[r]+=i[s]-c[s]:p[r]+=c[s]+m),g[1-r]+=h[l]/2-c[l]/2,n.attr("position",f),o.attr("position",p),a.attr("position",g);var v=this.group.getBoundingRect();if((v={x:0,y:0})[s]=d?i[s]:h[s],v[l]=Math.max(h[l],c[l]),v[u]=Math.min(0,c[u]+g[1-r]),o.__rectSize=i[s],d){var y={x:0,y:0};y[s]=Math.max(i[s]-c[s]-m,0),y[l]=v[l],o.setClipPath(new SS({shape:y})),o.__rectSize=y[s]}else a.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var x=this._getPageInfo(t);return null!=x.pageIndex&&fo(n,{position:x.contentPosition},!!d&&t),this._updatePageInfoView(t,x),v},_pageGo:function(t,e,i){var n=this._getPageInfo(e)[t];null!=n&&i.dispatchAction({type:"legendScroll",scrollDataIndex:n,legendId:e.id})},_updatePageInfoView:function(t,e){var i=this._controllerGroup;d(["pagePrev","pageNext"],function(n){var o=null!=e[n+"DataIndex"],a=i.childOfName(n);a&&(a.setStyle("fill",o?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),a.cursor=o?"pointer":"default")});var n=i.childOfName("pageText"),o=t.get("pageFormatter"),a=e.pageIndex,r=null!=a?a+1:0,s=e.pageCount;n&&o&&n.setStyle("text",_(o)?o.replace("{current}",r).replace("{total}",s):o({current:r,total:s}))},_getPageInfo:function(t){function e(t){var e=t.getBoundingRect().clone();return e[f]+=t.position[h],e}var i,n,o,a,r=t.get("scrollDataIndex",!0),s=this.getContentGroup(),l=s.getBoundingRect(),u=this._containerGroup.__rectSize,h=t.getOrient().index,c=Ok[h],d=Ok[1-h],f=Ek[h],p=s.position.slice();this._showController?s.eachChild(function(t){t.__legendDataIndex===r&&(a=t)}):a=s.childAt(0);var g=u?Math.ceil(l[c]/u):0;if(a){var m=a.getBoundingRect(),v=a.position[h]+m[f];p[h]=-v-l[f],i=Math.floor(g*(v+m[f]+u/2)/l[c]),i=l[c]&&g?Math.max(0,Math.min(g-1,i)):-1;var y={x:0,y:0};y[c]=u,y[d]=l[d],y[f]=-p[h]-l[f];var x,_=s.children();if(s.eachChild(function(t,i){var n=e(t);n.intersect(y)&&(null==x&&(x=i),o=t.__legendDataIndex),i===_.length-1&&n[f]+n[c]<=y[f]+y[c]&&(o=null)}),null!=x){var w=e(_[x]);if(y[f]=w[f]+w[c]-y[c],x<=0&&w[f]>=y[f])n=null;else{for(;x>0&&e(_[x-1]).intersect(y);)x--;n=_[x].__legendDataIndex}}}return{contentPosition:p,pageIndex:i,pageCount:g,pagePrevDataIndex:n,pageNextDataIndex:o}}});cs("legendScroll","legendscroll",function(t,e){var i=t.scrollDataIndex;null!=i&&e.eachComponent({mainType:"legend",subType:"scroll",query:t},function(t){t.setScrollDataIndex(i)})}),vs({type:"tooltip",dependencies:["axisPointer"],defaultOption:{zlevel:0,z:8,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove|click",alwaysShowContent:!1,displayMode:"single",confine:!1,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"rgba(50,50,50,0.7)",borderColor:"#333",borderRadius:4,borderWidth:0,padding:5,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:"#999",width:1,type:"dashed",textStyle:{}}},textStyle:{color:"#fff",fontSize:14}}});var zk=d,Bk=Ho,Vk=["","-webkit-","-moz-","-o-"];Wm.prototype={constructor:Wm,_enterable:!0,update:function(){var t=this._container,e=t.currentStyle||document.defaultView.getComputedStyle(t),i=t.style;"absolute"!==i.position&&"absolute"!==e.position&&(i.position="relative")},show:function(t){clearTimeout(this._hideTimeout);var e=this.el;e.style.cssText="position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;"+Gm(t)+";left:"+this._x+"px;top:"+this._y+"px;"+(t.get("extraCssText")||""),e.style.display=e.innerHTML?"block":"none",this._show=!0},setContent:function(t){this.el.innerHTML=null==t?"":t},setEnterable:function(t){this._enterable=t},getSize:function(){var t=this.el;return[t.clientWidth,t.clientHeight]},moveTo:function(t,e){var i,n=this._zr;n&&n.painter&&(i=n.painter.getViewportRootOffset())&&(t+=i.offsetLeft,e+=i.offsetTop);var o=this.el.style;o.left=t+"px",o.top=e+"px",this._x=t,this._y=e},hide:function(){this.el.style.display="none",this._show=!1},hideLater:function(t){!this._show||this._inContent&&this._enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(m(this.hide,this),t)):this.hide())},isShow:function(){return this._show}};var Gk=m,Wk=d,Fk=Do,Hk=new SS({shape:{x:-1,y:-1,width:2,height:2}});ys({type:"tooltip",init:function(t,e){if(!a_.node){var i=new Wm(e.getDom(),e);this._tooltipContent=i}},render:function(t,e,i){if(!a_.node&&!a_.wxa){this.group.removeAll(),this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastDataByCoordSys=null,this._alwaysShowContent=t.get("alwaysShowContent");var n=this._tooltipContent;n.update(),n.setEnterable(t.get("enterable")),this._initGlobalListener(),this._keepShow()}},_initGlobalListener:function(){var t=this._tooltipModel.get("triggerOn");Dg("itemTooltip",this._api,Gk(function(e,i,n){"none"!==t&&(t.indexOf(e)>=0?this._tryShow(i,n):"leave"===e&&this._hide(n))},this))},_keepShow:function(){var t=this._tooltipModel,e=this._ecModel,i=this._api;if(null!=this._lastX&&null!=this._lastY&&"none"!==t.get("triggerOn")){var n=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){n.manuallyShowTip(t,e,i,{x:n._lastX,y:n._lastY})})}},manuallyShowTip:function(t,e,i,n){if(n.from!==this.uid&&!a_.node){var o=Hm(n,i);this._ticket="";var a=n.dataByCoordSys;if(n.tooltip&&null!=n.x&&null!=n.y){var r=Hk;r.position=[n.x,n.y],r.update(),r.tooltip=n.tooltip,this._tryShow({offsetX:n.x,offsetY:n.y,target:r},o)}else if(a)this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,event:{},dataByCoordSys:n.dataByCoordSys,tooltipOption:n.tooltipOption},o);else if(null!=n.seriesIndex){if(this._manuallyAxisShowTip(t,e,i,n))return;var s=KL(n,e),l=s.point[0],u=s.point[1];null!=l&&null!=u&&this._tryShow({offsetX:l,offsetY:u,position:n.position,target:s.el,event:{}},o)}else null!=n.x&&null!=n.y&&(i.dispatchAction({type:"updateAxisPointer",x:n.x,y:n.y}),this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,target:i.getZr().findHover(n.x,n.y).target,event:{}},o))}},manuallyHideTip:function(t,e,i,n){var o=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&o.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=null,n.from!==this.uid&&this._hide(Hm(n,i))},_manuallyAxisShowTip:function(t,e,i,n){var o=n.seriesIndex,a=n.dataIndex,r=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=o&&null!=a&&null!=r){var s=e.getSeriesByIndex(o);if(s&&"axis"===(t=Fm([s.getData().getItemModel(a),s,(s.coordinateSystem||{}).model,t])).get("trigger"))return i.dispatchAction({type:"updateAxisPointer",seriesIndex:o,dataIndex:a,position:n.position}),!0}},_tryShow:function(t,e){var i=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var n=t.dataByCoordSys;n&&n.length?this._showAxisTooltip(n,t):i&&null!=i.dataIndex?(this._lastDataByCoordSys=null,this._showSeriesItemTooltip(t,i,e)):i&&i.tooltip?(this._lastDataByCoordSys=null,this._showComponentItemTooltip(t,i,e)):(this._lastDataByCoordSys=null,this._hide(e))}},_showOrMove:function(t,e){var i=t.get("showDelay");e=m(e,this),clearTimeout(this._showTimout),i>0?this._showTimout=setTimeout(e,i):e()},_showAxisTooltip:function(t,e){var i=this._ecModel,n=this._tooltipModel,o=[e.offsetX,e.offsetY],a=[],r=[],s=Fm([e.tooltipOption,n]);Wk(t,function(t){Wk(t.dataByAxis,function(t){var e=i.getComponent(t.axisDim+"Axis",t.axisIndex),n=t.value,o=[];if(e&&null!=n){var s=Hg(n,e.axis,i,t.seriesDataIndices,t.valueLabelOpt);d(t.seriesDataIndices,function(a){var l=i.getSeriesByIndex(a.seriesIndex),u=a.dataIndexInside,h=l&&l.getDataParams(u);h.axisDim=t.axisDim,h.axisIndex=t.axisIndex,h.axisType=t.axisType,h.axisId=t.axisId,h.axisValue=bl(e.axis,n),h.axisValueLabel=s,h&&(r.push(h),o.push(l.formatTooltip(u,!0)))});var l=s;a.push((l?Zo(l)+"
":"")+o.join("
"))}})},this),a.reverse(),a=a.join("

");var l=e.position;this._showOrMove(s,function(){this._updateContentNotChangedOnAxis(t)?this._updatePosition(s,l,o[0],o[1],this._tooltipContent,r):this._showTooltipContent(s,a,r,Math.random(),o[0],o[1],l)})},_showSeriesItemTooltip:function(t,e,i){var n=this._ecModel,o=e.seriesIndex,a=n.getSeriesByIndex(o),r=e.dataModel||a,s=e.dataIndex,l=e.dataType,u=r.getData(),h=Fm([u.getItemModel(s),r,a&&(a.coordinateSystem||{}).model,this._tooltipModel]),c=h.get("trigger");if(null==c||"item"===c){var d=r.getDataParams(s,l),f=r.formatTooltip(s,!1,l),p="item_"+r.name+"_"+s;this._showOrMove(h,function(){this._showTooltipContent(h,f,d,p,t.offsetX,t.offsetY,t.position,t.target)}),i({type:"showTip",dataIndexInside:s,dataIndex:u.getRawIndex(s),seriesIndex:o,from:this.uid})}},_showComponentItemTooltip:function(t,e,i){var n=e.tooltip;if("string"==typeof n){var o=n;n={content:o,formatter:o}}var a=new wo(n,this._tooltipModel,this._ecModel),r=a.get("content"),s=Math.random();this._showOrMove(a,function(){this._showTooltipContent(a,r,a.get("formatterParams")||{},s,t.offsetX,t.offsetY,t.position,e)}),i({type:"showTip",from:this.uid})},_showTooltipContent:function(t,e,i,n,o,a,r,s){if(this._ticket="",t.get("showContent")&&t.get("show")){var l=this._tooltipContent,u=t.get("formatter");r=r||t.get("position");var h=e;if(u&&"string"==typeof u)h=Uo(u,i,!0);else if("function"==typeof u){var c=Gk(function(e,n){e===this._ticket&&(l.setContent(n),this._updatePosition(t,r,o,a,l,i,s))},this);this._ticket=n,h=u(i,n,c)}l.setContent(h),l.show(t),this._updatePosition(t,r,o,a,l,i,s)}},_updatePosition:function(t,e,i,n,o,a,r){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=o.getSize(),h=t.get("align"),c=t.get("verticalAlign"),d=r&&r.getBoundingRect().clone();if(r&&d.applyTransform(r.transform),"function"==typeof e&&(e=e([i,n],a,o.el,d,{viewSize:[s,l],contentSize:u.slice()})),y(e))i=Fk(e[0],s),n=Fk(e[1],l);else if(w(e)){e.width=u[0],e.height=u[1];var f=Qo(e,{width:s,height:l});i=f.x,n=f.y,h=null,c=null}else"string"==typeof e&&r?(i=(p=jm(e,d,u))[0],n=p[1]):(i=(p=Zm(i,n,o.el,s,l,h?null:20,c?null:20))[0],n=p[1]);if(h&&(i-=Ym(h)?u[0]/2:"right"===h?u[0]:0),c&&(n-=Ym(c)?u[1]/2:"bottom"===c?u[1]:0),t.get("confine")){var p=Um(i,n,o.el,s,l);i=p[0],n=p[1]}o.moveTo(i,n)},_updateContentNotChangedOnAxis:function(t){var e=this._lastDataByCoordSys,i=!!e&&e.length===t.length;return i&&Wk(e,function(e,n){var o=e.dataByAxis||{},a=(t[n]||{}).dataByAxis||[];(i&=o.length===a.length)&&Wk(o,function(t,e){var n=a[e]||{},o=t.seriesDataIndices||[],r=n.seriesDataIndices||[];(i&=t.value===n.value&&t.axisType===n.axisType&&t.axisId===n.axisId&&o.length===r.length)&&Wk(o,function(t,e){var n=r[e];i&=t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})})}),this._lastDataByCoordSys=t,!!i},_hide:function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},dispose:function(t,e){a_.node||a_.wxa||(this._tooltipContent.hide(),Ng("itemTooltip",e))}}),cs({type:"showTip",event:"showTip",update:"tooltip:manuallyShowTip"},function(){}),cs({type:"hideTip",event:"hideTip",update:"tooltip:manuallyHideTip"},function(){}),Jm.prototype={constructor:Jm,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToRadius:qT.prototype.dataToCoord,radiusToData:qT.prototype.coordToData},u(Jm,qT),Qm.prototype={constructor:Qm,pointToData:function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},dataToAngle:qT.prototype.dataToCoord,angleToData:qT.prototype.coordToData},u(Qm,qT);var Zk=function(t){this.name=t||"",this.cx=0,this.cy=0,this._radiusAxis=new Jm,this._angleAxis=new Qm,this._radiusAxis.polar=this._angleAxis.polar=this};Zk.prototype={type:"polar",axisPointerEnabled:!0,constructor:Zk,dimensions:["radius","angle"],model:null,containPoint:function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},containData:function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},getAxis:function(t){return this["_"+t+"Axis"]},getAxes:function(){return[this._radiusAxis,this._angleAxis]},getAxesByScale:function(t){var e=[],i=this._angleAxis,n=this._radiusAxis;return i.scale.type===t&&e.push(i),n.scale.type===t&&e.push(n),e},getAngleAxis:function(){return this._angleAxis},getRadiusAxis:function(){return this._radiusAxis},getOtherAxis:function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},getBaseAxis:function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},getTooltipAxes:function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},dataToPoint:function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},pointToData:function(t,e){var i=this.pointToCoord(t);return[this._radiusAxis.radiusToData(i[0],e),this._angleAxis.angleToData(i[1],e)]},pointToCoord:function(t){var e=t[0]-this.cx,i=t[1]-this.cy,n=this.getAngleAxis(),o=n.getExtent(),a=Math.min(o[0],o[1]),r=Math.max(o[0],o[1]);n.inverse?a=r-360:r=a+360;var s=Math.sqrt(e*e+i*i);e/=s,i/=s;for(var l=Math.atan2(-i,e)/Math.PI*180,u=lr;)l+=360*u;return[s,l]},coordToPoint:function(t){var e=t[0],i=t[1]/180*Math.PI;return[Math.cos(i)*e+this.cx,-Math.sin(i)*e+this.cy]}};var Uk=hM.extend({type:"polarAxis",axis:null,getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"polar",index:this.option.polarIndex,id:this.option.polarId})[0]}});n(Uk.prototype,ET);var Xk={angle:{startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:!1}},radius:{splitNumber:5}};MD("angle",Uk,tv,Xk.angle),MD("radius",Uk,tv,Xk.radius),vs({type:"polar",dependencies:["polarAxis","angleAxis"],coordinateSystem:null,findAxisModel:function(t){var e;return this.ecModel.eachComponent(t,function(t){t.getCoordSysModel()===this&&(e=t)},this),e},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"80%"}});var jk={dimensions:Zk.prototype.dimensions,create:function(t,e){var i=[];return t.eachComponent("polar",function(t,n){var o=new Zk(n);o.update=iv;var a=o.getRadiusAxis(),r=o.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");nv(a,s),nv(r,l),ev(o,t,e),i.push(o),t.coordinateSystem=o,o.model=t}),t.eachSeries(function(e){if("polar"===e.get("coordinateSystem")){var i=t.queryComponents({mainType:"polar",index:e.get("polarIndex"),id:e.get("polarId")})[0];e.coordinateSystem=i.coordinateSystem}}),i}};Ca.register("polar",jk);var Yk=["axisLine","axisLabel","axisTick","splitLine","splitArea"];ED.extend({type:"angleAxis",axisPointerClass:"PolarAxisPointer",render:function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,o=n.polar,a=o.getRadiusAxis().getExtent(),r=n.getTicksCoords(),s=f(n.getViewLabels(),function(t){return(t=i(t)).coord=n.dataToCoord(t.tickValue),t});rv(s),rv(r),d(Yk,function(e){!t.get(e+".show")||n.scale.isBlank()&&"axisLine"!==e||this["_"+e](t,o,r,a,s)},this)}},_axisLine:function(t,e,i,n){var o=t.getModel("axisLine.lineStyle"),a=new pS({shape:{cx:e.cx,cy:e.cy,r:n[av(e)]},style:o.getLineStyle(),z2:1,silent:!0});a.style.fill=null,this.group.add(a)},_axisTick:function(t,e,i,n){var o=t.getModel("axisTick"),a=(o.get("inside")?-1:1)*o.get("length"),s=n[av(e)],l=f(i,function(t){return new MS({shape:ov(e,[s,s+a],t.coord)})});this.group.add(zS(l,{style:r(o.getModel("lineStyle").getLineStyle(),{stroke:t.get("axisLine.lineStyle.color")})}))},_axisLabel:function(t,e,i,n,o){var a=t.getCategories(!0),r=t.getModel("axisLabel"),s=r.get("margin");d(o,function(i,o){var l=r,u=i.tickValue,h=n[av(e)],c=e.coordToPoint([h+s,i.coord]),d=e.cx,f=e.cy,p=Math.abs(c[0]-d)/h<.3?"center":c[0]>d?"left":"right",g=Math.abs(c[1]-f)/h<.3?"middle":c[1]>f?"top":"bottom";a&&a[u]&&a[u].textStyle&&(l=new wo(a[u].textStyle,r,r.ecModel));var m=new fS({silent:!0});this.group.add(m),no(m.style,l,{x:c[0],y:c[1],textFill:l.getTextColor()||t.get("axisLine.lineStyle.color"),text:i.formattedLabel,textAlign:p,textVerticalAlign:g})},this)},_splitLine:function(t,e,i,n){var o=t.getModel("splitLine").getModel("lineStyle"),a=o.get("color"),s=0;a=a instanceof Array?a:[a];for(var l=[],u=0;u=0?"p":"n",D=w;_&&(a[l][I]||(a[l][I]={p:w,n:w}),D=a[l][I][T]);var A,C,L,k;if("radius"===d.dim){var P=d.dataToRadius(M)-w,N=s.dataToAngle(I);Math.abs(P)=0},sP.findTargetInfo=function(t,e){for(var i=this._targetInfoList,n=Mv(e,t),o=0;o=0||nP(n,t.getAxis("y").model)>=0)&&a.push(t)}),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:a[0],coordSyses:a,getPanelRect:hP.grid,xAxisDeclared:r[t.id],yAxisDeclared:s[t.id]})}))},geo:function(t,e){iP(t.geoModels,function(t){var i=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:i,coordSyses:[i],getPanelRect:hP.geo})})}},uP=[function(t,e){var i=t.xAxisModel,n=t.yAxisModel,o=t.gridModel;return!o&&i&&(o=i.axis.grid.model),!o&&n&&(o=n.axis.grid.model),o&&o===e.gridModel},function(t,e){var i=t.geoModel;return i&&i===e.geoModel}],hP={grid:function(){return this.coordSys.grid.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(go(t)),e}},cP={lineX:oP(Iv,0),lineY:oP(Iv,1),rect:function(t,e,i){var n=e[aP[t]]([i[0][0],i[1][0]]),o=e[aP[t]]([i[0][1],i[1][1]]),a=[Sv([n[0],o[0]]),Sv([n[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,i){var n=[[1/0,-1/0],[1/0,-1/0]];return{values:f(i,function(i){var o=e[aP[t]](i);return n[0][0]=Math.min(n[0][0],o[0]),n[1][0]=Math.min(n[1][0],o[1]),n[0][1]=Math.max(n[0][1],o[0]),n[1][1]=Math.max(n[1][1],o[1]),o}),xyMinMax:n}}},dP={lineX:oP(Tv,0),lineY:oP(Tv,1),rect:function(t,e,i){return[[t[0][0]-i[0]*e[0][0],t[0][1]-i[0]*e[0][1]],[t[1][0]-i[1]*e[1][0],t[1][1]-i[1]*e[1][1]]]},polygon:function(t,e,i){return f(t,function(t,n){return[t[0]-i[0]*e[n][0],t[1]-i[1]*e[n][1]]})}},fP=["inBrush","outOfBrush"],pP="__ecBrushSelect",gP="__ecInBrushSelectEvent",mP=LI.VISUAL.BRUSH;fs(mP,function(t,e,i){t.eachComponent({mainType:"brush"},function(e){i&&"takeGlobalCursor"===i.type&&e.setBrushOption("brush"===i.key?i.brushOption:{brushType:!1}),(e.brushTargetManager=new bv(e.option,t)).setInputRanges(e.areas,t)})}),ps(mP,function(t,e,n){var o,a,s=[];t.eachComponent({mainType:"brush"},function(e,n){function l(t){return"all"===m||v[t]}function u(t){return!!t.length}function h(t,e){var i=t.coordinateSystem;w|=i.hasAxisBrushed(),l(e)&&i.eachActiveState(t.getData(),function(t,e){"active"===t&&(x[e]=1)})}function c(i,n,o){var a=Pv(i);if(a&&!Nv(e,n)&&(d(b,function(n){a[n.brushType]&&e.brushTargetManager.controlSeries(n,i,t)&&o.push(n),w|=u(o)}),l(n)&&u(o))){var r=i.getData();r.each(function(t){kv(a,o,r,t)&&(x[t]=1)})}}var p={brushId:e.id,brushIndex:n,brushName:e.name,areas:i(e.areas),selected:[]};s.push(p);var g=e.option,m=g.brushLink,v=[],x=[],_=[],w=0;n||(o=g.throttleType,a=g.throttleDelay);var b=f(e.areas,function(t){return Ov(r({boundingRect:vP[t.brushType](t)},t))}),S=dv(e.option,fP,function(t){t.mappingMethod="fixed"});y(m)&&d(m,function(t){v[t]=1}),t.eachSeries(function(t,e){var i=_[e]=[];"parallel"===t.subType?h(t,e):c(t,e,i)}),t.eachSeries(function(t,e){var i={seriesId:t.id,seriesIndex:e,seriesName:t.name,dataIndex:[]};p.selected.push(i);var n=Pv(t),o=_[e],a=t.getData(),r=l(e)?function(t){return x[t]?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"}:function(t){return kv(n,o,a,t)?(i.dataIndex.push(a.getRawIndex(t)),"inBrush"):"outOfBrush"};(l(e)?w:u(o))&&pv(fP,S,a,r)})}),Cv(e,o,a,s,n)});var vP={lineX:B,lineY:B,rect:function(t){return Ev(t.range)},polygon:function(t){for(var e,i=t.range,n=0,o=i.length;ne[0][1]&&(e[0][1]=a[0]),a[1]e[1][1]&&(e[1][1]=a[1])}return e&&Ev(e)}},yP=["#ddd"];vs({type:"brush",dependencies:["geo","grid","xAxis","yAxis","parallel","series"],defaultOption:{toolbox:null,brushLink:null,seriesIndex:"all",geoIndex:null,xAxisIndex:null,yAxisIndex:null,brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(120,140,180,0.3)",borderColor:"rgba(120,140,180,0.8)"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},areas:[],brushType:null,brushOption:{},coordInfoList:[],optionUpdated:function(t,e){var i=this.option;!e&&fv(i,t,["inBrush","outOfBrush"]);var n=i.inBrush=i.inBrush||{};i.outOfBrush=i.outOfBrush||{color:yP},n.hasOwnProperty("liftZ")||(n.liftZ=5)},setAreas:function(t){t&&(this.areas=f(t,function(t){return Rv(this.option,t)},this))},setBrushOption:function(t){this.brushOption=Rv(this.option,t),this.brushType=this.brushOption.brushType}});ys({type:"brush",init:function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new Qd(e.getZr())).on("brush",m(this._onBrush,this)).mount()},render:function(t){return this.model=t,zv.apply(this,arguments)},updateTransform:zv,updateView:zv,dispose:function(){this._brushController.dispose()},_onBrush:function(t,e){var n=this.model.id;this.model.brushTargetManager.setOutputRanges(t,this.ecModel),(!e.isEnd||e.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:n,areas:i(t),$from:n})}}),cs({type:"brush",event:"brush"},function(t,e){e.eachComponent({mainType:"brush",query:t},function(e){e.setAreas(t.areas)})}),cs({type:"brushSelect",event:"brushSelected",update:"none"},function(){});var xP={},_P=lI.toolbox.brush;Gv.defaultOption={show:!0,type:["rect","polygon","lineX","lineY","keep","clear"],icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:i(_P.title)};var wP=Gv.prototype;wP.render=wP.updateView=function(t,e,i){var n,o,a;e.eachComponent({mainType:"brush"},function(t){n=t.brushType,o=t.brushOption.brushMode||"single",a|=t.areas.length}),this._brushType=n,this._brushMode=o,d(t.get("type",!0),function(e){t.setIconStatus(e,("keep"===e?"multiple"===o:"clear"===e?a:e===n)?"emphasis":"normal")})},wP.getIcons=function(){var t=this.model,e=t.get("icon",!0),i={};return d(t.get("type",!0),function(t){e[t]&&(i[t]=e[t])}),i},wP.onclick=function(t,e,i){var n=this._brushType,o=this._brushMode;"clear"===i?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===i?n:n!==i&&i,brushMode:"keep"===i?"multiple"===o?"single":"multiple":o}})},Bv("brush",Gv),us(function(t,e){var i=t&&t.brush;if(y(i)||(i=i?[i]:[]),i.length){var n=[];d(i,function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(n=n.concat(e))});var o=t&&t.toolbox;y(o)&&(o=o[0]),o||(o={feature:{}},t.toolbox=[o]);var a=o.feature||(o.feature={}),r=a.brush||(a.brush={}),s=r.type||(r.type=[]);s.push.apply(s,n),hv(s),e&&!s.length&&s.push.apply(s,Qk)}});Wv.prototype={constructor:Wv,type:"calendar",dimensions:["time","value"],getDimensionsInfo:function(){return[{name:"time",type:"time"},"value"]},getRangeInfo:function(){return this._rangeInfo},getModel:function(){return this._model},getRect:function(){return this._rect},getCellWidth:function(){return this._sw},getCellHeight:function(){return this._sh},getOrient:function(){return this._orient},getFirstDayOfWeek:function(){return this._firstDayOfWeek},getDateInfo:function(t){var e=(t=Ro(t)).getFullYear(),i=t.getMonth()+1;i=i<10?"0"+i:i;var n=t.getDate();n=n<10?"0"+n:n;var o=t.getDay();return o=Math.abs((o+7-this.getFirstDayOfWeek())%7),{y:e,m:i,d:n,day:o,time:t.getTime(),formatedDate:e+"-"+i+"-"+n,date:t}},getNextNDay:function(t,e){return 0===(e=e||0)?this.getDateInfo(t):((t=new Date(this.getDateInfo(t).time)).setDate(t.getDate()+e),this.getDateInfo(t))},update:function(t,e){function i(t,e){return null!=t[e]&&"auto"!==t[e]}this._firstDayOfWeek=+this._model.getModel("dayLabel").get("firstDay"),this._orient=this._model.get("orient"),this._lineWidth=this._model.getModel("itemStyle").getItemStyle().lineWidth||0,this._rangeInfo=this._getRangeInfo(this._initRangeOption());var n=this._rangeInfo.weeks||1,o=["width","height"],a=this._model.get("cellSize").slice(),r=this._model.getBoxLayoutParams(),s="horizontal"===this._orient?[n,7]:[7,n];d([0,1],function(t){i(a,t)&&(r[o[t]]=a[t]*s[t])});var l={width:e.getWidth(),height:e.getHeight()},u=this._rect=Qo(r,l);d([0,1],function(t){i(a,t)||(a[t]=u[o[t]]/s[t])}),this._sw=a[0],this._sh=a[1]},dataToPoint:function(t,e){y(t)&&(t=t[0]),null==e&&(e=!0);var i=this.getDateInfo(t),n=this._rangeInfo,o=i.formatedDate;if(e&&!(i.time>=n.start.time&&i.timea.end.time&&t.reverse(),t},_getRangeInfo:function(t){var e;(t=[this.getDateInfo(t[0]),this.getDateInfo(t[1])])[0].time>t[1].time&&(e=!0,t.reverse());var i=Math.floor(t[1].time/864e5)-Math.floor(t[0].time/864e5)+1,n=new Date(t[0].time),o=n.getDate(),a=t[1].date.getDate();if(n.setDate(o+i-1),n.getDate()!==a)for(var r=n.getTime()-t[1].time>0?1:-1;n.getDate()!==a&&(n.getTime()-t[1].time)*r>0;)i-=r,n.setDate(o+i-1);var s=Math.floor((i+t[0].day+6)/7),l=e?1-s:s-1;return e&&t.reverse(),{range:[t[0].formatedDate,t[1].formatedDate],start:t[0],end:t[1],allDay:i,weeks:s,nthWeek:l,fweek:t[0].day,lweek:t[1].day}},_getDateByWeeksAndDay:function(t,e,i){var n=this._getRangeInfo(i);if(t>n.weeks||0===t&&en.lweek)return!1;var o=7*(t-1)-n.fweek+e,a=new Date(n.start.time);return a.setDate(n.start.d+o),this.getDateInfo(a)}},Wv.dimensions=Wv.prototype.dimensions,Wv.getDimensionsInfo=Wv.prototype.getDimensionsInfo,Wv.create=function(t,e){var i=[];return t.eachComponent("calendar",function(n){var o=new Wv(n,t,e);i.push(o),n.coordinateSystem=o}),t.eachSeries(function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])}),i},Ca.register("calendar",Wv);var bP=hM.extend({type:"calendar",coordinateSystem:null,defaultOption:{zlevel:0,z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",nameMap:"en",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",nameMap:"en",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},init:function(t,e,i,n){var o=na(t);bP.superApply(this,"init",arguments),Hv(t,o)},mergeOption:function(t,e){bP.superApply(this,"mergeOption",arguments),Hv(this.option,t)}}),SP={EN:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],CN:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},MP={EN:["S","M","T","W","T","F","S"],CN:["日","一","二","三","四","五","六"]};ys({type:"calendar",_tlpoints:null,_blpoints:null,_firstDayOfMonth:null,_firstDayPoints:null,render:function(t,e,i){var n=this.group;n.removeAll();var o=t.coordinateSystem,a=o.getRangeInfo(),r=o.getOrient();this._renderDayRect(t,a,n),this._renderLines(t,a,r,n),this._renderYearText(t,a,r,n),this._renderMonthText(t,r,n),this._renderWeekText(t,a,r,n)},_renderDayRect:function(t,e,i){for(var n=t.coordinateSystem,o=t.getModel("itemStyle").getItemStyle(),a=n.getCellWidth(),r=n.getCellHeight(),s=e.start.time;s<=e.end.time;s=n.getNextNDay(s,1).time){var l=n.dataToRect([s],!1).tl,u=new SS({shape:{x:l[0],y:l[1],width:a,height:r},cursor:"default",style:o});i.add(u)}},_renderLines:function(t,e,i,n){function o(e){a._firstDayOfMonth.push(r.getDateInfo(e)),a._firstDayPoints.push(r.dataToRect([e],!1).tl);var o=a._getLinePointsOfOneWeek(t,e,i);a._tlpoints.push(o[0]),a._blpoints.push(o[o.length-1]),l&&a._drawSplitline(o,s,n)}var a=this,r=t.coordinateSystem,s=t.getModel("splitLine.lineStyle").getLineStyle(),l=t.get("splitLine.show"),u=s.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var h=e.start,c=0;h.time<=e.end.time;c++){o(h.formatedDate),0===c&&(h=r.getDateInfo(e.start.y+"-"+e.start.m));var d=h.date;d.setMonth(d.getMonth()+1),h=r.getDateInfo(d)}o(r.getNextNDay(e.end.time,1).formatedDate),l&&this._drawSplitline(a._getEdgesPoints(a._tlpoints,u,i),s,n),l&&this._drawSplitline(a._getEdgesPoints(a._blpoints,u,i),s,n)},_getEdgesPoints:function(t,e,i){var n=[t[0].slice(),t[t.length-1].slice()],o="horizontal"===i?0:1;return n[0][o]=n[0][o]-e/2,n[1][o]=n[1][o]+e/2,n},_drawSplitline:function(t,e,i){var n=new bS({z2:20,shape:{points:t},style:e});i.add(n)},_getLinePointsOfOneWeek:function(t,e,i){var n=t.coordinateSystem;e=n.getDateInfo(e);for(var o=[],a=0;a<7;a++){var r=n.getNextNDay(e.time,a),s=n.dataToRect([r.time],!1);o[2*r.day]=s.tl,o[2*r.day+1]=s["horizontal"===i?"bl":"tr"]}return o},_formatterLabel:function(t,e){return"string"==typeof t&&t?Xo(t,e):"function"==typeof t?t(e):e.nameMap},_yearTextPositionControl:function(t,e,i,n,o){e=e.slice();var a=["center","bottom"];"bottom"===n?(e[1]+=o,a=["center","top"]):"left"===n?e[0]-=o:"right"===n?(e[0]+=o,a=["center","top"]):e[1]-=o;var r=0;return"left"!==n&&"right"!==n||(r=Math.PI/2),{rotation:r,position:e,style:{textAlign:a[0],textVerticalAlign:a[1]}}},_renderYearText:function(t,e,i,n){var o=t.getModel("yearLabel");if(o.get("show")){var a=o.get("margin"),r=o.get("position");r||(r="horizontal"!==i?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===i?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},d=e.start.y;+e.end.y>+e.start.y&&(d=d+"-"+e.end.y);var f=o.get("formatter"),p={start:e.start.y,end:e.end.y,nameMap:d},g=this._formatterLabel(f,p),m=new fS({z2:30});no(m.style,o,{text:g}),m.attr(this._yearTextPositionControl(m,c[r],i,r,a)),n.add(m)}},_monthTextPositionControl:function(t,e,i,n,o){var a="left",r="top",s=t[0],l=t[1];return"horizontal"===i?(l+=o,e&&(a="center"),"start"===n&&(r="bottom")):(s+=o,e&&(r="middle"),"start"===n&&(a="right")),{x:s,y:l,textAlign:a,textVerticalAlign:r}},_renderMonthText:function(t,e,i){var n=t.getModel("monthLabel");if(n.get("show")){var o=n.get("nameMap"),r=n.get("margin"),s=n.get("position"),l=n.get("align"),u=[this._tlpoints,this._blpoints];_(o)&&(o=SP[o.toUpperCase()]||[]);var h="start"===s?0:1,c="horizontal"===e?0:1;r="start"===s?-r:r;for(var d="center"===l,f=0;f=r[0]&&t<=r[1]}if(t===this._dataZoomModel){var n=this._dimName,o=this.getTargetSeriesModels(),a=t.get("filterMode"),r=this._valueWindow;"none"!==a&&DP(o,function(t){var e=t.getData(),o=e.mapDimension(n,!0);"weakFilter"===a?e.filterSelf(function(t){for(var i,n,a,s=0;sr[1];if(u&&!h&&!c)return!0;u&&(a=!0),h&&(i=!0),c&&(n=!0)}return a&&i&&n}):DP(o,function(n){if("empty"===a)t.setData(e.map(n,function(t){return i(t)?t:NaN}));else{var o={};o[n]=r,e.selectRange(o)}}),DP(o,function(t){e.setApproximateExtent(r,t)})})}}};var LP=d,kP=TP,PP=vs({type:"dataZoom",dependencies:["xAxis","yAxis","zAxis","radiusAxis","angleAxis","singleAxis","series"],defaultOption:{zlevel:0,z:4,orient:null,xAxisIndex:null,yAxisIndex:null,filterMode:"filter",throttle:null,start:0,end:100,startValue:null,endValue:null,minSpan:null,maxSpan:null,minValueSpan:null,maxValueSpan:null,rangeMode:null},init:function(t,e,i){this._dataIntervalByAxis={},this._dataInfo={},this._axisProxies={},this.textStyleModel,this._autoThrottle=!0,this._rangePropMode=["percent","percent"];var n=Kv(t);this.mergeDefaultAndTheme(t,i),this.doInit(n)},mergeOption:function(t){var e=Kv(t);n(this.option,t,!0),this.doInit(e)},doInit:function(t){var e=this.option;a_.canvasSupported||(e.realtime=!1),this._setDefaultThrottle(t),$v(this,t),LP([["start","startValue"],["end","endValue"]],function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=null)},this),this.textStyleModel=this.getModel("textStyle"),this._resetTarget(),this._giveAxisProxies()},_giveAxisProxies:function(){var t=this._axisProxies;this.eachTargetAxis(function(e,i,n,o){var a=this.dependentModels[e.axis][i],r=a.__dzAxisProxy||(a.__dzAxisProxy=new CP(e.name,i,this,o));t[e.name+"_"+i]=r},this)},_resetTarget:function(){var t=this.option,e=this._judgeAutoMode();kP(function(e){var i=e.axisIndex;t[i]=Si(t[i])},this),"axisIndex"===e?this._autoSetAxisIndex():"orient"===e&&this._autoSetOrient()},_judgeAutoMode:function(){var t=this.option,e=!1;kP(function(i){null!=t[i.axisIndex]&&(e=!0)},this);var i=t.orient;return null==i&&e?"orient":e?void 0:(null==i&&(t.orient="horizontal"),"axisIndex")},_autoSetAxisIndex:function(){var t=!0,e=this.get("orient",!0),i=this.option,n=this.dependentModels;if(t){var o="vertical"===e?"y":"x";n[o+"Axis"].length?(i[o+"AxisIndex"]=[0],t=!1):LP(n.singleAxis,function(n){t&&n.get("orient",!0)===e&&(i.singleAxisIndex=[n.componentIndex],t=!1)})}t&&kP(function(e){if(t){var n=[],o=this.dependentModels[e.axis];if(o.length&&!n.length)for(var a=0,r=o.length;a0?100:20}},getFirstTargetAxisModel:function(){var t;return kP(function(e){if(null==t){var i=this.get(e.axisIndex);i.length&&(t=this.dependentModels[e.axis][i[0]])}},this),t},eachTargetAxis:function(t,e){var i=this.ecModel;kP(function(n){LP(this.get(n.axisIndex),function(o){t.call(e,n,o,this,i)},this)},this)},getAxisProxy:function(t,e){return this._axisProxies[t+"_"+e]},getAxisModel:function(t,e){var i=this.getAxisProxy(t,e);return i&&i.getAxisModel()},setRawRange:function(t,e){var i=this.option;LP([["start","startValue"],["end","endValue"]],function(e){null==t[e[0]]&&null==t[e[1]]||(i[e[0]]=t[e[0]],i[e[1]]=t[e[1]])},this),!e&&$v(this,t)},getPercentRange:function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},getValueRange:function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var i=this.findRepresentativeAxisProxy();return i?i.getDataValueWindow():void 0},findRepresentativeAxisProxy:function(t){if(t)return t.__dzAxisProxy;var e=this._axisProxies;for(var i in e)if(e.hasOwnProperty(i)&&e[i].hostedBy(this))return e[i];for(var i in e)if(e.hasOwnProperty(i)&&!e[i].hostedBy(this))return e[i]},getRangePropMode:function(){return this._rangePropMode.slice()}}),NP=$M.extend({type:"dataZoom",render:function(t,e,i,n){this.dataZoomModel=t,this.ecModel=e,this.api=i},getTargetCoordInfo:function(){function t(t,e,i,n){for(var o,a=0;a0&&e%g)p+=f;else{var i=null==t||isNaN(t)||""===t,n=i?0:EP(t,a,u,!0);i&&!l&&e?(c.push([c[c.length-1][0],0]),d.push([d[d.length-1][0],0])):!i&&l&&(c.push([p,0]),d.push([p,0])),c.push([p,n]),d.push([p,n]),p+=f,l=i}});var m=this.dataZoomModel;this._displayables.barGroup.add(new wS({shape:{points:c},style:r({fill:m.get("dataBackgroundColor")},m.getModel("dataBackground.areaStyle").getAreaStyle()),silent:!0,z2:-20})),this._displayables.barGroup.add(new bS({shape:{points:d},style:m.getModel("dataBackground.lineStyle").getLineStyle(),silent:!0,z2:-19}))}}},_prepareDataShadowInfo:function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var i,n=this.ecModel;return t.eachTargetAxis(function(o,a){d(t.getAxisProxy(o.name,a).getTargetSeriesModels(),function(t){if(!(i||!0!==e&&l(WP,t.get("type"))<0)){var r,s=n.getComponent(o.axis,a).axis,u=Jv(o.name),h=t.coordinateSystem;null!=u&&h.getOtherAxis&&(r=h.getOtherAxis(s).inverse),u=t.getData().mapDimension(u),i={thisAxis:s,series:t,thisDim:o.name,otherDim:u,otherAxisInverse:r}}},this)},this),i}},_renderHandle:function(){var t=this._displayables,e=t.handles=[],i=t.handleLabels=[],n=this._displayables.barGroup,o=this._size,a=this.dataZoomModel;n.add(t.filler=new OP({draggable:!0,cursor:Qv(this._orient),drift:zP(this._onDragMove,this,"all"),onmousemove:function(t){zw(t.event)},ondragstart:zP(this._showDataInfo,this,!0),ondragend:zP(this._onDragEnd,this),onmouseover:zP(this._showDataInfo,this,!0),onmouseout:zP(this._showDataInfo,this,!1),style:{fill:a.get("fillerColor"),textPosition:"inside"}})),n.add(new OP(Wn({silent:!0,shape:{x:0,y:0,width:o[0],height:o[1]},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}}))),BP([0,1],function(t){var o=_o(a.get("handleIcon"),{cursor:Qv(this._orient),draggable:!0,drift:zP(this._onDragMove,this,t),onmousemove:function(t){zw(t.event)},ondragend:zP(this._onDragEnd,this),onmouseover:zP(this._showDataInfo,this,!0),onmouseout:zP(this._showDataInfo,this,!1)},{x:-1,y:0,width:2,height:2}),r=o.getBoundingRect();this._handleHeight=Do(a.get("handleSize"),this._size[1]),this._handleWidth=r.width/r.height*this._handleHeight,o.setStyle(a.getModel("handleStyle").getItemStyle());var s=a.get("handleColor");null!=s&&(o.style.fill=s),n.add(e[t]=o);var l=a.textStyleModel;this.group.add(i[t]=new fS({silent:!0,invisible:!0,style:{x:0,y:0,text:"",textVerticalAlign:"middle",textAlign:"center",textFill:l.getTextColor(),textFont:l.getFont()},z2:10}))},this)},_resetInterval:function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[EP(t[0],[0,100],e,!0),EP(t[1],[0,100],e,!0)]},_updateInterval:function(t,e){var i=this.dataZoomModel,n=this._handleEnds,o=this._getViewExtent(),a=i.findRepresentativeAxisProxy().getMinMaxSpan(),r=[0,100];PC(e,n,o,i.get("zoomLock")?"all":t,null!=a.minSpan?EP(a.minSpan,r,o,!0):null,null!=a.maxSpan?EP(a.maxSpan,r,o,!0):null);var s=this._range,l=this._range=RP([EP(n[0],o,r,!0),EP(n[1],o,r,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},_updateView:function(t){var e=this._displayables,i=this._handleEnds,n=RP(i.slice()),o=this._size;BP([0,1],function(t){var n=e.handles[t],a=this._handleHeight;n.attr({scale:[a/2,a/2],position:[i[t],o[1]/2-a/2]})},this),e.filler.setShape({x:n[0],y:0,width:n[1]-n[0],height:o[1]}),this._updateDataInfo(t)},_updateDataInfo:function(t){function e(t){var e=go(n.handles[t].parent,this.group),i=vo(0===t?"right":"left",e),s=this._handleWidth/2+GP,l=mo([c[t]+(0===t?-s:s),this._size[1]/2],e);o[t].setStyle({x:l[0],y:l[1],textVerticalAlign:a===VP?"middle":i,textAlign:a===VP?i:"center",text:r[t]})}var i=this.dataZoomModel,n=this._displayables,o=n.handleLabels,a=this._orient,r=["",""];if(i.get("showDetail")){var s=i.findRepresentativeAxisProxy();if(s){var l=s.getAxisModel().axis,u=this._range,h=t?s.calculateDataWindow({start:u[0],end:u[1]}).valueWindow:s.getDataValueWindow();r=[this._formatLabel(h[0],l),this._formatLabel(h[1],l)]}}var c=RP(this._handleEnds.slice());e.call(this,0),e.call(this,1)},_formatLabel:function(t,e){var i=this.dataZoomModel,n=i.get("labelFormatter"),o=i.get("labelPrecision");null!=o&&"auto"!==o||(o=e.getPixelPrecision());var a=null==t||isNaN(t)?"":"category"===e.type||"time"===e.type?e.scale.getLabel(Math.round(t)):t.toFixed(Math.min(o,20));return x(n)?n(t,a):_(n)?n.replace("{value}",a):a},_showDataInfo:function(t){t=this._dragging||t;var e=this._displayables.handleLabels;e[0].attr("invisible",!t),e[1].attr("invisible",!t)},_onDragMove:function(t,e,i){this._dragging=!0;var n=mo([e,i],this._displayables.barGroup.getLocalTransform(),!0),o=this._updateInterval(t,n[0]),a=this.dataZoomModel.get("realtime");this._updateView(!a),o&&a&&this._dispatchZoomAction()},_onDragEnd:function(){this._dragging=!1,this._showDataInfo(!1),!this.dataZoomModel.get("realtime")&&this._dispatchZoomAction()},_onClickPanelClick:function(t){var e=this._size,i=this._displayables.barGroup.transformCoordToLocal(t.offsetX,t.offsetY);if(!(i[0]<0||i[0]>e[0]||i[1]<0||i[1]>e[1])){var n=this._handleEnds,o=(n[0]+n[1])/2,a=this._updateInterval("all",i[0]-o);this._updateView(),a&&this._dispatchZoomAction()}},_dispatchZoomAction:function(){var t=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,start:t[0],end:t[1]})},_findCoordRect:function(){var t;if(BP(this.getTargetCoordInfo(),function(e){if(!t&&e.length){var i=e[0].model.coordinateSystem;t=i.getRect&&i.getRect()}}),!t){var e=this.api.getWidth(),i=this.api.getHeight();t={x:.2*e,y:.2*i,width:.6*e,height:.6*i}}return t}});PP.extend({type:"dataZoom.inside",defaultOption:{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,preventDefaultMouseMove:!0}});var HP=v,ZP="\0_ec_dataZoom_roams",UP=m,XP=NP.extend({type:"dataZoom.inside",init:function(t,e){this._range},render:function(t,e,i,n){XP.superApply(this,"render",arguments),this._range=t.getPercentRange(),d(this.getTargetCoordInfo(),function(e,n){var o=f(e,function(t){return iy(t.model)});d(e,function(e){var a=e.model,r=t.option;ty(i,{coordId:iy(a),allCoordIds:o,containsPoint:function(t,e,i){return a.coordinateSystem.containPoint([e,i])},dataZoomId:t.id,throttleRate:t.get("throttle",!0),panGetRange:UP(this._onPan,this,e,n),zoomGetRange:UP(this._onZoom,this,e,n),zoomLock:r.zoomLock,disabled:r.disabled,roamControllerOpt:{zoomOnMouseWheel:r.zoomOnMouseWheel,moveOnMouseMove:r.moveOnMouseMove,preventDefaultMouseMove:r.preventDefaultMouseMove}})},this)},this)},dispose:function(){ey(this.api,this.dataZoomModel.id),XP.superApply(this,"dispose",arguments),this._range=null},_onPan:function(t,e,i,n,o,a,r,s,l){var u=this._range,h=u.slice(),c=t.axisModels[0];if(c){var d=jP[e]([a,r],[s,l],c,i,t),f=d.signal*(h[1]-h[0])*d.pixel/d.pixelLength;return PC(f,h,[0,100],"all"),this._range=h,u[0]!==h[0]||u[1]!==h[1]?h:void 0}},_onZoom:function(t,e,i,n,o,a){var r=this._range,s=r.slice(),l=t.axisModels[0];if(l){var u=jP[e](null,[o,a],l,i,t),h=(u.signal>0?u.pixelStart+u.pixelLength-u.pixel:u.pixel-u.pixelStart)/u.pixelLength*(s[1]-s[0])+s[0];n=Math.max(1/n,0),s[0]=(s[0]-h)*n+h,s[1]=(s[1]-h)*n+h;var c=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return PC(0,s,[0,100],0,c.minSpan,c.maxSpan),this._range=s,r[0]!==s[0]||r[1]!==s[1]?s:void 0}}}),jP={grid:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem.getRect();return t=t||[0,0],"x"===a.dim?(r.pixel=e[0]-t[0],r.pixelLength=s.width,r.pixelStart=s.x,r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=s.height,r.pixelStart=s.y,r.signal=a.inverse?-1:1),r},polar:function(t,e,i,n,o){var a=i.axis,r={},s=o.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===i.mainType?(r.pixel=e[0]-t[0],r.pixelLength=l[1]-l[0],r.pixelStart=l[0],r.signal=a.inverse?1:-1):(r.pixel=e[1]-t[1],r.pixelLength=u[1]-u[0],r.pixelStart=u[0],r.signal=a.inverse?-1:1),r},singleAxis:function(t,e,i,n,o){var a=i.axis,r=o.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===a.orient?(s.pixel=e[0]-t[0],s.pixelLength=r.width,s.pixelStart=r.x,s.signal=a.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=r.height,s.pixelStart=r.y,s.signal=a.inverse?-1:1),s}};hs({getTargetSeries:function(t){var e=R();return t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){d(n.getAxisProxy(t.name,i).getTargetSeriesModels(),function(t){e.set(t.uid,t)})})}),e},modifyOutputEnd:!0,overallReset:function(t,e){t.eachComponent("dataZoom",function(t){t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).reset(n,e)}),t.eachTargetAxis(function(t,i,n){n.getAxisProxy(t.name,i).filterData(n,e)})}),t.eachComponent("dataZoom",function(t){var e=t.findRepresentativeAxisProxy(),i=e.getDataPercentWindow(),n=e.getDataValueWindow();t.setRawRange({start:i[0],end:i[1],startValue:n[0],endValue:n[1]},!0)})}}),cs("dataZoom",function(t,e){var i=Uv(m(e.eachComponent,e,"dataZoom"),TP,function(t,e){return t.get(e.axisIndex)}),n=[];e.eachComponent({mainType:"dataZoom",query:t},function(t,e){n.push.apply(n,i(t).nodes)}),d(n,function(e,i){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})})});var YP=d,qP=function(t){var e=t&&t.visualMap;y(e)||(e=e?[e]:[]),YP(e,function(t){if(t){cy(t,"splitList")&&!cy(t,"pieces")&&(t.pieces=t.splitList,delete t.splitList);var e=t.pieces;e&&y(e)&&YP(e,function(t){w(t)&&(cy(t,"start")&&!cy(t,"min")&&(t.min=t.start),cy(t,"end")&&!cy(t,"max")&&(t.max=t.end))})}})};hM.registerSubTypeDefaulter("visualMap",function(t){return t.categories||(t.pieces?t.pieces.length>0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"});var KP=LI.VISUAL.COMPONENT;ps(KP,{createOnAllSeries:!0,reset:function(t,e){var i=[];return e.eachComponent("visualMap",function(e){var n=t.pipelineContext;!e.isTargetSeries(t)||n&&n.large||i.push(gv(e.stateList,e.targetVisuals,m(e.getValueState,e),e.getDataDimension(t.getData())))}),i}}),ps(KP,{createOnAllSeries:!0,reset:function(t,e){var i=t.getData(),n=[];e.eachComponent("visualMap",function(e){if(e.isTargetSeries(t)){var o=e.getVisualMeta(m(dy,null,t,e))||{stops:[],outerColors:[]},a=e.getDataDimension(i),r=i.getDimensionInfo(a);null!=r&&(o.dimension=r.index,n.push(o))}}),t.getData().setVisual("visualMeta",n)}});var $P={get:function(t,e,n){var o=i((JP[t]||{})[e]);return n&&y(o)?o[o.length-1]:o}},JP={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},QP=ZA.mapVisual,tN=ZA.eachVisual,eN=y,iN=d,nN=Co,oN=To,aN=B,rN=vs({type:"visualMap",dependencies:["series"],stateList:["inRange","outOfRange"],replacableOptionKeys:["inRange","outOfRange","target","controller","color"],dataBound:[-1/0,1/0],layoutMode:{type:"box",ignoreSize:!0},defaultOption:{show:!0,zlevel:0,z:4,seriesIndex:"all",min:0,max:200,dimension:null,inRange:null,outOfRange:null,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,color:null,formatter:null,text:null,textStyle:{color:"#333"}},init:function(t,e,i){this._dataExtent,this.targetVisuals={},this.controllerVisuals={},this.textStyleModel,this.itemSize,this.mergeDefaultAndTheme(t,i)},optionUpdated:function(t,e){var i=this.option;a_.canvasSupported||(i.realtime=!1),!e&&fv(i,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},resetVisual:function(t){var e=this.stateList;t=m(t,this),this.controllerVisuals=dv(this.option.controller,e,t),this.targetVisuals=dv(this.option.target,e,t)},getTargetSeriesIndices:function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries(function(t,i){e.push(i)}):e=Si(t),e},eachTargetSeries:function(t,e){d(this.getTargetSeriesIndices(),function(i){t.call(e,this.ecModel.getSeriesByIndex(i))},this)},isTargetSeries:function(t){var e=!1;return this.eachTargetSeries(function(i){i===t&&(e=!0)}),e},formatValueText:function(t,e,i){function n(t){return t===l[0]?"min":t===l[1]?"max":(+t).toFixed(Math.min(s,20))}var o,a,r=this.option,s=r.precision,l=this.dataBound,u=r.formatter;return i=i||["<",">"],y(t)&&(t=t.slice(),o=!0),a=e?t:o?[n(t[0]),n(t[1])]:n(t),_(u)?u.replace("{value}",o?a[0]:a).replace("{value2}",o?a[1]:a):x(u)?o?u(t[0],t[1]):u(t):o?t[0]===l[0]?i[0]+" "+a[1]:t[1]===l[1]?i[1]+" "+a[0]:a[0]+" - "+a[1]:a},resetExtent:function(){var t=this.option,e=nN([t.min,t.max]);this._dataExtent=e},getDataDimension:function(t){var e=this.option.dimension,i=t.dimensions;if(null!=e||i.length){if(null!=e)return t.getDimension(e);for(var n=t.dimensions,o=n.length-1;o>=0;o--){var a=n[o];if(!t.getDimensionInfo(a).isCalculationCoord)return a}}},getExtent:function(){return this._dataExtent.slice()},completeVisualOption:function(){function t(t){eN(o.color)&&!t.inRange&&(t.inRange={color:o.color.slice().reverse()}),t.inRange=t.inRange||{color:e.get("gradientColor")},iN(this.stateList,function(e){var i=t[e];if(_(i)){var n=$P.get(i,"active",l);n?(t[e]={},t[e][i]=n):delete t[e]}},this)}var e=this.ecModel,o=this.option,a={inRange:o.inRange,outOfRange:o.outOfRange},r=o.target||(o.target={}),s=o.controller||(o.controller={});n(r,a),n(s,a);var l=this.isCategory();t.call(this,r),t.call(this,s),function(t,e,i){var n=t[e],o=t[i];n&&!o&&(o=t[i]={},iN(n,function(t,e){if(ZA.isValidType(e)){var i=$P.get(e,"inactive",l);null!=i&&(o[e]=i,"color"!==e||o.hasOwnProperty("opacity")||o.hasOwnProperty("colorAlpha")||(o.opacity=[0,0]))}}))}.call(this,r,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,o=this.get("inactiveColor");iN(this.stateList,function(a){var r=this.itemSize,s=t[a];s||(s=t[a]={color:l?o:[o]}),null==s.symbol&&(s.symbol=e&&i(e)||(l?"roundRect":["roundRect"])),null==s.symbolSize&&(s.symbolSize=n&&i(n)||(l?r[0]:[r[0],r[0]])),s.symbol=QP(s.symbol,function(t){return"none"===t||"square"===t?"roundRect":t});var u=s.symbolSize;if(null!=u){var h=-1/0;tN(u,function(t){t>h&&(h=t)}),s.symbolSize=QP(u,function(t){return oN(t,[0,h],[0,r[0]],!0)})}},this)}.call(this,s)},resetItemSize:function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},isCategory:function(){return!!this.option.categories},setSelected:aN,getValueState:aN,getVisualMeta:aN}),sN=[20,140],lN=rN.extend({type:"visualMap.continuous",defaultOption:{align:"auto",calculable:!1,range:null,realtime:!0,itemHeight:null,itemWidth:null,hoverLink:!0,hoverLinkDataSize:null,hoverLinkOnHandle:null},optionUpdated:function(t,e){lN.superApply(this,"optionUpdated",arguments),this.resetExtent(),this.resetVisual(function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()}),this._resetRange()},resetItemSize:function(){lN.superApply(this,"resetItemSize",arguments);var t=this.itemSize;"horizontal"===this._orient&&t.reverse(),(null==t[0]||isNaN(t[0]))&&(t[0]=sN[0]),(null==t[1]||isNaN(t[1]))&&(t[1]=sN[1])},_resetRange:function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},completeVisualOption:function(){rN.prototype.completeVisualOption.apply(this,arguments),d(this.stateList,function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=0)},this)},setSelected:function(t){this.option.range=t.slice(),this._resetRange()},getSelected:function(){var t=this.getExtent(),e=Co((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=i[1]||t<=e[1])?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){t[0]<=e&&e<=t[1]&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getVisualMeta:function(t){function e(e,i){o.push({value:e,color:t(e,i)})}for(var i=fy(0,0,this.getExtent()),n=fy(0,0,this.option.range.slice()),o=[],a=0,r=0,s=n.length,l=i.length;rt[1])break;i.push({color:this.getControllerVisual(a,"color",e),offset:o/100})}return i.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),i},_createBarPoints:function(t,e){var i=this.visualMapModel.itemSize;return[[i[0]-e[0],t[0]],[i[0],t[0]],[i[0],t[1]],[i[0]-e[1],t[1]]]},_createBarGroup:function(t){var e=this._orient,i=this.visualMapModel.get("inverse");return new sw("horizontal"!==e||i?"horizontal"===e&&i?{scale:"bottom"===t?[-1,1]:[1,1],rotation:-Math.PI/2}:"vertical"!==e||i?{scale:"left"===t?[1,1]:[-1,1]}:{scale:"left"===t?[1,-1]:[-1,-1]}:{scale:"bottom"===t?[1,1]:[-1,1],rotation:Math.PI/2})},_updateHandle:function(t,e){if(this._useHandle){var i=this._shapes,n=this.visualMapModel,o=i.handleThumbs,a=i.handleLabels;cN([0,1],function(r){var s=o[r];s.setStyle("fill",e.handlesColor[r]),s.position[1]=t[r];var l=mo(i.handleLabelPoints[r],go(s,this.group));a[r].setStyle({x:l[0],y:l[1],text:n.formatValueText(this._dataInterval[r]),textVerticalAlign:"middle",textAlign:this._applyTransform("horizontal"===this._orient?0===r?"bottom":"top":"left",i.barGroup)})},this)}},_showIndicator:function(t,e,i,n){var o=this.visualMapModel,a=o.getExtent(),r=o.itemSize,s=[0,r[1]],l=hN(t,a,s,!0),u=this._shapes,h=u.indicator;if(h){h.position[1]=l,h.attr("invisible",!1),h.setShape("points",yy(!!i,n,l,r[1]));var c={convertOpacityToAlpha:!0},d=this.getControllerVisual(t,"color",c);h.setStyle("fill",d);var f=mo(u.indicatorLabelPoint,go(h,this.group)),p=u.indicatorLabel;p.attr("invisible",!1);var g=this._applyTransform("left",u.barGroup),m=this._orient;p.setStyle({text:(i||"")+o.formatValueText(e),textVerticalAlign:"horizontal"===m?g:"middle",textAlign:"horizontal"===m?"center":g,x:f[0],y:f[1]})}},_enableHoverLinkToSeries:function(){var t=this;this._shapes.barGroup.on("mousemove",function(e){if(t._hovering=!0,!t._dragging){var i=t.visualMapModel.itemSize,n=t._applyTransform([e.offsetX,e.offsetY],t._shapes.barGroup,!0,!0);n[1]=dN(fN(0,n[1]),i[1]),t._doHoverLinkToSeries(n[1],0<=n[0]&&n[0]<=i[0])}}).on("mouseout",function(){t._hovering=!1,!t._dragging&&t._clearHoverLinkToSeries()})},_enableHoverLinkFromSeries:function(){var t=this.api.getZr();this.visualMapModel.option.hoverLink?(t.on("mouseover",this._hoverLinkFromSeriesMouseOver,this),t.on("mouseout",this._hideIndicator,this)):this._clearHoverLinkFromSeries()},_doHoverLinkToSeries:function(t,e){var i=this.visualMapModel,n=i.itemSize;if(i.option.hoverLink){var o=[0,n[1]],a=i.getExtent();t=dN(fN(o[0],t),o[1]);var r=xy(i,a,o),s=[t-r,t+r],l=hN(t,o,a,!0),u=[hN(s[0],o,a,!0),hN(s[1],o,a,!0)];s[0]o[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",r):u[1]===1/0?this._showIndicator(l,u[0],"> ",r):this._showIndicator(l,l,"≈ ",r));var h=this._hoverLinkDataIndices,c=[];(e||_y(i))&&(c=this._hoverLinkDataIndices=i.findTargetDataIndices(u));var d=ki(h,c);this._dispatchHighDown("downplay",gy(d[0])),this._dispatchHighDown("highlight",gy(d[1]))}},_hoverLinkFromSeriesMouseOver:function(t){var e=t.target,i=this.visualMapModel;if(e&&null!=e.dataIndex){var n=this.ecModel.getSeriesByIndex(e.seriesIndex);if(i.isTargetSeries(n)){var o=n.getData(e.dataType),a=o.get(i.getDataDimension(o),e.dataIndex,!0);isNaN(a)||this._showIndicator(a,a)}}},_hideIndicator:function(){var t=this._shapes;t.indicator&&t.indicator.attr("invisible",!0),t.indicatorLabel&&t.indicatorLabel.attr("invisible",!0)},_clearHoverLinkToSeries:function(){this._hideIndicator();var t=this._hoverLinkDataIndices;this._dispatchHighDown("downplay",gy(t)),t.length=0},_clearHoverLinkFromSeries:function(){this._hideIndicator();var t=this.api.getZr();t.off("mouseover",this._hoverLinkFromSeriesMouseOver),t.off("mouseout",this._hideIndicator)},_applyTransform:function(t,e,i,n){var o=go(e,n?null:this.group);return BS[y(t)?"applyTransform":"transformDirection"](t,o,i)},_dispatchHighDown:function(t,e){e&&e.length&&this.api.dispatchAction({type:t,batch:e})},dispose:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()},remove:function(){this._clearHoverLinkFromSeries(),this._clearHoverLinkToSeries()}});cs({type:"selectDataRange",event:"dataRangeSelected",update:"update"},function(t,e){e.eachComponent({mainType:"visualMap",query:t},function(e){e.setSelected(t.selected)})}),us(qP);var vN=rN.extend({type:"visualMap.piecewise",defaultOption:{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieceList:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0,showLabel:null},optionUpdated:function(t,e){vN.superApply(this,"optionUpdated",arguments),this._pieceList=[],this.resetExtent();var n=this._mode=this._determineMode();yN[this._mode].call(this),this._resetSelected(t,e);var o=this.option.categories;this.resetVisual(function(t,e){"categories"===n?(t.mappingMethod="category",t.categories=i(o)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=f(this._pieceList,function(t){var t=i(t);return"inRange"!==e&&(t.visual=null),t}))})},completeVisualOption:function(){function t(t,e,i){return t&&t[e]&&(w(t[e])?t[e].hasOwnProperty(i):t[e]===i)}var e=this.option,i={},n=ZA.listVisualTypes(),o=this.isCategory();d(e.pieces,function(t){d(n,function(e){t.hasOwnProperty(e)&&(i[e]=1)})}),d(i,function(i,n){var a=0;d(this.stateList,function(i){a|=t(e,i,n)||t(e.target,i,n)},this),!a&&d(this.stateList,function(t){(e[t]||(e[t]={}))[n]=$P.get(n,"inRange"===t?"active":"inactive",o)})},this),rN.prototype.completeVisualOption.apply(this,arguments)},_resetSelected:function(t,e){var i=this.option,n=this._pieceList,o=(e?i:t).selected||{};if(i.selected=o,d(n,function(t,e){var i=this.getSelectedMapKey(t);o.hasOwnProperty(i)||(o[i]=!0)},this),"single"===i.selectedMode){var a=!1;d(n,function(t,e){var i=this.getSelectedMapKey(t);o[i]&&(a?o[i]=!1:a=!0)},this)}},getSelectedMapKey:function(t){return"categories"===this._mode?t.value+"":t.index+""},getPieceList:function(){return this._pieceList},_determineMode:function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},setSelected:function(t){this.option.selected=i(t)},getValueState:function(t){var e=ZA.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},findTargetDataIndices:function(t){var e=[];return this.eachTargetSeries(function(i){var n=[],o=i.getData();o.each(this.getDataDimension(o),function(e,i){ZA.findPieceIndex(e,this._pieceList)===t&&n.push(i)},this),e.push({seriesId:i.id,dataIndex:n})},this),e},getRepresentValue:function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var i=t.interval||[];e=i[0]===-1/0&&i[1]===1/0?0:(i[0]+i[1])/2}return e},getVisualMeta:function(t){function e(e,a){var r=o.getRepresentValue({interval:e});a||(a=o.getValueState(r));var s=t(r,a);e[0]===-1/0?n[0]=s:e[1]===1/0?n[1]=s:i.push({value:e[0],color:s},{value:e[1],color:s})}if(!this.isCategory()){var i=[],n=[],o=this,a=this._pieceList.slice();if(a.length){var r=a[0].interval[0];r!==-1/0&&a.unshift({interval:[-1/0,r]}),(r=a[a.length-1].interval[1])!==1/0&&a.push({interval:[r,1/0]})}else a.push({interval:[-1/0,1/0]});var s=-1/0;return d(a,function(t){var i=t.interval;i&&(i[0]>s&&e([s,i[0]],"outOfRange"),e(i.slice()),s=i[1])},this),{stops:i,outerColors:n}}}}),yN={splitNumber:function(){var t=this.option,e=this._pieceList,i=Math.min(t.precision,20),n=this.getExtent(),o=t.splitNumber;o=Math.max(parseInt(o,10),1),t.splitNumber=o;for(var a=(n[1]-n[0])/o;+a.toFixed(i)!==a&&i<5;)i++;t.precision=i,a=+a.toFixed(i);var r=0;t.minOpen&&e.push({index:r++,interval:[-1/0,n[0]],close:[0,0]});for(var s=n[0],l=r+o;r","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,i)},this)}};uN.extend({type:"visualMap.piecewise",doRender:function(){var t=this.group;t.removeAll();var e=this.visualMapModel,i=e.get("textGap"),n=e.textStyleModel,o=n.getFont(),a=n.getTextColor(),r=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=T(e.get("showLabel",!0),!u);u&&this._renderEndsText(t,u[0],s,h,r),d(l.viewPieceList,function(n){var l=n.piece,u=new sw;u.onclick=m(this._onItemClick,this,l),this._enableHoverLink(u,n.indexInModelPieceList);var c=e.getRepresentValue(l);if(this._createItemSymbol(u,c,[0,0,s[0],s[1]]),h){var d=this.visualMapModel.getValueState(c);u.add(new fS({style:{x:"right"===r?-i:s[0]+i,y:s[1]/2,text:l.text,textVerticalAlign:"middle",textAlign:r,textFont:o,textFill:a,opacity:"outOfRange"===d?.5:1}}))}t.add(u)},this),u&&this._renderEndsText(t,u[1],s,h,r),sM(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},_enableHoverLink:function(t,e){function i(t){var i=this.visualMapModel;i.option.hoverLink&&this.api.dispatchAction({type:t,batch:gy(i.findTargetDataIndices(e))})}t.on("mouseover",m(i,this,"highlight")).on("mouseout",m(i,this,"downplay"))},_getItemAlign:function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return py(t,this.api,t.itemSize);var i=e.align;return i&&"auto"!==i||(i="left"),i},_renderEndsText:function(t,e,i,n,o){if(e){var a=new sw,r=this.visualMapModel.textStyleModel;a.add(new fS({style:{x:n?"right"===o?i[0]:0:i[0]/2,y:i[1]/2,textVerticalAlign:"middle",textAlign:n?o:"center",text:e,textFont:r.getFont(),textFill:r.getTextColor()}})),t.add(a)}},_getViewData:function(){var t=this.visualMapModel,e=f(t.getPieceList(),function(t,e){return{piece:t,indexInModelPieceList:e}}),i=t.get("text"),n=t.get("orient"),o=t.get("inverse");return("horizontal"===n?o:!o)?e.reverse():i&&(i=i.slice().reverse()),{viewPieceList:e,endsText:i}},_createItemSymbol:function(t,e,i){t.add(Tl(this.getControllerVisual(e,"symbol"),i[0],i[1],i[2],i[3],this.getControllerVisual(e,"color")))},_onItemClick:function(t){var e=this.visualMapModel,n=e.option,o=i(n.selected),a=e.getSelectedMapKey(t);"single"===n.selectedMode?(o[a]=!0,d(o,function(t,e){o[e]=e===a})):o[a]=!o[a],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:o})}});us(qP);var xN=Fo,_N=Zo,wN=vs({type:"marker",dependencies:["series","grid","polar","geo"],init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i),this.mergeOption(t,i,n.createdBySelf,!0)},isAnimationEnabled:function(){if(a_.node)return!1;var t=this.__hostSeries;return this.getShallow("animation")&&t&&t.isAnimationEnabled()},mergeOption:function(t,e,i,n){var o=this.constructor,r=this.mainType+"Model";i||e.eachSeries(function(t){var i=t.get(this.mainType,!0),s=t[r];i&&i.data?(s?s.mergeOption(i,e,!0):(n&&Sy(i),d(i.data,function(t){t instanceof Array?(Sy(t[0]),Sy(t[1])):Sy(t)}),a(s=new o(i,this,e),{mainType:this.mainType,seriesIndex:t.seriesIndex,name:t.name,createdBySelf:!0}),s.__hostSeries=t),t[r]=s):t[r]=null},this)},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=y(i)?f(i,xN).join(", "):xN(i),o=e.getName(t),a=_N(this.name);return(null!=i||o)&&(a+="
"),o&&(a+=_N(o),null!=i&&(a+=" : ")),null!=i&&(a+=_N(n)),a},getData:function(){return this._data},setData:function(t){this._data=t}});h(wN,XM),wN.extend({type:"markPoint",defaultOption:{zlevel:0,z:5,symbol:"pin",symbolSize:50,tooltip:{trigger:"item"},label:{show:!0,position:"inside"},itemStyle:{borderWidth:2},emphasis:{label:{show:!0}}}});var bN=l,SN=v,MN={min:SN(Ty,"min"),max:SN(Ty,"max"),average:SN(Ty,"average")},IN=ys({type:"marker",init:function(){this.markerGroupMap=R()},render:function(t,e,i){var n=this.markerGroupMap;n.each(function(t){t.__keep=!1});var o=this.type+"Model";e.eachSeries(function(t){var n=t[o];n&&this.renderSeries(t,n,e,i)},this),n.each(function(t){!t.__keep&&this.group.remove(t.group)},this)},renderSeries:function(){}});IN.extend({type:"markPoint",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markPointModel;e&&(Ny(e.getData(),t,i),this.markerGroupMap.get(t.id).updateLayout(e))},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,r=t.getData(),s=this.markerGroupMap,l=s.get(a)||s.set(a,new Ql),u=Oy(o,t,e);e.setData(u),Ny(e.getData(),t,n),u.each(function(t){var i=u.getItemModel(t),n=i.getShallow("symbolSize");"function"==typeof n&&(n=n(e.getRawValue(t),e.getDataParams(t))),u.setItemVisual(t,{symbolSize:n,color:i.get("itemStyle.color")||r.getVisual("color"),symbol:i.getShallow("symbol")})}),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl(function(t){t.traverse(function(t){t.dataModel=e})}),l.__keep=!0,l.group.silent=e.get("silent")||t.get("silent")}}),us(function(t){t.markPoint=t.markPoint||{}}),wN.extend({type:"markLine",defaultOption:{zlevel:0,z:5,symbol:["circle","arrow"],symbolSize:[8,16],precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end"},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"}});var TN=function(t,e,o,r){var s=t.getData(),l=r.type;if(!y(r)&&("min"===l||"max"===l||"average"===l||"median"===l||null!=r.xAxis||null!=r.yAxis)){var u,h;if(null!=r.yAxis||null!=r.xAxis)u=null!=r.yAxis?"y":"x",e.getAxis(u),h=T(r.yAxis,r.xAxis);else{var c=Ay(r,s,e,t);u=c.valueDataDim,c.valueAxis,h=Py(s,u,l)}var d="x"===u?0:1,f=1-d,p=i(r),g={};p.type=null,p.coord=[],g.coord=[],p.coord[f]=-1/0,g.coord[f]=1/0;var m=o.get("precision");m>=0&&"number"==typeof h&&(h=+h.toFixed(Math.min(m,20))),p.coord[d]=g.coord[d]=h,r=[p,g,{type:l,valueIndex:r.valueIndex,value:h}]}return r=[Dy(t,r[0]),Dy(t,r[1]),a({},r[2])],r[2].type=r[2].type||"",n(r[2],r[0]),n(r[2],r[1]),r};IN.extend({type:"markLine",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markLineModel;if(e){var n=e.getData(),o=e.__from,a=e.__to;o.each(function(e){By(o,e,!0,t,i),By(a,e,!1,t,i)}),n.each(function(t){n.setItemLayout(t,[o.getItemLayout(t),a.getItemLayout(t)])}),this.markerGroupMap.get(t.id).updateLayout()}},this)},renderSeries:function(t,e,i,n){function o(e,i,o){var a=e.getItemModel(i);By(e,i,o,t,n),e.setItemVisual(i,{symbolSize:a.get("symbolSize")||g[o?0:1],symbol:a.get("symbol",!0)||p[o?0:1],color:a.get("itemStyle.color")||s.getVisual("color")})}var a=t.coordinateSystem,r=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(r)||l.set(r,new Sd);this.group.add(u.group);var h=Vy(a,t,e),c=h.from,d=h.to,f=h.line;e.__from=c,e.__to=d,e.setData(f);var p=e.get("symbol"),g=e.get("symbolSize");y(p)||(p=[p,p]),"number"==typeof g&&(g=[g,g]),h.from.each(function(t){o(c,t,!0),o(d,t,!1)}),f.each(function(t){var e=f.getItemModel(t).get("lineStyle.color");f.setItemVisual(t,{color:e||c.getItemVisual(t,"color")}),f.setItemLayout(t,[c.getItemLayout(t),d.getItemLayout(t)]),f.setItemVisual(t,{fromSymbolSize:c.getItemVisual(t,"symbolSize"),fromSymbol:c.getItemVisual(t,"symbol"),toSymbolSize:d.getItemVisual(t,"symbolSize"),toSymbol:d.getItemVisual(t,"symbol")})}),u.updateData(f),h.line.eachItemGraphicEl(function(t,i){t.traverse(function(t){t.dataModel=e})}),u.__keep=!0,u.group.silent=e.get("silent")||t.get("silent")}}),us(function(t){t.markLine=t.markLine||{}}),wN.extend({type:"markArea",defaultOption:{zlevel:0,z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}}});var DN=function(t,e,i,n){var a=Dy(t,n[0]),r=Dy(t,n[1]),s=T,l=a.coord,u=r.coord;l[0]=s(l[0],-1/0),l[1]=s(l[1],-1/0),u[0]=s(u[0],1/0),u[1]=s(u[1],1/0);var h=o([{},a,r]);return h.coord=[a.coord,r.coord],h.x0=a.x,h.y0=a.y,h.x1=r.x,h.y1=r.y,h},AN=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]];IN.extend({type:"markArea",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markAreaModel;if(e){var n=e.getData();n.each(function(e){var o=f(AN,function(o){return Hy(n,e,o,t,i)});n.setItemLayout(e,o),n.getItemGraphicEl(e).setShape("points",o)})}},this)},renderSeries:function(t,e,i,n){var o=t.coordinateSystem,a=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(a)||l.set(a,{group:new sw});this.group.add(u.group),u.__keep=!0;var h=Zy(o,t,e);e.setData(h),h.each(function(e){h.setItemLayout(e,f(AN,function(i){return Hy(h,e,i,t,n)})),h.setItemVisual(e,{color:s.getVisual("color")})}),h.diff(u.__data).add(function(t){var e=new wS({shape:{points:h.getItemLayout(t)}});h.setItemGraphicEl(t,e),u.group.add(e)}).update(function(t,i){var n=u.__data.getItemGraphicEl(i);fo(n,{shape:{points:h.getItemLayout(t)}},e,t),u.group.add(n),h.setItemGraphicEl(t,n)}).remove(function(t){var e=u.__data.getItemGraphicEl(t);u.group.remove(e)}).execute(),h.eachItemGraphicEl(function(t,i){var n=h.getItemModel(i),o=n.getModel("label"),a=n.getModel("emphasis.label"),s=h.getItemVisual(i,"color");t.useStyle(r(n.getModel("itemStyle").getItemStyle(),{fill:Rt(s,.4),stroke:s})),t.hoverStyle=n.getModel("emphasis.itemStyle").getItemStyle(),io(t.style,t.hoverStyle,o,a,{labelFetcher:e,labelDataIndex:i,defaultText:h.getName(i)||"",isRectText:!0,autoColor:s}),eo(t,{}),t.dataModel=e}),u.__data=h,u.group.silent=e.get("silent")||t.get("silent")}}),us(function(t){t.markArea=t.markArea||{}});hM.registerSubTypeDefaulter("timeline",function(){return"slider"}),cs({type:"timelineChange",event:"timelineChanged",update:"prepareAndUpdate"},function(t,e){var i=e.getComponent("timeline");return i&&null!=t.currentIndex&&(i.setCurrentIndex(t.currentIndex),!i.get("loop",!0)&&i.isIndexMax()&&i.setPlayState(!1)),e.resetOption("timeline"),r({currentIndex:i.option.currentIndex},t)}),cs({type:"timelinePlayChange",event:"timelinePlayChanged",update:"update"},function(t,e){var i=e.getComponent("timeline");i&&null!=t.playState&&i.setPlayState(t.playState)});var CN=hM.extend({type:"timeline",layoutMode:"box",defaultOption:{zlevel:0,z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},init:function(t,e,i){this._data,this._names,this.mergeDefaultAndTheme(t,i),this._initData()},mergeOption:function(t){CN.superApply(this,"mergeOption",arguments),this._initData()},setCurrentIndex:function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},getCurrentIndex:function(){return this.option.currentIndex},isIndexMax:function(){return this.getCurrentIndex()>=this._data.count()-1},setPlayState:function(t){this.option.autoPlay=!!t},getPlayState:function(){return!!this.option.autoPlay},_initData:function(){var t=this.option,e=t.data||[],n=t.axisType,o=this._names=[];if("category"===n){var a=[];d(e,function(t,e){var n,r=Ii(t);w(t)?(n=i(t)).value=e:n=e,a.push(n),_(r)||null!=r&&!isNaN(r)||(r=""),o.push(r+"")}),e=a}var r={category:"ordinal",time:"time"}[n]||"number";(this._data=new sT([{name:"value",type:r}],this)).initData(e,o)},getData:function(){return this._data},getCategories:function(){if("category"===this.get("axisType"))return this._names.slice()}});h(CN.extend({type:"timeline.slider",defaultOption:{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"emptyCircle",symbolSize:10,lineStyle:{show:!0,width:2,color:"#304654"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#304654"},itemStyle:{color:"#304654",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:13,color:"#c23531",borderWidth:5,borderColor:"rgba(194,53,49, 0.5)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:22,itemGap:12,position:"left",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",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",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",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",color:"#304654",borderColor:"#304654",borderWidth:1},emphasis:{label:{show:!0,color:"#c23531"},itemStyle:{color:"#c23531"},controlStyle:{color:"#c23531",borderColor:"#c23531",borderWidth:2}},data:[]}}),XM);var LN=$M.extend({type:"timeline"}),kN=function(t,e,i,n){qT.call(this,t,e,i),this.type=n||"value",this.model=null};kN.prototype={constructor:kN,getLabelModel:function(){return this.model.getModel("label")},isHorizontal:function(){return"horizontal"===this.model.get("orient")}},u(kN,qT);var PN=m,NN=d,ON=Math.PI;LN.extend({type:"timeline.slider",init:function(t,e){this.api=e,this._axis,this._viewRect,this._timer,this._currentPointer,this._mainGroup,this._labelGroup},render:function(t,e,i,n){if(this.model=t,this.api=i,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var o=this._layout(t,i),a=this._createGroup("mainGroup"),r=this._createGroup("labelGroup"),s=this._axis=this._createAxis(o,t);t.formatTooltip=function(t){return Zo(s.scale.getLabel(t))},NN(["AxisLine","AxisTick","Control","CurrentPointer"],function(e){this["_render"+e](o,a,s,t)},this),this._renderAxisLabel(o,r,s,t),this._position(o,t)}this._doPlayStop()},remove:function(){this._clearTimer(),this.group.removeAll()},dispose:function(){this._clearTimer()},_layout:function(t,e){var i=t.get("label.position"),n=t.get("orient"),o=Yy(t,e);null==i||"auto"===i?i="horizontal"===n?o.y+o.height/2=0||"+"===i?"left":"right"},r={horizontal:i>=0||"+"===i?"top":"bottom",vertical:"middle"},s={horizontal:0,vertical:ON/2},l="vertical"===n?o.height:o.width,u=t.getModel("controlStyle"),h=u.get("show",!0),c=h?u.get("itemSize"):0,d=h?u.get("itemGap"):0,f=c+d,p=t.get("label.rotate")||0;p=p*ON/180;var g,m,v,y,x=u.get("position",!0),_=h&&u.get("showPlayBtn",!0),w=h&&u.get("showPrevBtn",!0),b=h&&u.get("showNextBtn",!0),S=0,M=l;return"left"===x||"bottom"===x?(_&&(g=[0,0],S+=f),w&&(m=[S,0],S+=f),b&&(v=[M-c,0],M-=f)):(_&&(g=[M-c,0],M-=f),w&&(m=[0,0],S+=f),b&&(v=[M-c,0],M-=f)),y=[S,M],t.get("inverse")&&y.reverse(),{viewRect:o,mainLength:l,orient:n,rotation:s[n],labelRotation:p,labelPosOpt:i,labelAlign:t.get("label.align")||a[n],labelBaseline:t.get("label.verticalAlign")||t.get("label.baseline")||r[n],playPosition:g,prevBtnPosition:m,nextBtnPosition:v,axisExtent:y,controlSize:c,controlGap:d}},_position:function(t,e){function i(t){var e=t.position;t.origin=[c[0][0]-e[0],c[1][0]-e[1]]}function n(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function o(t,e,i,n,o){t[n]+=i[n][o]-e[n][o]}var a=this._mainGroup,r=this._labelGroup,s=t.viewRect;if("vertical"===t.orient){var l=st(),u=s.x,h=s.y+s.height;ct(l,l,[-u,-h]),dt(l,l,-ON/2),ct(l,l,[u,h]),(s=s.clone()).applyTransform(l)}var c=n(s),d=n(a.getBoundingRect()),f=n(r.getBoundingRect()),p=a.position,g=r.position;g[0]=p[0]=c[0][0];var m=t.labelPosOpt;if(isNaN(m))o(p,d,c,1,v="+"===m?0:1),o(g,f,c,1,1-v);else{var v=m>=0?0:1;o(p,d,c,1,v),g[1]=p[1]+m}a.attr("position",p),r.attr("position",g),a.rotation=r.rotation=t.rotation,i(a),i(r)},_createAxis:function(t,e){var i=e.getData(),n=e.get("axisType"),o=xl(e,n);o.getTicks=function(){return i.mapArray(["value"],function(t){return t})};var a=i.getDataExtent("value");o.setExtent(a[0],a[1]),o.niceTicks();var r=new kN("value",o,t.axisExtent,n);return r.model=e,r},_createGroup:function(t){var e=this["_"+t]=new sw;return this.group.add(e),e},_renderAxisLine:function(t,e,i,n){var o=i.getExtent();n.get("lineStyle.show")&&e.add(new MS({shape:{x1:o[0],y1:0,x2:o[1],y2:0},style:a({lineCap:"round"},n.getModel("lineStyle").getLineStyle()),silent:!0,z2:1}))},_renderAxisTick:function(t,e,i,n){var o=n.getData(),a=i.scale.getTicks();NN(a,function(t){var a=i.dataToCoord(t),r=o.getItemModel(t),s=r.getModel("itemStyle"),l=r.getModel("emphasis.itemStyle"),u={position:[a,0],onclick:PN(this._changeTimeline,this,t)},h=Ky(r,s,e,u);eo(h,l.getItemStyle()),r.get("tooltip")?(h.dataIndex=t,h.dataModel=n):h.dataIndex=h.dataModel=null},this)},_renderAxisLabel:function(t,e,i,n){if(i.getLabelModel().get("show")){var o=n.getData(),a=i.getViewLabels();NN(a,function(n){var a=n.tickValue,r=o.getItemModel(a),s=r.getModel("label"),l=r.getModel("emphasis.label"),u=i.dataToCoord(n.tickValue),h=new fS({position:[u,0],rotation:t.labelRotation-t.rotation,onclick:PN(this._changeTimeline,this,a),silent:!1});no(h.style,s,{text:n.formattedLabel,textAlign:t.labelAlign,textVerticalAlign:t.labelBaseline}),e.add(h),eo(h,no({},l))},this)}},_renderControl:function(t,e,i,n){function o(t,i,o,h){if(t){var c=qy(n,i,u,{position:t,origin:[a/2,0],rotation:h?-r:0,rectHover:!0,style:s,onclick:o});e.add(c),eo(c,l)}}var a=t.controlSize,r=t.rotation,s=n.getModel("controlStyle").getItemStyle(),l=n.getModel("emphasis.controlStyle").getItemStyle(),u=[0,-a/2,a,a],h=n.getPlayState(),c=n.get("inverse",!0);o(t.nextBtnPosition,"controlStyle.nextIcon",PN(this._changeTimeline,this,c?"-":"+")),o(t.prevBtnPosition,"controlStyle.prevIcon",PN(this._changeTimeline,this,c?"+":"-")),o(t.playPosition,"controlStyle."+(h?"stopIcon":"playIcon"),PN(this._handlePlayClick,this,!h),!0)},_renderCurrentPointer:function(t,e,i,n){var o=n.getData(),a=n.getCurrentIndex(),r=o.getItemModel(a).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=PN(s._handlePointerDrag,s),t.ondragend=PN(s._handlePointerDragend,s),$y(t,a,i,n,!0)},onUpdate:function(t){$y(t,a,i,n)}};this._currentPointer=Ky(r,r,this._mainGroup,{},this._currentPointer,l)},_handlePlayClick:function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},_handlePointerDrag:function(t,e,i){this._clearTimer(),this._pointerChangeTimeline([i.offsetX,i.offsetY])},_handlePointerDragend:function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},_pointerChangeTimeline:function(t,e){var i=this._toAxisCoord(t)[0],n=Co(this._axis.getExtent().slice());i>n[1]&&(i=n[1]),ii.getHeight()&&(n.textPosition="top",l=!0);var u=l?-5-o.height:s+8;a+o.width/2>i.getWidth()?(n.textPosition=["100%",u],n.textAlign="right"):a-o.width/2<0&&(n.textPosition=[0,u],n.textAlign="left")}})}},updateView:function(t,e,i,n){d(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,n)})},remove:function(t,e){d(this._features,function(i){i.remove&&i.remove(t,e)}),this.group.removeAll()},dispose:function(t,e){d(this._features,function(i){i.dispose&&i.dispose(t,e)})}});var RN=lI.toolbox.saveAsImage;Qy.defaultOption={show:!0,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",title:RN.title,type:"png",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:RN.lang.slice()},Qy.prototype.unusable=!a_.canvasSupported,Qy.prototype.onclick=function(t,e){var i=this.model,n=i.get("name")||t.get("title.0.text")||"echarts",o=document.createElement("a"),a=i.get("type",!0)||"png";o.download=n+"."+a,o.target="_blank";var r=e.getConnectedDataURL({type:a,backgroundColor:i.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",excludeComponents:i.get("excludeComponents"),pixelRatio:i.get("pixelRatio")});if(o.href=r,"function"!=typeof MouseEvent||a_.browser.ie||a_.browser.edge)if(window.navigator.msSaveOrOpenBlob){for(var s=atob(r.split(",")[1]),l=s.length,u=new Uint8Array(l);l--;)u[l]=s.charCodeAt(l);var h=new Blob([u]);window.navigator.msSaveOrOpenBlob(h,n+"."+a)}else{var c=i.get("lang"),d='';window.open().document.write(d)}else{var f=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1});o.dispatchEvent(f)}},Bv("saveAsImage",Qy);var zN=lI.toolbox.magicType;tx.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",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",tiled:"M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z"},title:i(zN.title),option:{},seriesIndex:{}};var BN=tx.prototype;BN.getIcons=function(){var t=this.model,e=t.get("icon"),i={};return d(t.get("type"),function(t){e[t]&&(i[t]=e[t])}),i};var VN={line:function(t,e,i,o){if("bar"===t)return n({id:e,type:"line",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.line")||{},!0)},bar:function(t,e,i,o){if("line"===t)return n({id:e,type:"bar",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},o.get("option.bar")||{},!0)},stack:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:"__ec_magicType_stack__"},o.get("option.stack")||{},!0)},tiled:function(t,e,i,o){if("line"===t||"bar"===t)return n({id:e,stack:""},o.get("option.tiled")||{},!0)}},GN=[["line","bar"],["stack","tiled"]];BN.onclick=function(t,e,i){var n=this.model,o=n.get("seriesIndex."+i);if(VN[i]){var a={series:[]};d(GN,function(t){l(t,i)>=0&&d(t,function(t){n.setIconStatus(t,"normal")})}),n.setIconStatus(i,"emphasis"),t.eachComponent({mainType:"series",query:null==o?null:{seriesIndex:o}},function(e){var o=e.subType,s=e.id,l=VN[i](o,s,e,n);l&&(r(l,e.option),a.series.push(l));var u=e.coordinateSystem;if(u&&"cartesian2d"===u.type&&("line"===i||"bar"===i)){var h=u.getAxesByScale("ordinal")[0];if(h){var c=h.dim+"Axis",d=t.queryComponents({mainType:c,index:e.get(name+"Index"),id:e.get(name+"Id")})[0].componentIndex;a[c]=a[c]||[];for(var f=0;f<=d;f++)a[c][d]=a[c][d]||{};a[c][d].boundaryGap="bar"===i}}}),e.dispatchAction({type:"changeMagicType",currentType:i,newOption:a})}},cs({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),Bv("magicType",tx);var WN=lI.toolbox.dataView,FN=new Array(60).join("-"),HN="\t",ZN=new RegExp("["+HN+"]+","g");hx.defaultOption={show:!0,readOnly:!1,optionToContent:null,contentToOption:null,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",title:i(WN.title),lang:i(WN.lang),backgroundColor:"#fff",textColor:"#000",textareaColor:"#fff",textareaBorderColor:"#333",buttonColor:"#c23531",buttonTextColor:"#fff"},hx.prototype.onclick=function(t,e){function i(){n.removeChild(a),x._dom=null}var n=e.getDom(),o=this.model;this._dom&&n.removeChild(this._dom);var a=document.createElement("div");a.style.cssText="position:absolute;left:5px;top:5px;bottom:5px;right:5px;",a.style.backgroundColor=o.get("backgroundColor")||"#fff";var r=document.createElement("h4"),s=o.get("lang")||[];r.innerHTML=s[0]||o.get("title"),r.style.cssText="margin: 10px 20px;",r.style.color=o.get("textColor");var l=document.createElement("div"),u=document.createElement("textarea");l.style.cssText="display:block;width:100%;overflow:auto;";var h=o.get("optionToContent"),c=o.get("contentToOption"),d=ox(t);if("function"==typeof h){var f=h(e.getOption());"string"==typeof f?l.innerHTML=f:M(f)&&l.appendChild(f)}else l.appendChild(u),u.readOnly=o.get("readOnly"),u.style.cssText="width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;",u.style.color=o.get("textColor"),u.style.borderColor=o.get("textareaBorderColor"),u.style.backgroundColor=o.get("textareaColor"),u.value=d.value;var p=d.meta,g=document.createElement("div");g.style.cssText="position:absolute;bottom:0;left:0;right:0;";var m="float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px",v=document.createElement("div"),y=document.createElement("div");m+=";background-color:"+o.get("buttonColor"),m+=";color:"+o.get("buttonTextColor");var x=this;ui(v,"click",i),ui(y,"click",function(){var t;try{t="function"==typeof c?c(l,e.getOption()):ux(u.value,p)}catch(t){throw i(),new Error("Data view format error "+t)}t&&e.dispatchAction({type:"changeDataView",newOption:t}),i()}),v.innerHTML=s[1],y.innerHTML=s[2],y.style.cssText=m,v.style.cssText=m,!o.get("readOnly")&&g.appendChild(y),g.appendChild(v),ui(u,"keydown",function(t){if(9===(t.keyCode||t.which)){var e=this.value,i=this.selectionStart,n=this.selectionEnd;this.value=e.substring(0,i)+HN+e.substring(n),this.selectionStart=this.selectionEnd=i+1,zw(t)}}),a.appendChild(r),a.appendChild(l),a.appendChild(g),l.style.height=n.clientHeight-80+"px",n.appendChild(a),this._dom=a},hx.prototype.remove=function(t,e){this._dom&&e.getDom().removeChild(this._dom)},hx.prototype.dispose=function(t,e){this.remove(t,e)},Bv("dataView",hx),cs({type:"changeDataView",event:"dataViewChanged",update:"prepareAndUpdate"},function(t,e){var i=[];d(t.newOption.series,function(t){var n=e.getSeriesByName(t.name)[0];if(n){var o=n.get("data");i.push({name:t.name,data:cx(t.data,o)})}else i.push(a({type:"scatter"},t))}),e.mergeOption(r({series:i},t.newOption))});var UN=d,XN="\0_ec_hist_store";PP.extend({type:"dataZoom.select"}),NP.extend({type:"dataZoom.select"});var jN=lI.toolbox.dataZoom,YN=d,qN="\0_ec_\0toolbox-dataZoom_";vx.defaultOption={show:!0,icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:i(jN.title)};var KN=vx.prototype;KN.render=function(t,e,i,n){this.model=t,this.ecModel=e,this.api=i,_x(t,e,this,n,i),xx(t,e)},KN.onclick=function(t,e,i){$N[i].call(this)},KN.remove=function(t,e){this._brushController.unmount()},KN.dispose=function(t,e){this._brushController.dispose()};var $N={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(fx(this.ecModel))}};KN._onBrush=function(t,e){function i(t,e,i){var r=e.getAxis(t),s=r.model,l=n(t,s,a),u=l.findRepresentativeAxisProxy(s).getMinMaxSpan();null==u.minValueSpan&&null==u.maxValueSpan||(i=PC(0,i.slice(),r.scale.getExtent(),0,u.minValueSpan,u.maxValueSpan)),l&&(o[l.id]={dataZoomId:l.id,startValue:i[0],endValue:i[1]})}function n(t,e,i){var n;return i.eachComponent({mainType:"dataZoom",subType:"select"},function(i){i.getAxisModel(t,e.componentIndex)&&(n=i)}),n}if(e.isEnd&&t.length){var o={},a=this.ecModel;this._brushController.updateCovers([]),new bv(yx(this.model.option),a,{include:["grid"]}).matchOutputRanges(t,a,function(t,e,n){if("cartesian2d"===n.type){var o=t.brushType;"rect"===o?(i("x",n,e[0]),i("y",n,e[1])):i({lineX:"x",lineY:"y"}[o],n,e)}}),dx(a,o),this._dispatchZoomAction(o)}},KN._dispatchZoomAction=function(t){var e=[];YN(t,function(t,n){e.push(i(t))}),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},Bv("dataZoom",vx),us(function(t){function e(t,e){if(e){var o=t+"Index",a=e[o];null==a||"all"==a||y(a)||(a=!1===a||"none"===a?[]:[a]),i(t,function(e,i){if(null==a||"all"==a||-1!==l(a,i)){var r={type:"select",$fromToolbox:!0,id:qN+t+i};r[o]=i,n.push(r)}})}}function i(e,i){var n=t[e];y(n)||(n=n?[n]:[]),YN(n,i)}if(t){var n=t.dataZoom||(t.dataZoom=[]);y(n)||(t.dataZoom=n=[n]);var o=t.toolbox;if(o&&(y(o)&&(o=o[0]),o&&o.feature)){var a=o.feature.dataZoom;e("xAxis",a),e("yAxis",a)}}});var JN=lI.toolbox.restore;bx.defaultOption={show:!0,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",title:JN.title},bx.prototype.onclick=function(t,e,i){px(t),e.dispatchAction({type:"restore",from:this.uid})},Bv("restore",bx),cs({type:"restore",event:"restore",update:"prepareAndUpdate"},function(t,e){e.resetOption("recreate")});var QN,tO="urn:schemas-microsoft-com:vml",eO="undefined"==typeof window?null:window,iO=!1,nO=eO&&eO.document;if(nO&&!a_.canvasSupported)try{!nO.namespaces.zrvml&&nO.namespaces.add("zrvml",tO),QN=function(t){return nO.createElement("')}}catch(t){QN=function(t){return nO.createElement("<"+t+' xmlns="'+tO+'" class="zrvml">')}}var oO=Hb.CMD,aO=Math.round,rO=Math.sqrt,sO=Math.abs,lO=Math.cos,uO=Math.sin,hO=Math.max;if(!a_.canvasSupported){var cO=21600,dO=cO/2,fO=function(t){t.style.cssText="position:absolute;left:0;top:0;width:1px;height:1px;",t.coordsize=cO+","+cO,t.coordorigin="0,0"},pO=function(t){return String(t).replace(/&/g,"&").replace(/"/g,""")},gO=function(t,e,i){return"rgb("+[t,e,i].join(",")+")"},mO=function(t,e){e&&t&&e.parentNode!==t&&t.appendChild(e)},vO=function(t,e){e&&t&&e.parentNode===t&&t.removeChild(e)},yO=function(t,e,i){return 1e5*(parseFloat(t)||0)+1e3*(parseFloat(e)||0)+i},xO=function(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t},_O=function(t,e,i){var n=At(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=gO(n[0],n[1],n[2]),t.opacity=i*n[3])},wO=function(t){var e=At(t);return[gO(e[0],e[1],e[2]),e[3]]},bO=function(t,e,i){var n=e.fill;if(null!=n)if(n instanceof CS){var o,a=0,r=[0,0],s=0,l=1,u=i.getBoundingRect(),h=u.width,c=u.height;if("linear"===n.type){o="gradient";var d=i.transform,f=[n.x*h,n.y*c],p=[n.x2*h,n.y2*c];d&&(Q(f,f,d),Q(p,p,d));var g=p[0]-f[0],m=p[1]-f[1];(a=180*Math.atan2(g,m)/Math.PI)<0&&(a+=360),a<1e-6&&(a=0)}else{o="gradientradial";var f=[n.x*h,n.y*c],d=i.transform,v=i.scale,y=h,x=c;r=[(f[0]-u.x)/y,(f[1]-u.y)/x],d&&Q(f,f,d),y/=v[0]*cO,x/=v[1]*cO;var _=hO(y,x);s=0/_,l=2*n.r/_-s}var w=n.colorStops.slice();w.sort(function(t,e){return t.offset-e.offset});for(var b=w.length,S=[],M=[],I=0;I=2){var A=S[0][0],C=S[1][0],L=S[0][1]*e.opacity,k=S[1][1]*e.opacity;t.type=o,t.method="none",t.focus="100%",t.angle=a,t.color=A,t.color2=C,t.colors=M.join(","),t.opacity=k,t.opacity2=L}"radial"===o&&(t.focusposition=r.join(","))}else _O(t,n,e.opacity)},SO=function(t,e){null!=e.lineDash&&(t.dashstyle=e.lineDash.join(" ")),null==e.stroke||e.stroke instanceof CS||_O(t,e.stroke,e.opacity)},MO=function(t,e,i,n){var o="fill"==e,a=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(o||!o&&i.lineWidth)?(t[o?"filled":"stroked"]="true",i[e]instanceof CS&&vO(t,a),a||(a=Sx(e)),o?bO(a,i,n):SO(a,i),mO(t,a)):(t[o?"filled":"stroked"]="false",vO(t,a))},IO=[[],[],[]],TO=function(t,e){var i,n,o,a,r,s,l=oO.M,u=oO.C,h=oO.L,c=oO.A,d=oO.Q,f=[],p=t.data,g=t.len();for(a=0;a.01?N&&(O+=.0125):Math.abs(E-A)<1e-4?N&&OD?x-=.0125:x+=.0125:N&&EA?y+=.0125:y-=.0125),f.push(R,aO(((D-C)*M+b)*cO-dO),",",aO(((A-L)*I+S)*cO-dO),",",aO(((D+C)*M+b)*cO-dO),",",aO(((A+L)*I+S)*cO-dO),",",aO((O*M+b)*cO-dO),",",aO((E*I+S)*cO-dO),",",aO((y*M+b)*cO-dO),",",aO((x*I+S)*cO-dO)),r=y,s=x;break;case oO.R:var z=IO[0],B=IO[1];z[0]=p[a++],z[1]=p[a++],B[0]=z[0]+p[a++],B[1]=z[1]+p[a++],e&&(Q(z,z,e),Q(B,B,e)),z[0]=aO(z[0]*cO-dO),B[0]=aO(B[0]*cO-dO),z[1]=aO(z[1]*cO-dO),B[1]=aO(B[1]*cO-dO),f.push(" m ",z[0],",",z[1]," l ",B[0],",",z[1]," l ",B[0],",",B[1]," l ",z[0],",",B[1]);break;case oO.Z:f.push(" x ")}if(i>0){f.push(n);for(var V=0;V100&&(LO=0,CO={});var i,n=kO.style;try{n.font=t,i=n.fontFamily.split(",")[0]}catch(t){}e={style:n.fontStyle||"normal",variant:n.fontVariant||"normal",weight:n.fontWeight||"normal",size:0|parseFloat(n.fontSize||12),family:i||"Microsoft YaHei"},CO[t]=e,LO++}return e};!function(t,e){Dw[t]=e}("measureText",function(t,e){var i=nO;AO||((AO=i.createElement("div")).style.cssText="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;",nO.body.appendChild(AO));try{AO.style.font=e}catch(t){}return AO.innerHTML="",AO.appendChild(i.createTextNode(t)),{width:AO.offsetWidth}});for(var NO=new $t,OO=[kw,$e,Je,In,fS],EO=0;EO=o&&u+1>=a){for(var h=[],c=0;c=o&&c+1>=a)return Gx(0,s.components);l[i]=s}else l[i]=void 0}r++}();if(d)return d}},pushComponent:function(t,e,i){var n=t[t.length-1];n&&n.added===e&&n.removed===i?t[t.length-1]={count:n.count+1,added:e,removed:i}:t.push({count:1,added:e,removed:i})},extractCommon:function(t,e,i,n){for(var o=e.length,a=i.length,r=t.newPos,s=r-n,l=0;r+1=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},Fx.prototype.update=function(t,e){if(t){var i=this.getDefs(!1);if(t[this._domName]&&i.contains(t[this._domName]))"function"==typeof e&&e(t);else{var n=this.add(t);n&&(t[this._domName]=n)}}},Fx.prototype.addDom=function(t){this.getDefs(!0).appendChild(t)},Fx.prototype.removeDom=function(t){var e=this.getDefs(!1);e&&t[this._domName]&&(e.removeChild(t[this._domName]),t[this._domName]=null)},Fx.prototype.getDoms=function(){var t=this.getDefs(!1);if(!t)return[];var e=[];return d(this._tagNames,function(i){var n=t.getElementsByTagName(i);e=e.concat([].slice.call(n))}),e},Fx.prototype.markAllUnused=function(){var t=this;d(this.getDoms(),function(e){e[t._markLabel]="0"})},Fx.prototype.markUsed=function(t){t&&(t[this._markLabel]="1")},Fx.prototype.removeUnused=function(){var t=this.getDefs(!1);if(t){var e=this;d(this.getDoms(),function(i){"1"!==i[e._markLabel]&&t.removeChild(i)})}},Fx.prototype.getSvgProxy=function(t){return t instanceof In?YO:t instanceof Je?qO:t instanceof fS?KO:YO},Fx.prototype.getTextSvgElement=function(t){return t.__textSvgEl},Fx.prototype.getSvgElement=function(t){return t.__svgEl},u(Hx,Fx),Hx.prototype.addWithoutUpdate=function(t,e){if(e&&e.style){var i=this;d(["fill","stroke"],function(n){if(e.style[n]&&("linear"===e.style[n].type||"radial"===e.style[n].type)){var o,a=e.style[n],r=i.getDefs(!0);a._dom?(o=a._dom,r.contains(a._dom)||i.addDom(o)):o=i.add(a),i.markUsed(e);var s=o.getAttribute("id");t.setAttribute(n,"url(#"+s+")")}})}},Hx.prototype.add=function(t){var e;if("linear"===t.type)e=this.createElement("linearGradient");else{if("radial"!==t.type)return ew("Illegal gradient type."),null;e=this.createElement("radialGradient")}return t.id=t.id||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-gradient-"+t.id),this.updateDom(t,e),this.addDom(e),e},Hx.prototype.update=function(t){var e=this;Fx.prototype.update.call(this,t,function(){var i=t.type,n=t._dom.tagName;"linear"===i&&"linearGradient"===n||"radial"===i&&"radialGradient"===n?e.updateDom(t,t._dom):(e.removeDom(t),e.add(t))})},Hx.prototype.updateDom=function(t,e){if("linear"===t.type)e.setAttribute("x1",t.x),e.setAttribute("y1",t.y),e.setAttribute("x2",t.x2),e.setAttribute("y2",t.y2);else{if("radial"!==t.type)return void ew("Illegal gradient type.");e.setAttribute("cx",t.x),e.setAttribute("cy",t.y),e.setAttribute("r",t.r)}t.global?e.setAttribute("gradientUnits","userSpaceOnUse"):e.setAttribute("gradientUnits","objectBoundingBox"),e.innerHTML="";for(var i=t.colorStops,n=0,o=i.length;n0){var n,o,a=this.getDefs(!0),r=e[0],s=i?"_textDom":"_dom";r[s]?(o=r[s].getAttribute("id"),n=r[s],a.contains(n)||a.appendChild(n)):(o="zr"+this._zrId+"-clip-"+this.nextId,++this.nextId,(n=this.createElement("clipPath")).setAttribute("id",o),a.appendChild(n),r[s]=n);var l=this.getSvgProxy(r);if(r.transform&&r.parent.invTransform&&!i){var u=Array.prototype.slice.call(r.transform);ht(r.transform,r.parent.invTransform,r.transform),l.brush(r),r.transform=u}else l.brush(r);var h=this.getSvgElement(r);n.innerHTML="",n.appendChild(h.cloneNode()),t.setAttribute("clip-path","url(#"+o+")"),e.length>1&&this.updateDom(n,e.slice(1),i)}else t&&t.setAttribute("clip-path","none")},Zx.prototype.markUsed=function(t){var e=this;t.__clipPaths&&t.__clipPaths.length>0&&d(t.__clipPaths,function(t){t._dom&&Fx.prototype.markUsed.call(e,t._dom),t._textDom&&Fx.prototype.markUsed.call(e,t._textDom)})},u(Ux,Fx),Ux.prototype.addWithoutUpdate=function(t,e){if(e&&Xx(e.style)){var i,n=e.style;n._shadowDom?(i=n._shadowDom,this.getDefs(!0).contains(n._shadowDom)||this.addDom(i)):i=this.add(e),this.markUsed(e);var o=i.getAttribute("id");t.style.filter="url(#"+o+")"}},Ux.prototype.add=function(t){var e=this.createElement("filter"),i=t.style;return i._shadowDomId=i._shadowDomId||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-shadow-"+i._shadowDomId),this.updateDom(t,e),this.addDom(e),e},Ux.prototype.update=function(t,e){var i=e.style;if(Xx(i)){var n=this;Fx.prototype.update.call(this,e,function(t){n.updateDom(e,t._shadowDom)})}else this.remove(t,i)},Ux.prototype.remove=function(t,e){null!=e._shadowDomId&&(this.removeDom(e),t.style.filter="")},Ux.prototype.updateDom=function(t,e){var i=e.getElementsByTagName("feDropShadow");i=0===i.length?this.createElement("feDropShadow"):i[0];var n,o,a,r,s=t.style,l=t.scale?t.scale[0]||1:1,u=t.scale?t.scale[1]||1:1;if(s.shadowBlur||s.shadowOffsetX||s.shadowOffsetY)n=s.shadowOffsetX||0,o=s.shadowOffsetY||0,a=s.shadowBlur,r=s.shadowColor;else{if(!s.textShadowBlur)return void this.removeDom(e,s);n=s.textShadowOffsetX||0,o=s.textShadowOffsetY||0,a=s.textShadowBlur,r=s.textShadowColor}i.setAttribute("dx",n/l),i.setAttribute("dy",o/u),i.setAttribute("flood-color",r);var h=a/2/l+" "+a/2/u;i.setAttribute("stdDeviation",h),e.setAttribute("x","-100%"),e.setAttribute("y","-100%"),e.setAttribute("width",Math.ceil(a/2*200)+"%"),e.setAttribute("height",Math.ceil(a/2*200)+"%"),e.appendChild(i),s._shadowDom=e},Ux.prototype.markUsed=function(t){var e=t.style;e&&e._shadowDom&&Fx.prototype.markUsed.call(this,e._shadowDom)};var eE=function(t,e,i,n){this.root=t,this.storage=e,this._opts=i=a({},i||{});var o=Ax("svg");o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("version","1.1"),o.setAttribute("baseProfile","full"),o.style.cssText="user-select:none;position:absolute;left:0;top:0;",this.gradientManager=new Hx(n,o),this.clipPathManager=new Zx(n,o),this.shadowManager=new Ux(n,o);var r=document.createElement("div");r.style.cssText="overflow:hidden;position:relative",this._svgRoot=o,this._viewport=r,t.appendChild(r),r.appendChild(o),this.resize(i.width,i.height),this._visibleList=[]};eE.prototype={constructor:eE,getType:function(){return"svg"},getViewportRoot:function(){return this._viewport},getViewportRootOffset:function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},refresh:function(){var t=this.storage.getDisplayList(!0);this._paintList(t)},setBackgroundColor:function(t){this._viewport.style.background=t},_paintList:function(t){this.gradientManager.markAllUnused(),this.clipPathManager.markAllUnused(),this.shadowManager.markAllUnused();var e,i=this._svgRoot,n=this._visibleList,o=t.length,a=[];for(e=0;e=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},resize:function(t,e){var i=this._viewport;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n.height=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!==t||this._height!==e){this._width=t,this._height=e;var o=i.style;o.width=t+"px",o.height=e+"px";var a=this._svgRoot;a.setAttribute("width",t),a.setAttribute("height",e)}},getWidth:function(){return this._width},getHeight:function(){return this._height},_getSize:function(t){var e=this._opts,i=["width","height"][t],n=["clientWidth","clientHeight"][t],o=["paddingLeft","paddingTop"][t],a=["paddingRight","paddingBottom"][t];if(null!=e[i]&&"auto"!==e[i])return parseFloat(e[i]);var r=this.root,s=document.defaultView.getComputedStyle(r);return(r[n]||jx(s[i])||jx(r.style[i]))-(jx(s[o])||0)-(jx(s[a])||0)|0},dispose:function(){this.root.innerHTML="",this._svgRoot=this._viewport=this.storage=null},clear:function(){this._viewport&&this.root.removeChild(this._viewport)},pathToDataUrl:function(){return this.refresh(),"data:image/svg+xml;charset=UTF-8,"+this._svgRoot.outerHTML}},d(["getLayer","insertLayer","eachLayer","eachBuiltinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","toDataURL","pathToImage"],function(t){eE.prototype[t]=e_(t)}),wi("svg",eE),t.version="4.1.0",t.dependencies=TI,t.PRIORITY=LI,t.init=function(t,e,i){var n=ss(t);if(n)return n;var o=new Gr(t,e,i);return o.id="ec_"+jI++,UI[o.id]=o,Ri(t,qI,o.id),as(o),o},t.connect=function(t){if(y(t)){var e=t;t=null,bI(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+YI++,bI(e,function(e){e.group=t})}return XI[t]=!0,t},t.disConnect=rs,t.disconnect=$I,t.dispose=function(t){"string"==typeof t?t=UI[t]:t instanceof Gr||(t=ss(t)),t instanceof Gr&&!t.isDisposed()&&t.dispose()},t.getInstanceByDom=ss,t.getInstanceById=function(t){return UI[t]},t.registerTheme=ls,t.registerPreprocessor=us,t.registerProcessor=hs,t.registerPostUpdate=function(t){WI.push(t)},t.registerAction=cs,t.registerCoordinateSystem=ds,t.getCoordinateSystemDimensions=function(t){var e=Ca.get(t);if(e)return e.getDimensionsInfo?e.getDimensionsInfo():e.dimensions.slice()},t.registerLayout=fs,t.registerVisual=ps,t.registerLoading=ms,t.extendComponentModel=vs,t.extendComponentView=ys,t.extendSeriesModel=xs,t.extendChartView=_s,t.setCanvasCreator=function(t){e("createCanvas",t)},t.registerMap=function(t,e,i){e.geoJson&&!e.features&&(i=e.specialAreas,e=e.geoJson),"string"==typeof e&&(e="undefined"!=typeof JSON&&JSON.parse?JSON.parse(e):new Function("return ("+e+");")()),KI[t]={geoJson:e,specialAreas:i}},t.getMap=ws,t.dataTool=JI,t.zrender=$w,t.graphic=BS,t.number=qS,t.format=nM,t.throttle=_r,t.helper=ZT,t.matrix=P_,t.vector=I_,t.color=q_,t.parseGeoJSON=XT,t.parseGeoJson=KT,t.util=$T,t.List=sT,t.Model=wo,t.Axis=qT,t.env=a_}); diff --git a/src/main/resources/static/js/echartsjs.rar b/src/main/resources/static/js/echartsjs.rar new file mode 100644 index 0000000000000000000000000000000000000000..51a62b5f821333d9fdd1c6cf9ed8b4b76a07c3b9 GIT binary patch literal 908887 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 >tZ{#!_I8Igo7YgZJ^*%rbF~-ck0_FLJ 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�+{Y<(kzahq)M2axr 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%0DLo7ZE{2;#%WY)JR^FS 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 c3x1~^XCV`7zQ&x~Z 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

>zVF@kyD#+)%owXwj9m#qV)m(pB`gI`W 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

pY~jXMtqQ>3Cl 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%0AB*HXl6;ZZM-4_2a1w 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 + + + + diff --git a/src/main/resources/static/resources-room.html b/src/main/resources/static/resources-room.html new file mode 100644 index 0000000..252718e --- /dev/null +++ b/src/main/resources/static/resources-room.html @@ -0,0 +1,197 @@ + + + + + 选择资源室进入 + + + + + + + 离开 +
+
+
+
+ + + + + diff --git a/src/main/resources/static/room.html b/src/main/resources/static/room.html new file mode 100644 index 0000000..b77fa71 --- /dev/null +++ b/src/main/resources/static/room.html @@ -0,0 +1,291 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/sections.html b/src/main/resources/static/sections.html new file mode 100644 index 0000000..2899834 --- /dev/null +++ b/src/main/resources/static/sections.html @@ -0,0 +1,278 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/select.html b/src/main/resources/static/select.html new file mode 100644 index 0000000..64382a1 --- /dev/null +++ b/src/main/resources/static/select.html @@ -0,0 +1,40 @@ + + + + + 请选择资源室类型 + + + + + + + 离开 +
+

选择要进入的资源室类型

+ + +
+ + + diff --git a/src/main/resources/static/statistics.html b/src/main/resources/static/statistics.html new file mode 100644 index 0000000..0432fd5 --- /dev/null +++ b/src/main/resources/static/statistics.html @@ -0,0 +1,185 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ +
+ + + + + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
\ No newline at end of file diff --git a/src/main/resources/static/students.html b/src/main/resources/static/students.html new file mode 100644 index 0000000..3b7f9ff --- /dev/null +++ b/src/main/resources/static/students.html @@ -0,0 +1,578 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/system.html b/src/main/resources/static/system.html new file mode 100644 index 0000000..59fbb14 --- /dev/null +++ b/src/main/resources/static/system.html @@ -0,0 +1,278 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/teacher.html b/src/main/resources/static/teacher.html new file mode 100644 index 0000000..3adc783 --- /dev/null +++ b/src/main/resources/static/teacher.html @@ -0,0 +1,523 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/user.json b/src/main/resources/static/user.json new file mode 100644 index 0000000..6dd2a8a --- /dev/null +++ b/src/main/resources/static/user.json @@ -0,0 +1,127 @@ +{ + "code": 0 + ,"msg": "" + ,"count": 3000000 + ,"data": [{ + "id": "10001" + ,"username": "杜甫" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "点击此处,显示更多。当内容超出时,点击单元格会自动显示更多内容。" + ,"experience": "116" + ,"ip": "192.168.0.8" + ,"logins": "108" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10002" + ,"username": "李白" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "君不见,黄河之水天上来,奔流到海不复回。 君不见,高堂明镜悲白发,朝如青丝暮成雪。 人生得意须尽欢,莫使金樽空对月。 天生我材必有用,千金散尽还复来。 烹羊宰牛且为乐,会须一饮三百杯。 岑夫子,丹丘生,将进酒,杯莫停。 与君歌一曲,请君为我倾耳听。(倾耳听 一作:侧耳听) 钟鼓馔玉不足贵,但愿长醉不复醒。(不足贵 一作:何足贵;不复醒 一作:不愿醒/不用醒) 古来圣贤皆寂寞,惟有饮者留其名。(古来 一作:自古;惟 通:唯) 陈王昔时宴平乐,斗酒十千恣欢谑。 主人何为言少钱,径须沽取对君酌。 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。" + ,"experience": "12" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"LAY_CHECKED": true + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10003" + ,"username": "王勃" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "65" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10004" + ,"username": "李清照" + ,"email": "xianxin@layui.com" + ,"sex": "女" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "666" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10005" + ,"username": "冰心" + ,"email": "xianxin@layui.com" + ,"sex": "女" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "86" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10006" + ,"username": "贤心" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "12" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10007" + ,"username": "贤心" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "16" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }, { + "id": "10008" + ,"username": "贤心" + ,"email": "xianxin@layui.com" + ,"sex": "男" + ,"city": "浙江杭州" + ,"sign": "人生恰似一场修行" + ,"experience": "106" + ,"ip": "192.168.0.8" + ,"logins": "106" + ,"joinTime": "2016-10-14" + ,"dw_xinzhi":{ + "id":90 + ,"titel":"小学" + } + }] +} \ No newline at end of file diff --git a/src/main/resources/static/welcome.html b/src/main/resources/static/welcome.html new file mode 100644 index 0000000..6d97e6f --- /dev/null +++ b/src/main/resources/static/welcome.html @@ -0,0 +1,400 @@ + + + + + 欢迎页面-X-admin2.2 + + + + + + + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+
读书室使用统计量
+
+
+ +
+
+
+
+
+
机房使用统计量
+
+
+ +
+
+
+
+
+
用户来源
+
+
+ +
+
+
+
+
+
硬盘使用量
+
+
+ +
+
+
+
+
+ + + + + + + \ No newline at end of file -- Gitee

mMsp83~hevNjP&IDU-tVw0;_K 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 E01E`Ue*gdg literal 0 HcmV?d00001 diff --git a/src/main/resources/static/js/global.js b/src/main/resources/static/js/global.js new file mode 100644 index 0000000..c969d29 --- /dev/null +++ b/src/main/resources/static/js/global.js @@ -0,0 +1,6 @@ +const globalData = { + server:"http://localhost:8080/", + token:localStorage.token +}; + + \ No newline at end of file diff --git a/src/main/resources/static/js/jquery.min.js b/src/main/resources/static/js/jquery.min.js new file mode 100644 index 0000000..644d35e --- /dev/null +++ b/src/main/resources/static/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + + + + +

;%yxGu-A_iwKo%L%YuPOdjA8W_A-eaGDq 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�G2?3#giNCUg*Uyw2)J!Fke1cTH@f|jUd^5X2{fa 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]da^D3PIR@JtQ+@KQslB*@7v-yEvjK zp68GPeo~EhvLuQkIWBk;VP*3$-DnX<0zN)&_0G6yooEZ_!q%VO zj=tJ39=$RpKe%CQ!SZ&y_&fdI)!_ZTZuev&;P8Ci?(gjFb~`< z?Fc=n71)D$AYU)eSzK-)Fri=IEo5H-m;yM77a(Or$WS)BU?KJXLHl*SKG1i3A3>sD zs6HLSL%&d={a{EyZv$sv=lMhY50}s0`MbUFNTQbrA_$j!5st7#0`@V8hA6%P+?JjW z_yj&*lmj4i5BIb9{9thb7q9*Ip02k-;+`~=1jKQGXdU@3r#A1HkL z|1fmBMeywZKV(PHMZSzjL7V{-`Mz;74{!jzZr@w=icHXwgAhilgo4I`NG;yt5_|9b z{}>BF+yg)gU$48}>=LhlW4-$TcmQ_59sqYGA^F3kVE{qEQ#5!$prj&UADAG${?RE| z$R78*-#F|T_e2+S_JV~7)7BI3V3kw5+%)D37zb~lf#Mn!4<&X0zwHjV_JMc%hQQvi zs8|cV;1c{0GYTXOB=9{p5GW*{@{iUDR0nb}cSsTYdq9k6{vdx5fAx@5kil~jut430H-i0uH3XAW?!U;2`c}V7M~_(B7pIrRZKu=S z=+Cw;@yLwcEi-}hq1XUnlJ|#tiv}e-F zZ2;W+KdT3qJ`%cAXEWwu4B9lp3$mKaHLsqMrH@ELe&(S~r_G7dGZspa}(ca>q>}5Z? zjIl;MpHd?u{)dbXQ&^9rdX~r-1D7@;NtI&qB4PX1rgb zD-;l|icAWvGD7P}T}3S&%f*-9RCCnv00WZvsq!ATxl=gyMOy1{0Sk3SXS?PY@5t3v z^D?%EN`hgjG#tkjw*y3a8LLz7Z~&71CkNpy;)s02Br>~-^D;s1B4nT0R}Kv)aG6F`0&8up!BSP- zznHX|U3R6LVlPJq=Q%^yjTcxg__2u;*Gd)G^a2VgnGOT)o8Mqw+|FSUoIk4Xo6JYqZyzi5kvWz3wlMBBiR_t0lo;qoX|2Ovk!~EmV zxexFDzx87OkNUsg`~TnnWIdLLMu@Kh24z-{sw9=K${ux^3p!hBF_?6!Klg`8`r70y zohN@8(s<)~D#GbvwM7C`eGZO8)DQixKT-Mg1LN*~AcyJwSg?b&5w}nJ0)b0!ks)!~ z3t4Hybj?Qchuqz8=of`Ia+>;*$isxw>GspDFbUq1$$;BZJXxgtslY6J+#Kal$VNaRlpnE%y@Ndy++b7NP{Xes<-uimM7@^-AgJf02 z`G3vN$9M7G{Ct0p)VBuz?g>)w*$+^o1J??t{k7fU9z;d(`bDpbW*?4(jS{Avf^@;J z00<~IE*F(|P%NbbqqxPxT(xWSfHB*MJzKg+ecm9U09S8Gu9d@hV%^jfd;pDT3O$M8 z+(^O4(BfNOknCoIr!MOX%{%I~V8k`}3-XD3wQ-t%MW|9U-gwNH{Nw*Pq7oNm6RKpc z!puRbnJx&*@mjW>NU{a=2ryIu?~navfg>FB4E7bJ}cet2VD!#mL&%NQvc-q$h`_No6`-3P?NqU$< z$OH|i#Gm?GPlxn)g0WM>d9g421-p?jCY)Q|bG~LzM^$4==?5;nG=}^U^;6Q41t)EI z{drRST^|KKG4!Cc$|Ua7SY$EXm4pKdV24T9`WV7lw_PUovauyVU*LRu;o|dcoxY{i z=bj=H*Wch6jndt9uEJbb?IF0ey63wZ0pPQLODk*p{%^gy1G~=7i2dPoRC)=)XX$Bz z^IxPUBD!J)@yg}$YyIn_YYRXj%=a?^a9VCZ_d)7mEo*J_{x642lQ+cpBKMT@6vxxN zB|Tk9B}4ftRX?Bbw5=W(61PqcOK>p$KXNa9@Ng>#O!%<38bKsgCFSY1cc9SKRl@+G z{Pra5_2Jov(Jr#tzs2+TI_T`W;j}IO2~XXlg~4nh8=49SvkNvK~^a&OVcxIObtV&Rzoj=q1%c5BEDvxFUc z7FrR=8Atkp952v9$A#HXqua7=?UIc6bTnfw0lQ?}LtMd+uO+`Ac!BXuYVz6;_xJ)Q z3Ug-`OG^<@W#7MSGMok3smGmO0AMX{97No1*lQhXoT^?Nvk~pq>=N*SA6&27F3u0+ z3FTF8{_g6c+qo_y2JTwEzpYPSUQ4-;*Osp@mm~RdU6lE9)y2h;__AG;@nx&NAKs_$ z~j2uEIsL~a9zp~?4r$FTLe*Mj4cadNY3%&@AAtRlVv^-Ribv^?l`r#Z6{Q&>|3uFvhga`4AJF0RjoN8A_<{cdT0kl? zvANqP@hlomHRIRRj2pLW47rcBD63BG$5K&zusBsWs{sXUm zMSq^BOX!U>RM;eb0ZYeeHk*R zyW1CYrW5j8WM|Ql{*G@WPTsJ^&sWz9l1G-#x3J3T z4g8<-DpdONT=)Tx+6$R7JMY$>s9qvdzE$%SZ^x-qZvM2+L?5|!S)y87w2ix{XfGy1 z$&%BMSDO5$b7>Q1Z3e9<9*y$_DB-12B_-nnJyJmpWYx)&!|&G4Le+^J+c9jfgPk|E zLbTQxoIWs4|Op!r8YvJE^jO$$^S)=bJNk58k1)GbE1=RVq3QssQVxFuRslH0ClG0y|!R~CFC8*z}`xNejvD4}$>qUohF{d#X>PWfRYZe01`|QzUh=H2iU@7P<{tJrrBtww&G< za`Y_`n(919r$o{kNp>_pi5QrPRU$51+r`D;hSRp z*^*;RL$W6Ri(Xj!!?J6RjC0nGe-L*NSsR#iJd9Tkr-LYSAPznsHOslg%Us9^%y%Lo zvnw(LLnY9ZN}HJinUB@+HDb(x68ndGsD1$@7+}l3TIO=!2SQF~y%%UqG#qtuMGE)( z$%Ms5!zhq;;dP!h!ibjmDTHbka$<<)q#-33&y-Bh4FV#fxlGP|Bw)6cM6abSRrzwx zA2nBs0LvdcM)Z}2x>KuOlWMT~SQm8EVz~leWhG){&Ypw!#=n+Cm?MOG7x2HQ)oGRu5Zu?J3uu1F}G~XQ^m-03==f^S&@OWN`!}eY6Z$>4%d!iOT3#& z+LOR2Z(8&$I^c=<+O8}4Lgqy+dJ(IP^Lz_HNk+#Ka>p_^wGP72Ze86(l$4E_x|xt?WYQW)hT8c3t>uz!G6NPNKB7Q55UbX zn10@(G5^eHlttx`z$gu`D2!g?S^+^Wi;$6aK%qsk5t# zSHhz-GxKzs7OtCP&4S>T`h&6M#}Vv8A+(CN8j zKtfbjxB(c*E+?S()fF|;O)aFo@rKx1%#qE7)A9~vIK%8@fJSfPBnx7f3X3W(jSd=5 z;4c>FaCnH}cAy}p>O1a=6+ESRPZGbvzp>KzIcKW;Pjhs$xK=liFzZUH2OH-;hcL@>PU6RVs<@ygmbAM zag?qJY>Gzo&{8I<6o~Fvs#IWOuk)m*BHpQWmGzlknjo2iyP8Kj zVo3_9sQ|H|XQyvvk=>IqmQzv9v_{~oKCGLyazI`1vSrrE4H};5JH~|`T@lb=Mo;L@HqyTTv!(MQyZd&n^I|!m9L$f zfJ&7N>h!H(0P)Da1&NOBVL)U$R`19on5VgONaPtCOF%CXC$`gCP(|PaMw7wE)xZHpx`F)uG!Rutib9L&B8E4ce!4 z>|Gv*i^gL{3dK7t^c9hesCTS9U0vw}LssdKy+-HHdjwS+`2w7VImws@20e)U;_^75 zgYg~t4)LbcOL>`gj6jF;BOkGaz7IwQ5O~mYOHYYloEi+b5>GQIM2@fA(^JD_vBqd7mkMsBQG&K8%i3* zCo+h5gEQw?%Sx;4%BU5+s`z6z+tdlbB2a>gU@fej@%`K<3541$F+Oxz03%aW^jq?d zK~ZE6Mcbc>qKnv2R&X}=TTcX$Qn?}e@&jI;bIs+XG+WEdoh-c9XAzQk-$&`*%WLJuRET73S_qR8 z^Fb&SXMt6?br68{SU}1L5iToYrHED?8SC~)1!bW?Wtai(uFAW{L&v>hm;oE}nRX;JT9$heKPR#uBY$A}XU3C}L0K_l&>)B_`@pO?D6`)>yuvekj8T z(|E2}bywZubfCK2FFRDgEwe5NfbmnB}y9(`oN$_zLc3mSK zWA0bmh4WzJ!j!iB`CB}}#V`i@ZwD62{`23CM}bgQm_Hc<;Y;&KBTtcGycM~F2#yV# zxZNIB{_S5znhPk#QzlZCSp_aO!*M3RtLak7 zvoIRSL(#vxWknM1eVnWr$^#@?IQ{p$%p$OK1xWAEym z@B#iE?a!xh44+9bMM$wik8{gXdcfx?XEUx0I@|%E25{)e7h47$RykG@Ym!W9ELvc@ zw{%emyvwSQwliew672Xj=-**TTCZ~u`;qW4MEt3~Nv=sn$6_{U82GNq=-i!8!Z)z@ zHncQnk=t@tttVLYwIIz!AjIV#qH9?7!Lfw%Yp}C5g!TPlc{9}QT^+op;Gq`q@co!Tj*|sp{y>oso&DI%Q@ZlooJSXEu(dk}=Uux#ZM1D%Xt*(3jNzBuLnb&r z7gBJ>BZPB+zB@J|U7+7q!Q=9}ujXvCAYxMl=CfWnO zU6MQcoeZ_0gEYFG5+uwd9ElC%oH0rR=Fmv>aWG!S*O#LqGgWp(F=0}ppk5RPcIK;(ooFL|jiFVUsN)c8RQrXViwvKzO zaH$~>xiOkL&o`|#-o!d6D-Sh(y0j-BIrv8gj2Ezku_9o4lE_b4eeF+AB({))g^Flu zC%{>lZKIi$rD5MZmYf{dITLE)Cka4jd8yDEq=uRCU_3)@Aed)A9!C;C33=?!U@zj? zC_qSkZ;IYw^e6a9JipdSrStVZ994j`DG3|mqN+mzhnXv_U&yjBX$?tH0*vEkgB^n)|@2yCzIxci!isak?U#k1!7kMN{CSd*fc{x_SmQf7hV+U?t%dfXn>z=iAno}WuVIQfxGdPi zq67tt(#wB);u*MUO9CJ$m(q+X_Q#PJgV5wi%yNusl%7T z1N(t%L-@E4=Lp=8inZ0$_j-Q^yQmifXN2+I&X>)v z`MQ4h!O`)J++FP?KqtpC--+QJAe%f_+w>nzeh-=;H5AuAvTfRP; z7&imw@B7P}xZz)f6%r7T-Yt5F=ZFp+62X99n|t5){9<}PmhR@R+9RI^QPbS_)2pfm zE@$_=UiRm^%-}8${~)`m;skf#L$S=+ zjt?j%#&RFTvSasn_Qm@y8HE>tlC`<-L}J&Mo*LnGIF^BQQdzRUbh2fvJ1Ki!gtvs^ zxXAX`V@OqP3hi|-_V4g%j{H{P#{IC_MA9S;Q9xi3!`2I%LQgpEgeWXnE1e`-P_?J( zqIy!F+s>(tX`8z|O5!}L;s{ECl671@BXDEx-tjVM(+&jybv1+i5BfAceIVveOGslj zKxPlVkY|`tk}lmi1;2-LF^4V6>ksTcn+x?US;jU(2GkRk?oMe`hvGt@UCom-HCX?XJ!XFl$T$)`o)6B08baH9j zU9)tHs>qCu!vci#gi?3CMq9367zt=yOfkawY5B{S9#y(OdtX|Xa0v%Ci`5BWBj7zA z>^*pV>*{JcbP z@F_m4r?_ikWH}dYcVfrYa#*Kw@8il@fZ6A z>g*at0l{+l*5JL_85{Y;!NRY+z6yp{2#0i0lfl<<%1H^uD{lCed)8!4kz|h&$QVH_ z!|S6NllyC*Zn9HYMg?`Pet!8~NxAVB198(@dDpT|0x0akN{;yts4 z{B}ocB4O!`ufuG|GV)mBzEK@!aBh&pneEk_- zqwRjE$&Kr1M}$5SG`WA?bdv?A;?llm2GVuB_M%Y1kCCfbPrP=ozVV0XZ2F-Wl7>|F zygZ?kPTF~-$)47_n|x|%*{Oz>MZRT!C^S3Uvx6r+lnYEWNr%qhfO^(cnTHSDLZwtP z6)#s-x?IV{tGSP#A0cilSngAF`-z8o`4VrUrrH zaa|RxN*EEzliQOddD*?M#20JaaNS3Gt|3q}ac!<4J?+=hbua1}y4!pvnvJ=cId0lF z(W37XxSzNeaBKK(X4XcZ`7(NPWdE*ApU~)N3e`6_RfDM~ksQfXXb|o?l>5$M<&!Af zC5*C-gOaYx=sXoV#7x%=$~^R?S>KtpaeHJ>@3wl-doqbighQrWz7bg(+jRpe_>`qu;4SQFVF2}8JIUY zVR4))J)~DGIqZCJXm@{?F3+l(4*bhKy#1C^IUN13I(iMst2jg) zbIws4!$;6AF8yuYG@?d&2g@e(2I84-E*h;sUoTzcRraI9`+l(BOG*dr7mEI^?jLD4 z!pjCcfu7_z1N;NZuuYMXkDu}aQ1W|O#{KQet~M`Le_wsXjnhQ(XCxzZ(AedN6);>| zx7v>2dFFBkWgM=iQ5Lc8@A*@1H!$5}45x@w99!!x!fw zdta;v4zO^~T9~2C8l_OsN#E%Dd)?pK7bb5A-yy#D58cIF);|06q--j)>e;vaU7w?~ z*aALP^Y;6OZ~Hg73Qot-<>0V!`TL*Z?f`GOke3tor9EZphxP!zr+=@q3D*Eu0QFCA z{0EIrs6ULDEvQ>`6}&_ox2fw z@=I@jpb3p!gXin6MAw@q7k^hL%93+_2DuLTLXpKtC`}uyg%g<@48@Jei#e2tlHWl+ zoF{&zMv+_=9HD$R$9~iSK9-T2wiDeT3w)t>-UP+({22Nn|9%dhKYk`n|0mc9J9sDh z-v+ilQ!{j+VC#ZG3<7!A;RGbiognWI{nf{<%`e-xIAuhhGS@VY;(RfKDsA_x26O|`@S`gumKr%PLyd>;S4 z^D&R3?4x%dz6+hItLo*{<;e*>ThDh<9|A6nn!lK;(2AU|Qskhn<>BPn`Rv`l!eB6d z2Iad2NME=$?5VI@30m-Fn{R*D42XnKFh{HUKSa{}^-P*Kmd4`2=xtKRW_SpV zlaUT!8@gpW{Gk==)lopJ=mRCBjpFSb^hd1cbA>AX=T~SWbd6RH>Q(wA;^&O`TLyke z>8~&cAR-%qh|i&OHmkwR!hIPIEHUb4G9m z+i9b3iaM8<2J8O3>Xa9$p{qI(T`)cLAPs#=&~RvB-a;?~AHhf@&^@kTZ=8dK?tH#M z7VH@3K~_Jx_A6%p6_BfO10ZvYaE2Hda-66Fq(e5#*fXJd)^%?24T&H(-PYiaPRq+w zR*^6m@0G43RIi!??|Om|Q!MXF#VFW4jQdHybveJx^|2YzyV>ZD>N0I%K86j)fD#93 zOEztGpx5{8#~;AE=#n8{SWd9;(DssdAugrLmY!jxm~Kpt5vlKy&ZxLkKZjgC&x0ki z-#n6T;_&OHGaF5hnW4GN(gnYxf9}N9-@miSt zP;2%~^CQ%AES1q$B{V4J$Z2XS}>w{@CtXT zPkdA;ths@O8F2PdjV5KT7{T5O_YkS$#f+?0YO~GMZ$mF;*m`QVGJ?!-tO*YwZK-cI zIG{HvW=dK41Dj01tZo2Q-UEA^L}h8r+d(ph6=}AMf^Yw&oPv1`rixw9MI0UQJcJZI z@yR7%LV4|?4n#vn+tCFxE#ejqiSTAg$Rn)1z6^vN!10|?qoP~I?oH)&Hf_Q)M2Tnn zE5!%-fCF+Lequ;xiA#gk;e5w47k_Wp$yHd8Q}30299H6>d1aR%kO*RwLAmI;<>Y2W zy*(-I@t7h`88c!AyyXrRr+G!Sl{)&_E$HM28`!)z4fFXq?#U;F#7`tS9PC`G)YD4 zh2}5pyGXXz&DgA@DcqFQqN4z5=~67X!#%@;K0OB3*(`2=Bol5lG@>MOpwC#0Qz*VD zruFp94S&H>=ChEjC8yjIwJvIu+Umow+k7+@3Xl%QmM95fEf2fO{v|gyS9a zmKX%FUX+q5?;y>1Zq*=O2*G}gb&Oy0zK$@@2gYx`n9KO48%&|soi))PAmh}z$myKu z?$eFcqk}0t*D~U)zPj=HzVi?+D7o~!Nu@QzqG&v_7?!hEJ)NodjWELcX<0R>X*(14 zv?)M2XmHZRd@J+R?m0n3Af4ZsIYGnU1Xz9BBgl5lN%2Y|ItgeNN4zj7uy*)M4o*rC zFy;Ih#!wtsZn@-@r`Ae>{7-(Rm8)^CQ30PyHbbVM0`YRyKf&}I59!5-1gu&KZ=RoQ z(Kp?Y_#b2+JC7aHT$}9iwJj|CUgNsksJwE;-skZAD?HmgL?X~)vmXL{#F!Echgd+X2ZSoTWy%U`QavbPWD zhIKE&iMk-EqxeX@9%CW}zF~}mk&K7ROxFl-+o{9mimUR{;UTz@s{d4Lo~2bMMIk|k zWrV|DL4$=zfjfi+f{h)cY67?GHEnbEb+S{lqU zyfAsD%N>3nCy;(pdZMPlk0^P5fz;i1FVwe<%N zLOhArO_x2#n7z%<#F!oiwv5!0avECfUal28$N}(n($4` zcpq0y`t~}~Ivq{m^EYdBjGMoFH%+j&8=83jwBCyb&K|JutLx9cTk382wn6i>(|DzlQiEd!p%2PwpD5@nY~QqNc-*e(F);ygIvb%70V39wU?R+t z&KA8GFPe4y;(iK6Nh4^Z3Zjp~ln9etRo|86&eZOONo+@|M6lS2Yj7V)a6t0Q~sTu1*f)qvk$Vi?XBnhAav|usTyOBpC2ZCCsQejEO zIu>O1cq!Ohdj%+eT&p$X-t)o8OeD{EYK%C0%lCcrR0W1LN2z?=Pu`ClQH>6?cekYA z8;fHJ}HI{wb;k!na4JBqrS*+=EHc*Q(=ZhqQL;rBynAN`S zg{mw39PH~FA&+uma*1;780t=u7M|<8qNO-_!|y~x0Aq{pH8?AgAHO3azXvPXa)fedEnodA~V<* zUbtDW1~*At6jIe3$g_z$p_QTD^F0dMTdvPV0db%;;&>=mEd&Yk1NFay9oLe^E+%gU z%G;#vt%SW}1NN_hH6(`KnFT&xa#BYI2I1BDTzoAV@Z*WmQVrK2k%Z?j;c&$xU{+XI zYXAb@WmLTaM+~v&Ik&L|IV&pa$>FRZ{4N(jYq1}#?YR8vm2prKd1gAx+~7Y+E%&uK^yZ(u+`5ZfzcApZl;-Xmx;vLA)@wQFcEmUCGv_bx0-~sa z;8*dd--~c4$4Bxju_51gKvJgY4_sVj!RTL$hwlW035@a?LDFxZIpzd|xQ+2eYbXlC z2U=4V@geM9q`n46z2Z)JIJwVvV-^L*eJH96!?h6*_iiV83cGckGHb0W2%9O1KuD7z zY;!GZf2lDaGbOh(LzwClf~lpx{TutMyxCZ|LtPN>5iYE75x2QnIbI-ni;E^k2ues2 ze$e(1N*paKlEOFNQhxz4Y=1O^BnMIxdM^-=G>x>fKetPN`J4r5Jma0^*sVM2SO>i7 zeRlRLEzF9$11^7gcIe{U{&4<#QbQ`Wl}d31b;ji=r_v?Sx(%|!(rOm8eo>v>&gW@3 zfS-olq-VmlOrb&xioIIEIf%ugJMamMk@;DPKk)d!Bc|Huck=oN9+k2w#r25QTAm@VBno&__zj*?FIi>gs|YzDczvaevT_Z5xn7!fuk++ufzIxs7?if zEbflQWm$XWSMzy3cXVwyN^@7bNT|X>04A-(pZw94Gc%TIoa|f?W}y12sLHC6QgMIL z60W9xllVAzG_y%hJ8U}xeQmK{#n-PrW6fC2_+)4(&KUO65!c>M3wxM8K+roWLo_I0 zo8=a;oE`R2m(+f<1(i3*%{Q|4Qvbdb-h6A>MZuju{V!n8B<-4SpPX zl%_j^CuujJTL+#il)p2cCpPn(>?|Wg2#kL;>2mHo8PGSE0LjoZX$%cX+^2^TBt@7g zCm8~6Zx0ct1HST_4-NQf1{l$YH})JW^xJQQ6P)7BS6OaN)!eR`KWCES{Y(`lbYfHa;($=aX-oqgM4ry3U{B8HeNc#L&p?r z>{yVhs6)@Gz!05T*~7g1_--egHfE0FWZ#_(oo!^kv#2>~YC;wLB6paH4^H3f%J|u- z?Yzd!?nDbvbz$wnlPB_$ZMbm4#jD?)7KKU zV~C;-98eA=3}zSKLQI`n2n;TDazG1pq*O{8S)dkC6yK&>_?^Hs_9;*ONg7-8>ZE?F zaW9IO)ER?fD_nQW_@F?9ji@AmJN0eQ0Blg==cy}qQO;_(*hOhC3jii&uRZvrK(R<5 zt1_WGFWe#99ZGwqI6sX~a^`j6OZc>(>&r{Y?)9A`H&rJ7i+r&qM+$Uhb!5|djF6@S zyT&IAPjcbb4WL{LnV`ECI3bv5&D$Vgl(B}vP?A8AL;6-og5zOtfTXE@;} z9Hby&!`Pk*bo$x>1h*`Rrpji!n<}V29g3#dOi>DBMb&QnrYVK?p8_O$%l5Vn18*->VF! zr7^J#&3-6`z;*RN^l?ReH_#m5@~+%$vgpcvG!n(nE8+`L)hKR&cr*rw%v&y;hQ> zXPHHYXf%}I&Y1=Xp^bwo7 z3W|j*PeS?Cy#x$?Mr(yW&s?JxPUL&lyck}ZwGd$5}xQ$9~0QN|VxHkeWNauX31T;OM_tD5UhNHgPPAGnK2C6#Y@_4v@ z@Jt6G@|-X;3zO*Ig5y`W#AI3*YE>fOb4?*up>j_7+L!IbD=_deTlDt3ozBmAVGNf4 zO#YPLah4m^;|(@TqYJ-)-Y?b$4cg#a#mwsWA3K^=kDtv7iEFd7OVA*U8#LDSc##AQ?%Tk0zi=$r>BM9pQX{-S~$GItd5f#$V$*K2VB6kZG zW)l|XHZIe>rA?<5Rlo~Z)Jk=?pTcSjA0+{1U&TfVkQ6Ab(ErPSUm3d65Nfa?yOtOj z7l;lf8hs)vP6HUI>J^e>9*!!?o$VysT~-M-A7v5#D#@d^?)ow?+V8jK->DH30Bw7O z{VBtg4X&IqzprLA28Bv_&orplKY(sNTB_WRf5b6x@ikk~Yk9zM+|OvbX~4rMUsB`W zjy+k91$e0Z65g0>yVYv!dN^VAES?{fJ#E6fphw^Um5;O{TAj`{-r{DpzWHiTJN3! zIQ^7s5;H0_6kYdB_*t_s=|=by;U;6%$Ry5K}zzoT3w)4+$%GM54;nB~7pw)t#c4yu_1=`m^qWqVA`^-ctO zs=aL_f}UR^K>cMhqj$706*ERn^7W`<{6uhGQ=_OomN zh2)@HS#z~V0%-PIBQer?#6IuL5x<8}Uk$>sO2z|UpnIht(6-BkBQ_9I)>!&>rw*J9hROExF6u4f$$`?}yNtTCbq z^5xg`{TUOQnyEI*&Qw-ns1WNU9tV3BovTAKh$o6rSZWRs?%RU@%&r)S_Ceh-J2b^9 zfi_sV>$PVCUFKwstH8g5yMC>+s*uv&>#~0?*}Ez9-S>Hn_tGYQhAh|yYwVN0vw2Hj z+_`|IEN`}Mzb^Vl_ta>8+MrU!CjY9jKC~^O-Apl0klXy#Ov_T2F1!qOTuy9J>Eyu% zfJ*qdW4b)S8jm2k+*R7ebPg=xk>qpT%PWXn4cyD|HSgvZX03R)F9Xhvb#{FRUPIab zyKqEMi;e@Ksc<8got(qrYQ0KfA2;O_X!BYd6rX3KYLOeCXQRxM?~fS!{C(r2jmoF_ zC7f1T9P37%oLAXU77Kv(q>8kqLgWX$#Qz*h#}oq? zufZubR|v0hOx#zfm{Tq!iUOWbx5KewH15+kJ!2vdC%;OsQ+MdW*qznCN$bzPby=-k zjs4QKc<)2gGX9bJU7DBG=6b(cZ*+cl4)3CAZEl!xSi&=8O7~9gi1=@NW@$VqZchZ8 zjqSlgccY3~4L~pTxMntou*kNOH8`52rowhsdPW9`hquDiV}dL)ky3~w$+Ee9ZO z-zJb_RTAK&uD1C@6qj|x{)aLq6j`226es)z;oT@$$NtWtq;>Y{hq(uGh?QWRNqoLH zg%yYuj^v{?M?39dI#7VKPkh%<@lc8VH-ytI25N8d@+^VUT;UlynQ8|=feETmaRTK< zYHKsKSeWle1+4`PxZ!OK{yAPNW0&%uRlcvgZoyo6xdhP2vXqPM*4jr;uJLV2>iI{uvo+b^cs>H~4aX^ZkUxPrjS8b`dQH$`Np5 zt8gayfwByrQGC7w=o{1X3Th)%2h+VP|y4YS}fo{W)i7$NCAy(DK$=a_UN234k7 zBPY~QIV6==g9}k=WZDWx-Qv6ey$5gkr+qV`yWg&lov^^pgEd%*|y`L5srI zse)K5C86FN->=$mfnw0>)F4Asr@>o3j>dBcrl3G1!Vd(V|1*7ufdsu7gACk>9cpB= zHBJO2NZB?nY|dc*Ej(lO8{}EHd}_=j=1f(ev=(NU0F)G9H@%96{o2OO+NP0c^;1~3 zo^xuZ&+4>I{lBYbLptHmOE2vSuXg%qVT$0@Oau>{mr8)tGvx{{1DE;$oh z>I(pV$~D4?64M)&2j>5w!Pdtb@Do>tFREdr$s2>Vju(h2J9$^EfF; z9+>_1ZJqKX6)B8Xq)e$x6wU=SvB-oS}9 zFKbxhiTAet=179d{;ku-e5&=2wwU1_R6$h({{^wlMM7h;{O@de_H`k>N)uctc4OBz zjRjcBu#7fSm$Qj?Tw-x`hGwAA5b0JZq|3RY{aD^Hf1AUP6j0Et>-MAs`c?wO1R|ZI zB*y(|b?HKesmL>f<|$8}6DwrsaQ{DOUd+J6aWd2TD$*&$Co`(=m#t&uhu%vkJCgp~ zS~hbA@U+lZ`-L^C{I9Sww;poJ;67V*yV%sHFzbZL)Bay(;MFA-oxPzM^|psf4Og`q zIK|9~@7;eBVEZ*EKVcF({`LV({|f-Gty|BoARF?hO$GEq`Z-s#Cc9{Cl&rKH zH=VoFBh%2UQ<<5B4I9o@2PBBkvBW<5?CKiWYVSq$DDso1=ZLC>LaOfARlM`J~dbzz)B^{J+`%AM5_V-~UhlAKU*A`-3hQ z$yqRe`~FY&e|P_1=>FgK|LOnd`@ggMzuEq_HN$5J7c}_#xEx*4&TOF(%GK&zLp5St z37hUi?^(fKs?Wn!0=(1SONxRC9V=0TFEuZjCTWLS(_5=4hC&rbFf7nZYH*UWbvA3N zWc3iAQ?|S4>pMUuD05GiQ`CpamOWO!wv%Y?81yP+wgi6uJ>b)26moTeYNsM$?uLrc zF9zt-2ZFDNKxZ)ol>>4<*HLUw!OHqGQQ?9LEK^}KazwIO!+h{UA>|zDC((}(H+@}^ z%*}LZko^j?bK3Z^KF<;f4BSezFpo=;u&_pi{G2b+o z9e2(SBH19%J}+v$;*j9cyfGb2!4nmVpEzImdZoU%R!hm-y4;MqTigl{wLBuk~)OWLopk;3l~ z{TNhS5UC4s4b{AoBV&$_`IySri**w0DL2H#9=!0+WtFlbHbCQ#jnk{%taNEw4 zb`~j8Y#wbwL&3vm(i}5^k4NT!D|}HmHWfJo@E4mxtEEqg5yHWYn{F2=#7TljMXFww zWoxSWL@p>7bSoBSYWFjWM1_Nq;!9{Cc&Lfvu_LIR$)Vss$|h8eY|dB}O*Y|=nB->z z?Eq>QcJRng;Ql;sn?D;^X zCP!VVV^~V}9`LRM4Q6IQ%~tP;n|N6vt;FX*C0mb*xSMiSwTwb7zfQz=fSg@ueigq*qCBY4@PlDcto|nsear_Q zA^TVA4-@bWV^=p=o7TTGaN&W&(EXeH-*T}ov!?!Q4)!ET&Z;J8XpWDGMalL zd@VnZku#U|y^uZsNsO}Lh~xTro#xZoJ`A&gS&z$5_%WSVMiLcNRyN>+**ltT;?{MX z0_zc99-~L#ES?|aZz%t!!c_yCxm+!mU@Y0$+&4Pjk3u`ha-bfvQefC?ARNwTH`zPl zQ&D(0K2CMKF2cAYbBWcHb$gA~Wkp`)Y9k(cycE>Rp)6B5>MnL+b}^gPh01zqjF3z^ zUL00r-|ei0JvhpGmRN+|RY~(A%0jc;8*%I9<0?Gy$T=*y^rlBGP3x+?w|kp(PIa0j z0B@GPmR=?`Du!H87oNR_A~26-jBOK5WWlj^C&%ADquDsA*D#C^1T|lhJ0{sAV*IAp z%c~~hYZUQuo6$On(uWZNg`X+C6son;PH#SAAyr;w=nQ$%bc^D67(4mCe$RX8Y>@~E z$6vrQPeZGrkD;Ua^yFDZ0L|M1_$~7FyPaZJM6!EJgQpJ*eari-e~QUNiAiXS=AtN- z;A?1{OmpGTdFs0--sC)^kI7c|Ar%}Bw`8%Mh~cdZ7rEzMuo5eOKHNOTo_AtM)tdM1 z>?)me54*c^r=?SN@$k2bD_(V>B*%&KPid6xq{+-YDcKvA6)x)qnPbNxH*}EKpDY}t zU!#0VZkB@WX)cy8Hm*0r49hPCn}H;Zb%r-sZZ#OJ!+0nJlAJ}!fquYsos97?4TRTN zV5*}jNR2|G79TE-wxxAM;Z^yN$@hjaj1krCXqJ~sIcDe4QlMinDsS*)fZa`X`+M2g z$J5lXG6iLW&H3x0I=b276?Wle#hRZ7i>=wGFNt^M7-Uh8eux`EA>VVejxq>qp*1C@ z#5g(vz2DfsAQuy{_2cRhtZEhUt@fuLf27o#e8y?#e}?gs2qd>(H36Rl1$|~8aFxfh zR|-)0S)VrW*$^@3teD_GHmNRY__8TrHfbJ2+@Bqae&ESRw4 z9vq2|o_IiCtAw;3hb|&T@P5%3u#rPD#Kj9?z~||MfPkk>fg#XGw~ihmFEqFg;r=fo zVds`z{8sozn+`veb#!RVAU8f<$V$8ei0)r%Om&zIt&_N&IG_v8LzVU@h9=xs%*oA0 zM!9wS+i74&xvzP}_n4UGji5>Uf5ppU&=Qg2X_Y|Am_pAAHkwtlwd9fSHi@|Vk7K6E z`eI4MS1VK?R5#+{5PWwtq*m{dnU1<1qqgEtQp)^2GE*uek^w01m9a* z?pC((+Rh+PRM;R~k)OZuY&4OO$Fs|%@C+%fdL2sV*UInKvazp{-{H65QzfcSm#2!jbB|CqXR>2&}0moS=T)=1#>%FoOCO1}iqz zFzkDiiSh$EhSeVB5fX7*9P_AIS(q+rc(z<#wIzTJ6Df<$S*U^ib zm9-9f7Pc~B%vlQ)LM&A&kCShXjzW_jYYRCSiT8}))ZuU9a5=~vldJ_!1UEDQOFrNo zhw4txq4b11xY+7h&ImoE^ZnnYxwj?AsoA`*t8KUSN zXiB-P;;C{ei3MH)Sj`7-TcbfeUR!t z`G)s#zsvof+yBq`$>!)gooC0CqdIgrZW)z{Uc8~!R$>)^JiFPD445{iYM^B?(g4hO zygo)TLvyaQl}43;bE&SZbCTjX%h1Lv?f0w>{!ed~#!II7mCHcl6>PQLvnwuiZScuu ze8cVM3IhqvjdT&&A;|LM@W{T?lkU}zLk%0_lDL5qV0b;S=P3a^E8_ES?i6YVXuV3n zmnEQXz)TdAJC))kY*PNwL(<0tu@`1KxGXFl4SKKdNcZb>(aSyycP;Fm*choRhh4q# zf?Z2v>o%Thtt#~OE}or1ndJ+8_zL7drdZqWY;Whj{+MpNAy>NCKTCKU>UCDnp| z^bX1v(0#An01h>Q8Z)B+*ppd)>C{+4Ugi(N%qupxl%lrMyaAt5mNEI#_jk#31fuo zx4x6yNWg3p->~7HLQe(YX)$*&K`Y#`c=>2{#z^&1b&_NA6stSohOnfji<|}ZTL*X0 zKIXmL6o`$;OePxHQ$j!xAclrd<57b6nSCr+2I8@0PRZZAw0^Ic81k_O^>F?F?f<{~ zzuEq>=4F^a4pH**(J#k}Xm4cfc*g84nXLZ*{6F&j|M35{cb!hOLYcUE;kjLhF>gv4 zhif&0uR1u zqN|wB>d_GoN1-k~?agd;k-)Uj+9g@K>IQ^ko1mb*gYTuwRyID4Adv^GgY&9DiwU_S zfa&MAZ4rOcBo#iDV9=y3T8@Jes#g<|qKTh()sOD8>cUA8DmR+-3ZeQ zukQC)V)Wak1av$;n*PSra+ z=(oOP?p0*tyQ&LUd2=sZMwdfXW3}J&a#@*Fwdm+L()NIB$Ll$avt2e{BVOmy2;GzM zaM(kp;3uArk)FS+&{8Q{f0+KdzZW@)Uer177{q0GP-t=|!!4lc9|vq~#NQ}RQ238v zLlL|Lv%*rf2^G(?0Zu%2M-a%G`?24hF*WI6JG&@3`SKYZ@M*}&W}J z7~KQtd!c?lJh^t|$z!XiZmO2#p3~TgcOM^~x1@SO1DABjzxvJP6ylj@?Y@&K9OX( z_!d_@kZNPp6P<4c&0I~_m*KhbdQHjw>TycDx5PgFOT)>{3f9QQ4KY;}aHhx;d%dyh zbvlwm-PWp8lQ%Lc>RS+Yb5wN9z&2Ka({Oi7-eb7gTgPLH4Uk@z1leDIu%piu$Z)(A zY=^b7a#PP-C3DHglbSp@8tN6M6>=)mD0E_`a$l{)4?P43gBRv?e=?p-FzRndk@;{uCXpqQBTszh?8od z+%a)shT@A@PC3~HYeNlpm0P|u>UFTyJscYVSwN=0<)Z?zk3wBN9Quxjfq6x$78j8V z1QwtUXL;!gFc5G{kezYniDlr%_#Sl@Vm$AfhiA+A9;Qtb!CgB1UXpZjZhg|q<CY%s`M62-yYp1!kaO;RO&fpNcK zy4@}yVVkqD&Xj;d&9uX>SZucBS*B3@)Qe*1P-rVus)zZ#3Ok#{y{VF%2Sd}qY{yj6 zxJ}XBjBY%(oaen$1wEg zbeun^;snm7%P|TC;iT7E=_-N5G!x=(;y*BWxT~X#8fqCWLY>3~(F-TbgZM3+AS=j+X$gE`OnwM1tt zXs-1Q$-^YHqWik;^m=-cK!-reFMbCfxLNi4nz1-eRVG(WzW~6J)O(BJ3-na4Hjnzg z>QMG1dQx7aG1g#-fF|iSiI1fQx0_6st-+V0i~_vO8LBvD(x?T58VW^xRBYFBwHPc7lPx(J7$=%^af+91xb8-4F}f{1oy8>fSUoY?UHT96B!rXbeS$09 znIn6SVxx=~Wvf1?f-8?`X|AF0GV`jal#CQ5iX17pJLUV_9{<5=w;}fUYlTVJ0xgyS=ZVe-e zbspG%fmNU}1uD;JuT#sg1kslc-M!DSJqnN@-q=B94g*##zKFK7>pXnwjX`V5;!Lp1 zIbzeXg3{xl#DK(=bc-(g6R3#9j&V$SBRt-8T-q7K1F0|V*@K_fFSer_GX;3Ay7RI2 z^Z5mUNpdG8W5G!CT8znZyl+q*dbC z8$E%_l1mc$V|Et$kWb8vTbRwUcAgOF>j~)&_7mh2*u%f5p0kHTnLC%x!glgxjEuRI z>*UGyb~~a&ZHuRYVMo~K3`U85I!~{O3)V_2W&*i}*}84iD=&8FM&G0Ah3jRxfkGHM z8V}lLjssKf-;ITQ@|fE-{0*u;Bn(N%>b@~fK88Eh-Q4r~JiaQvSXG?w9DPykw>s}> zYAIha3rI#yu0N&&ztQB&Wuyx=ZAC} zj0r`BNO4Q@J$|kLKkJYGhx@a_mK^NB0EgL^oe6*?hdhVoksZcKv`|-HD7r70P&`!Y zFQnv0G!$~Xs7&UGhppizE?-&j&_#1!1yUnOV?OPlLBxabVmn@>dFj5KTk!hCjad=k zGNBO=)lK9p5*AazoFg@+V|rm8=KJ|Lex~^Z<00gLtrWeK41#qhJVM|FOab{(TlQGj z;exprR%LK~3m)UWRm0^sS#oOfdJ()v@lciK zIS0d&G@&ybM=LY4)0kytU&~oVhN(;wINBg`i%PVnMr?wYpGJi&m`!6E6x{2|&V5_l zF+s=gItu%U!_i{}?i5;^B&ZaK$YC1cR43eU5|gJ6DqC|1dyZ2eSdOS&4dQf_t z*WeZ;=|upgKiK>w!y=t5^&E&G|6}dcxL2=I@qnO4*djGQ0Y-A=uIh zk^keuX8$*PyYqH?#hWfr(Oul|nH$!ydrveA*0DCL`qV%m%bk@pO8niZMfCv`a}Rcr zmRVh^_pVoHhp*@UL@r4u_51ahxiF`DT70h9Bm=MA?fl(f40r=JaMy}LhakZra7AVW zc(aCaE8%OZKZPIr!qIR8@LJ|fzLL6xjZ)vpL|GS8aI*6f+~}FwOj7XF?X95NaVKYn znOL51LeP0CC2S&ZD$n3xV1yT~S-W|-pNRfV*`#F7=p@wQyOoRGjMc&ho~KZ*sSvgT zj=eFo)W+%#y@)?CMTna!P6z)6eu6a@8zMDh?a4fijsgS;Q4&bS&fN)0j`Az3Qjz=A!@QJ#m*Sjq$#i!pd!z3r4^Bl++WlPSYGY_a=r7kas|1BGXTk0*DJHni5suvW{ zX_EEMMV6P?oaT5P!Q*)ovs;1aDvrFbRDw&FFbE_|?MXfN&qSHFYTYH#Cy-x{t9bMo zPT1P$faqp!aAUMeojEohKEvOKl~KkSyx2-vv}RX&Po~3(Ylp(^!mX7)lmseM5!Eno zPDUrG=kWX{?QvvSp=b0>85=rXOOyFGmwMLo~nZGoGF}Z zADfVc2CBg7gg-sMtMPfc6Gtq}QcrrmMCMly0kEuT;E}HA2^5{C4Fx%wD~@$%iLE~a zrLH&7onX`abgLwDbvxFuOe7nZD!n+CZ;K@qplr$$#o<_SOcU9zfQL4q7FK3<_DlgO zbGdY_$o@#gw?Ms|1|?^kZunDobRvpP5&a(ABnHaoEVp=Xv#@+S^SY4LnNa)xj;&dv z22ik%Y=6K5kNlj+x@7bIbW0sqA@N|YWtqik&;&Ug*Or6*8~gg9m$eR*7?Elx^y{2{ zyV{22I+7IaNimDyM#GsGV3hH`fdSv%FHX&52|W}Ymad2i{aU;aR=GOkG6_o$3;(xJ ze;@`;rh+^YU1(?^wcwF_PQt*sXxtN}$(5;cc8_~Cy}khoKQ#vv(YX5BduQCVD&^jm2M`ikCF zJ~G6nQZy4{#rndXP)!R~-G}M+r#+ktDonpHC*$O>z`2o|FIkH5vip=ak>h|d+WHA8 z*ph0EsHV)g?5kmf0DL94iH)Pmf2SrS=K;r%|4HB7uj$ET@NMAgO1AESgaJQQE9cpnzlhr73%lk^BMw(4B?F zMbRnoXdMJolX^@+Ky`EaL0d2v!;(J^NA5&X%UzXS^%4to9U_fe`Yl7dHG5lVK8*oL zWLjz2TEn~gxf#PA#Q=vpar+=XLfw;-n&GO%Q}MCl-uzMZDEUd21(Qm^2?-NRyxSyf zs{z7165{?w>StuJv=1JJCOrr0o}!sc(n&hvpd-{*0%Ou&J~k^3#J@*RnFol;>=My> z=T+F@SmbRIP@J$8*O$;!3&2ExWcwFsq^{#lw2vl9UmkdQ!3d$T{z%nbR@L?tR5-(< z9o>yckMP+B&-xiO$zCp7RNF}}W(ON=lTUa4RlvDjbuL);gpVVgPXiX;O8q5`Wtw3n z3|f;@8q&&355Xlk#!K29BH?rj^_l+xBE6@L28$;q?aExwbBrD|nuQYUF%VWr4FiumXZIQX^0F}hps6^2GJ z2En412s$v@I0H+xj>NUXbOK#^y8FX@#kf}s(_e*?G2yLZ#wh=PNs{O1?6r&(u5ZiZ z6~*l)c#!Q84N0VOi?U9f_~&8qa85-JOYxSy$`DYXMM>Ba#ZP4l@Z_wvzpz)6UEeV! zk{pk*|J}Ws=i8_)U+Mgv5eB+86j!w z`HWt%OW&s(|5e8RA}Snjv8o{d($Kd`>w|{hi4^2gw&90&{T|=;BOoH+D%%D4CM5@4 z@d0z{T~U=}!WIrIJ@RVM^87J9 z&f|RSWvbETFOQqnF1Yh=9HRK{zU{-8#m z0+;cm66c~`)^v1nNg}`o4J!1F)4WTVZ&Qukt2~D{Y)+~=43VB(v*^(188|T;;Q<~+ z!Tm(@!fmnrOjZt0j#O9}wW^->c(B*D86e3XL&Qm*^`maBGx?0!eGqc4lsTy?Rk$wJ z+*etd_R$b44FF_;c%|Oa%rrv6L(BBOq#U^UspMSi6SXkMXJ!sK;{Wy#42k_q z^5RNSWI_@)L=j8rD_Z1NQ)v3H(9<0L^gxzI%>oI{#tVoJ#_em17I}V6v};qw%T=|G zvuY%fg1Izrq7gFM8D8d6p^i5eleAkW*?NtZ5U*WclIkPcvur#sY@Pi$!yyu^@*;0L z@CWQjJ;u6mtPWwAu?Sgl<|aot`6l7gVKotN!56ty&q?`mdh^RNHil&yoQ_0EYbJAA zFkNn%*CS4iw?KWM;FT_AtM~Len-=cpsFmT!6F1%*f@>|NjztPlrwi<%J2l9y?K$M* zHe0zEyaGJ4+ob;=Sz$XSB-${)mb*t!Qc$kCa6)?Ls2>@T2Qj#LJz!4ZtDb&-Bq9+g zCndn<8((I5I2qL(*t>y4%C44OG;3YehmNBjg}2Ny9D*aHpPG$^qfFW)knJV@vvW;S zsbWPp=R?N{0Nt?M;mvUg<_aJ^KesdmXZCUVkywnAsZ;n0$wtmIJ}ajXr2%1rYvS_@ zxTng<*<6$r(K8)?%5rWGa<}C<$-A@az)k0EDl^X6UI^$`&pAe`xvp74%XY>@uFuU; zibsi;K!x|{kT+gmL8e=_ofh4`z=Ru(Rm~G-p9l`z@qCkpL!W1SY`YYdfpL9v( z6Mv7K>znQOeP!ipJ|w820Xh#oky3D@cWW>l;L2*ryOt~L+Ysr!d z7Huh`0TreoDUnxXJCG@IA2SDRlL$;g26enMOEe^=hMyV0Wux(lmh zioDZ|bXgO5fNlazQ;Db~@gdMGLRa4^H^Bv(-&SaXP9Y%yer@r-e%@^r(R6s9Rx3aWiw9*sYvP6d80kbr6Vk(kn zTgpk!97(;+PZ)PP>-B0Vn%+!rN2P(==yJ~I#9&tqyhT4Fc8honJ+M_l89tHZn~^b;z_j9P)GIp%-o3Wc#>ag8A%Q1ppd%|HGC|>z< z$i>VGGTF(_{IEstEYB|npnVA%_9ALn1rIku5TyuBC)aDHzjpCOWtImPV|c)Awrk%w zyIbSCb7V~O9LU-G2BpV>R>HM6Ebh$4F$MS}T<(f8-_eT(lfQIIY&-Q!F|4MD)k06k zxEMOI0ae#C(i)8_C@K9PRcVyNTl=-U!m&&Jl?)*%0$EQfRP-TZffL;}58rG~eM|nt2y-8(kk6!`-JejkG= z?#HgW;<~%6naR`X!OZxbk?6UQGkA9}?L&DtM+PsS;m3l^sx;1l#M{)5+DrknR>ZRB zovwh@Ck%|wR}QC9m7+cVtC*Hc8n(w&kPI_vUF&66+c`YVab%J;dPb|fLjH<5GY_FL z)kbSbB#Rw9*tuzt_X0Vz?yXzeS{BM(0zv3Gs`5kUbOCikd$u3mpXJ%;_<4L^h zQa^|5J&^p`ra!QoVH{5PhRIL7B+?P&BzZjy3gVX7Rt%xu1V}c>0E0(j+MMjwC_xlv z_ZL^Odz?B=3x-j`3t7|7?j=6)6R+^LiNv*&2d}Aewo5b3^{T?(vZA%!dMtE1Y4#SX zlO?`xym|BOZJ^_%(XE+OrW0xxE^vLqn<}iNe0(Iekxmi1Xkf86e=U77aq>&O`6kIf zS+861!gzd)Lkes51;5%VxJ)YU82(s;o!QVpOlB5=LV<^M@$Z>}?Belid^UESvLknx zI^(E3Qn_fB4cjVj2jX}+BzXpDb(a-CC;Fb)~ikOR;Babwm@7~F8sIK@Ba zK>_m}gR|ekPFNa>_McIJRHb z{xD*%d}Xvn!;zi4uV+z+;WGl0xk`Y=W-}i*p!BGnjJM0(=5M=RQf8{^QG%G) zq?m}ET5gX~6WwY_gvf>JeUa{h+MZZ8G61>Kuy;P-OfZ9HE*vIQ-C~@fD~re5=2ZK^9b`1Ivp00Ifu zM@<`vTN{P_BMYU(@1-24^lt{*8e2IM7~jh}mZ77mg0cNnHGLBq?U9gM zC@{$ZwT1Svq$K>%(B|`Y4y-=0bLR%U`VpXkXG`z#`aE1mek6kG zK?PN4$%LR;hvE>dzZXdoa>^f9PAK>|UStv>rZYB@wQW`Sa)js}PV4n+*qkiqe&e|0 z(6$P_RHemaTPXE7iMx5WZU5>V6ULi^DB6U1FdGL!JMvUW$dJ8c<=CF>N()y>!%B^Z z1^7RANmTnrS0}|J+c>CJ#hYlEl(K+*n;%h57m8kP?+XvDsU{=)2~$Nhnmbwb#BLj6 zi?e$fnzs8lStDBzv*dl%IwdV>Sy|U{4 zZCiuhcGh~(75JCVd7UZ8ZInsS{s6%zxy4d)UVZ;TIyxGq4o#)`B%OL){wQ-sq0V!& zGK6TJ1QSAsuL)7zQ1Wk{1HSw+jqIRwzZWeBI~<%{@cd+m@m0X%QrTL@7< z46!LK6*dt^u?62xbpfoW(;uo}_f=ERgp{|c-+qTc<}g+HgJs>MAs$L_G#EAfjHa3( zO&kqAbR4IwXVb|Dz!O{9u*RQ=o#%qDRn)f??qCfjR3)}-$L$UoQiO(J4 zn!*NP(EeTW!t-@G7}rE}>Oq#}wluc{zpmlPzRQL{)d_Nyxk{7AjZ~HKCu`J;$c@vT zHZHusxzs~5k^*Td?hQT|v`m^5sGMyVR6B@uzIf{RF52@s zk=D zsLA5J^-|2t5m&@v&}OI7!TCVsgB#`5%a?u2W5`YQj@4t4%Sx*}=^?3!qm0qb(t)R% ztSR2bIiSsaGeJS+w;$R`JYp3KWdl-6j*;Aq>)O$x5$3z`)SwF>tdcVonTs3Ah^_Q3 zr5Es*INi1Ip~tuZ(%;cCkTRN+zhUo+)0Pe<)(U z=H}xuZ;H*=jGjsD%epr4Qq)^s(Jl**J_kGO~_ap8)!rTscuf=WBC_@O9D?p!5+!)A`f_g?zTe1Y1XeS&6`Mbhq z89e4p6f5A&WSTBnrj&g2hVBus=k0bLS?a2HFlshw4imP%js4!ir-&Wr?BLoihtv7} zGz0n_4qdF9ho^_)0z2z+fzjW-p)&jpe(d;V)+ap(Eg3;|?!v>5+5`hI%5UY< zmtBBC_{0{Z&x0ePZ|dN}5c0hqEfUd|zzuQc*addapnDWu5MxqT2mIxi=Jn+wlxH2t zKP>ke%NGd)6o$522swMy_?&hK)r{;_+E}NvOFUZQoMa0DyJ`cAd@6*2cJjguS9k+9 zw-rM^Y@E4l!?y7CESz{cZGpaektVQkc616XuztYmF4R4`P(X?AN)j3MIdNAvq#e3W zOV_q_?C@^YIgeJs#qPpTcZY6Co-30(ltuh_*01c|n?gNRW5 zJi~Fe$aaG45(a~dkX^DY+l%)OUaH`(faE~}#^qJ=>xvG)b4>iZOsrZbe3d}JAlD{2 zYm&V6XDYoAGVF>^Tk*z1){BnN;~@PZosO*Qe!XcLbCF z@Ml5yuV*|FpP-}>A09**tBVy1P}7l3t_PO7w~fpS7-EcQ&E2M%C){>W)JJvG#9UMaJ)t$w-8ex zXy~Ssw~*IkfSe3pk(^YG>9@7EmGS>8?XXneRSMusxO2XKxN>zJUOz~oko@Zs?MQ^5 zzP2bHTiZ}XO@$Ve@H~he9}Od6&2Y31LBKkee4Wp0=2I7{|FT6|NIQ?wF}Hq3(KLdbyvbvOoed? z;$MOfX21LyO5_PzkV(T}whBlEJik4EI_q|*^hey#6A+F`>NN4@n|yydavykU6MT>i zIOxvj#?^5Xsxp|$m{`A{PykOjXoz>A)R2cfqQfvw6Pa3?z=NYZ$O_syc<|Mf_poPp zG_!6fs~zRNiHFOaV*evj7V9xG2DI`WlG$?`$|K>30p%c1rZv_gmCGLg2WNbj2Jw+c z9__ZzE0#4%2lR}yf>%2;O!UL-=1K4Q1%*PK?Lwvh63+n{#9K=3n1ok+gjGr#>~M_P zY&~icmVX6bZiaM>&O_{tXrEK!g@rrlS|+t!c}S76Ruju^sws zwM>r{PVLJf9MuSOnlYL6GVj(oUnJCC|B*0eU5zS5aZ%l$^LEIFa%ap%s@6hc8(y<4 z#-6BuO+3gu1XfC5I3G0OOz!U`jEg+;HWqwgo)%cNWuC5FW@uB=n1~PG8E+iMi%s967bRxhsvPTEN zp(UFJ=G<IU$N0lXNEnVr)`jR#L^EYTH<`mHsJD_cG+ zZQesVIp+$2-yIh>f?6Nu`jqr^~N*<*WuJgd0wcL19ywyD(ba^U4B{Rg>USrX{Z%#vbsA(Pc%{b*-di+4Vj@I>`hyS8${ z9U|;XxxOsf2K>uiQz|8$+hc=4E)H!n()NC z9EMQsChH)r``spe8}#R@<_tNb-Ra@NA>;DN5hfG6$X3DHL4AY~3JBASX+Mhe(U*4v;dR zOCi!&XG`F2Kav~=|1OUiMcat#U|H3K6pUwiE2*}WU119gOfuZnbo@V&k8TqG4y1u6 zWL$*LSy*Pf7sQ8g*(H1KO+gTwQrJ1HOVnS=hl)W;3=JdCRV|(;n%<{X>l;*qKoeXt zA2csjhpkG(?FpkQ2&a6YO zX&%t)R?A31_4`9_Ez!Q61uLJH*9@}P!EVgJ^>Nj~p%;pi zO=4}Ot^(5Wrk`)OrV>9tU)QhY^6QS5Rs_1)T!^iv`%*O6D>w7>Re@0C<9#}`c!o#p zwqrW62$EOB;`8bJSW}dQwF!*nrpccc3iAgUpDip6yHvXPyiIcSMMLZ$b}Orh(-_?D zLb*Z_T={jNe9bX$Zlh;f`AFCU7Mk;Ec`jpr+nKN>r$86+3zardq6wqeYyrym%h>eF zG*Ex;eYO3vA)!H_@?cNX%6Z<;Rw+UG)YCVuGpNb5b*5XpygZ{0vMSmwp?sM;fa@CED){%dp&b-1RTWxzyx$5)dEjSX=>CB z{PVWMKF^Y?(8t=K-LAEA9gDYogY`b=y2#;S>;1%hOnsz9ciZEsJyXme~+9y|k)g+uUq z;nc~06&Yxhi@OuV45AbyK7tmtEZIZ=CYnl?5n zHS;GAnd*Vm+f!7w++#{cRD_ddzH6&UL(O|RBFeC(8VkVof?amd=s%3>IA1w_f(c58 zs(+t0oOWnnmsBgF=Q-+I0AjQyP*^zX=yIl|ojR1Uqpu-R0WxbMWSA~gObk<5?gD12 zWUfh!KTVv$pW1xc(IywAo_1bwwxbqXTxKoBl|3eizPPOwhd$X*`Hz|C!t^-2F)k)T zDA4v$=H-4nn^zVhxaW$jrp5SBn-J4`f)grbpUn1MOm$}u%NV+It7yPv4mg~pPnJivZ?uM_}}#IX~&Wc#&5_8v<_Xs@!S8>7e~w^zAtGe34TTZqMd zn_B1M6-bB3ntceskRFKc6zQsrU!!>^$+ar6jK8DwFqm;wbxdmZ!vCh|9FDE*TN&!w z`Xri68RJq|FISk%tZNS*z)WbExp>u5pH!hz zG&glL_H{Vq+PjV38-pzbK<(nxm@laW<=;w_d77GGykR!R_^Ftws-(S#uu+SY=TIA? z45+7snq!mnXKPg&%;t9E9O4BV@wMCR_&z`gzWi&?%DOVm+zACMwc_(BRMH%p0DB<= zz6g(ui_xUQE19D8wxH={!V1$p7#k2jQfH}ZXHZt%aNnR#b*Y;3u70kKhdHeZuW3ra zY#6#1v;{m>7BLb=c{z5k)nMv83;I7pzJkRRsUl(<^a)=4lP)DurcE~49@(I2RyGyN z%N5&XvN~6rT_M-N082ffegq_Gl+3})ds4xGy-j1?Qe~vpQXMw|SQ8HDitnqGKn7G* zGc+_nR%ZK;#RE>^fD#LclBp#~3Mj%vl}y`R6$qtH?S?FXNCi-INCyZDusC;@7kPaT zE#<~sV|fkUHuEy`FD@*b$@pb4FIPPM7j?|a}SDoxZy{1@Ah zkv!)2K8)1#AI9s@lRj!^&FiDhPUnI-0w6>W!d#M~_;TSeA|!};lz@Wbsm%J0*MF%s z$Ciy+vVc*;29Vq-^;tk62%-HBef(ew1?>W9%3A#Tos+p|)$n8CQ_^9gw6pZb;Yhkb zd6!}$%Wed`C++|^W+9=e11|O>%gp7CNdu~lB|4N9KuTCrq4x`T#;%r({_&b!;Rt@> z&@OFJV;QEvJUS7rH$Ligoha9+c4)BZUJlJ#h`~oJ9eoZ1=oK(H06uN0^&hN-ZLcfC ziOs-!I=DWbf@2casj@7P4JX6G0_(qQ4HoB7_?Aidhe?!FwU=$q1u5{*ayz)J)vPw|^#AN=4xrB;B6t zP3Qss12rQB&8IQ({{xJGgJNA&RrMj=LO^C6K73gp8D=}#UXhna0JLynd1zF-U)lGG zf^w3>Y!wR#Ces3nqorAJT#sE3s1TD^LG)DHJ;MvG=w`T-?4qT_$|V&oM}!1uC3&!5 zbJj-!dF%pd>IxI8o@0cd84N0`VmRdAJ`rnkXVe^A9`z&o)ej>QKv4xX9J5Xxm!u$6r?5gP zKl7m?cM$n~5Rn5^b6_Mg^kJ6#!pBJ7j;w|quvM+H=)r53J`?Df7H{?Biap|05OKO{L=2SkGH9;a}FqxSKXEm^X!PESZ73iCj= zb68}Qf`X7L>Bncl@39$NC-RRw^UKysw8bxu3A7nYbut&%E`x5_^i3Gk)VoDdJk_X0 zwdyIh!;SXiP1ReK1~RsBQbow!MfGsK^HtA;0+zk*E7`oiED{bCmKFx{1Qn1PFlTMu z3%Q0X)f#F-O0Ur%%zocCczUy4mCq{Qw5Sj!-33E7N&201S1A7tkYis zXFQty&_ViblB&K)vj`48VQ#M4fW9ZEgv3X1Gl|=VjaqQg zv7{0sWQOHy${d6@ijhLyLky_?t5||TEYR7GK|Q9l`#HmX&WcM@JV*gd8hmLemM9j{D8b)hygIV9^RkdejHSvF zkRd$TtalG(xRQw+OPAG(;dNTKeORrPG4V7M;=RV0K2Qz^_IS3`h2>zlxPq zrZVS7W^|j02N975QeN$4Owx6cGf^vv5CXJp!!;qYv|-whI@%CA95RwYSJSS4E+@$e z$Xmo;9Z+|I;(-2mPrs`7a(_V=*ct9WJL&5HKtP^{5 zZXrF?A$`AV-1j|xuw2bs1mNo*O9w&DI%hR1)Z?M~-_XC(Ogfv4acgLRW|YZAsnAXx zQ_QT?v0!tR8P^kZ#5L_pBjz87iWw6QMMP_!d%bV}(=r4V2VRGQYhBWA!Gj|eUmBl{gNsD5 zLgCu1W~aN%(bIWR)2fm+l_v{1hMg4{-;ELo>^Ug4svxDt7nd3vv=^b;$r_ z^?(kX1$X~hbunx~+?W}lel)Pq%w4wLVH`=0{uk=dqfbJ)yrM;JmtS!5XgJtw;VzQv zF{uB9MxL`3nk$Z;r6`8th6IGPusjbl^mN_76Z8qDA=4&0kftm*B`n&1C$VJtxL{Km zO49MexFih+6UUg~*T%rQ)|f_;^O8IPQ{2*N{XaCV5tFkY)1)*87P1Yx#cVJDkS zbfZ^_< z^T_2!7WWx$>?Vql13k_9TSPgXfC7Xj0YkRCXXz?3Y}FgXt;+$bsljR_j-6cT(L8W; z^#vD>apMuM)fHCi=(xl-7A}HPzbWP}W!FXLcQ173RjB|nxxZLQY76!p^6V(t{^ddL z+!*2a8e$A)=ad^T7J?C&lpb=p&ez%ydct_bthAsXWXI`9QXDeljNTS9kho$OCZ1D0 zX}XGBMHlo~W8VVoq%^5uQE{wMFD}|yT90fqFA}{QbY6qc6pA?Lk}gXL-rj0?VAP58 z7>mQZyLF9x-afdttPD&8RrQ9hWKalte@FCfL*}R3()!U?)Q)ueQ7Wf?&dF=0z<&R! z-R_Kz;jr8VP`ai;c01Q)lhKkU&8x%4zG*HL_T619LV!7zx_t(Zqg_AP7}&7t8Epd_ zrxNQ>@aMaDZnIBf8#^c^{b{{N5qP58MWA@zweOzMI1GJpa)z5b4slvKRFZ_GKd&GN zIe!kHsw2EjBR7!#<L4IYn{fzIkFY1$Wv#h(3*sG zrRk>=@_@C*??hQ8aN}7f5owjCi!8_qD={bN)wT-gs!GF_IwW2=b|(*fi;D)JO~ST^ zlT-<9T}4Oou9`H>v_TbSNggI5RLGJNqTA7B^!lPaOjI-~u2t7JPp4E<8ABkD|5E6? zfg=^h(N)k4kZ%sf%wH>)KzPJ<{~~TjyQCWkmwr##|2N|QNB>rAdl}z7D934jAK(8d z31tydNi+T65PmQBQ?If$;v_`h-x9;{f6JGZD2T8U|5yC~+4#R}{5+S7*ugC6#I%nt z?!tjEe0X+$aS1eoae$xe|L6RlhxfmxC8#6iE#b@rR6%d?{r}1PpT=KWamJgavv|0r zkvz*J@5n;UAmTivHm~sUBq6!tCH}wp{_o-cPw-?AFTJ<#Z+5}_rd-L6F1!Kf|GJz# z4SoRFh=@=gQ#0UrtN1^Y@&BLsc`OT?&xg>U+fv8abw~seM4?4R-MKH#~q79Zo>eE-2!MN}V^qzitCa3qm{r&uBrNn+Ps9JG`Xmt7Jt4qL z`g5Ob4@qaP5R?Dn{y)S1f8OLl`+pDb|Mw@T>-C}c|2N>Jp;5%@D2iCJ75ArGwGKNvW|7EuBjXdNpi zK*W|bEQ2`QejJah|9`<;qBi4@=(OtO2{9jNU(4vTsEY8;kKzB1_`e_e|B(q{vWm)w zz^rfb{^dIwyZ_;UYS7evKlp#Z_sW|R2*-+&5+B+o#1MxW12IZGfgC~n-@)LO1jpfW z$Wf(1|L<}q!UA7$qzE6DuSK5WvcmIkx>e<^7(4z_afSy^{-3k{u>Y-Ms+CB41;Nma z5Agq+{{NJzY_6pf2l9Ux^IjkrmOn1}q%}(~lx&xL>t<1`;yff+Vk%0Kgo+oO6li@& zw5JXYyuQ%&cdUmEQAN16B415CA@;KjZ@I(ZW(BK;txd1T4YuODM0Z-+3Ir54zEL9$ z<{g5C!y&ctW2p_TqqBBd#s)Uo2&d)wbt6oPeqlitc6kFc##mTxhMhn7g|>p!F;!(d z!RhQY*2Nx+)q*}YfLuW(vi7OB)p<(ea3yeDplYY>Mz7dO+;M9F{nW##vQzM-hAM_1 z6D}@!%B&q9v;upyz43)Nsi^_M+;7pyHooTfy{DvZoii(@T3yJwB(|dH+`q16mhtW| z_e=D3KRsbzRZtNRCN3bAn*`}GSr6fL`=_F+95+6BjB57P7Rz=MuB8$%uVK*gYF>j5+WLtxua05q~5fW<7!^>*T zL^znVktIT{>LhzD?#*N?jC*R8r>mU2C#KUz1j;$*xM?+{78{-rKnznPiWhH|Rj)ee znzb8l-4;nMifzQE!WJ=D8mN?CRams)hc;p^ZR*dfLf8fdQMQYsYw0SDI zR|5t96x8I>*gE_Kw3&IN)N39n&dE23)#CoMO*G=}JZP$`jHq2Vb{jK#VKx?XUQ5ZD zVa2g-{k%E@RTChywqFr1a4Rlr`+yI!wb`Dt(!w7w{}rPM(ZTsBZ)ftV?PQP3PMwK@ ztWRoW$PI2qs}@?gk+hWKww&74I!#fymj3^TPCCD_N6=XU^kVd%&_*m3KH zw-i>|c!UP-g?-JgNn6;wdq1!}LSSpH|64(qEi3)^nseh6I0$P!0^t>FH3$!Ng zm+OAF%TN1<%BXRj59*))7-1oltLU|FcF>16ZMIv{xsJLl>1qq_@UIuH&wDjZn0uqp z%dthbvlCdfnVpZ*dX-T;APqAKe*qptNz%6HV0J{RW|Mxdt`7$q9B>=pL7h-`!Muqk zZ-wqYIJN@_u;$FHtelUNsU>?ar1sP~NuvJe(OZffh>_z>?cF%=bsIQ7-imJ<3@aF} zITLmghE(geO-Ptcf2kxW=iBSoZ&4Ocyz;pQ>2rb}$%CW>IZDvM_XM9y6n)fSj}xTc z2~;FBpy5D;Tsd{Cbzwo+V|Bs=W+ymsweX2r>69p$6OvXLJwfjk<1VDY^?lw7#M+?y z+0pa-`W3AHIr+ZEqeb5#a&E(*)&M&|#J~1R6x1oXqHvEx*NLyEkl2YlQI4hxq7FF= z0u-O&zQG5TSqx=A?%DOyMD4i6KVrz|>_)TZ3aHz!WwVPMus|D^#lTHOMCfzoII|!T zY)02rL|Gu`>I8(pz&jA4$+d&iHFW`=A;&|KqU=l(|2|Bp1Lwt6RI5mn*tNzIhL~Q9 zJ~LN$LTqIA`qff0tCPpjG`^g;?VhGJLtqk@V&x;aj~kgqf}+1GN6rNo$D!x^l`=;EHDPmhtqjRAHEK_1U)@K>VmY&G>os}CQ?$(rg3 zt@9>;c(O!@Y)y90VxWcMu=VyG1_ns3lgwdl&rD)yhoo(2(t4+Vgb4+LVY&909(?8F z(eB}ef<0J<{B2P4cqooG;0x9DA<0xj$x?fj|Na0f4pw)yQGT5Wgx^U_U1jbw3rCBD z+7rn8)%~M1xJQN2Kfec?gZ`c&|(_y#=DE3y8$u1qU0{ zuqgif0E1FwdP{&;d)q&q*y@@j;6w))OLFKUmW!NP4#&rL?bEWGs-dAGd6v9BOfYnfJC>L7@b<{)p$)oQVUm(B ziyF+zwPT_>U7IW_w&JfH0FG_2N-#z9HlXGv-%2Xfk);$qSlqUm)n3x%ttnu_FVfPL zje~3-saho=`xMc^b+*~Gc3W6ImBc2H{ciDg(&N1X1gWbo4!-^u0IZ`4B*_N54BTwz zE~w&L^=>K};lNS$Li;`f)Wa(5#|XC~V$}$W(}8>;g*vNx9Mec-MTmQ~08h1}E|>!5 z&E~P7bmQt)qET5rW>!A10T;+IycFsEy9Me=1t1wvLPVm3c9dzgsjFO$4iYo{864}-vfslpo2Io?psYNgcWrc@5IF952Zmbub?hHa86Z@0y2L4k9sflmaB${#3$-FonK<^2oMHG-5@R4%sXYSI!vVZv;bJ9u3LbvsmArvfci|JNgyU^8{`=E*!EBwh=Iq z(R>GBz^u6EOm-jN>ITp1OYCi_8W96_Cr3SBacDD$cvKzMpGPYvZs9c!*%frWPJ#W| zP-W^kStZH3(e&6=1|5NfpO(wSD&u3*V92ifct@9ByothSMCo#guF$P-70WLnLE6e2 zw`G`1?MCZ?(QB(}Pd-QaE38GWCDtj{f8?u(TB-pLE0p@D>#w;r(p!Rw+AeL_V)=6GlA6OxCH2%5 z|5C;EE4nKdx?5nrj{(bj=#b464XeWjX>8S|*>TE?z<@EXz>B2EU6Gi8>zIiP_%K+G!(Qe8{xu3!ibA=#D(VsSj8bX-fPW zmUk$}UK#Olp%Ww1X*8`oF^!|IQ{ybLFGiN6NV|e&*;a?Tplb_l0!XsGhkM<|)UB;> zWGjmvzLkT*J$kvk4FSS{N&;4U1R*F9=LM(g+Pch5rv-@N)TS0zkEp@SbO(A`JvBfF zGRop1^*Vfwd$#ZISfCAQJXMGbzRhCGzVWjtSq_C5+$cXUzU5sJ@N05Y6wd1jq z(%ITnhoY`yp+c+#NPBl;Y1NRx43%3=*rM>RyYETn#7mVJ3xI$}Cx|$CB>)6)UJ*Bh zFgID4GAf6~OkJR}RSa9Is5C!LB@N{dw*qh4KQA&T7IC9ub$!9BFY1WE+7f3YG?m91 z*aYKzQCgwquZUf3e{8S8%@W&GOcwg0TJQB+sAT7Rp_Ld-D!V?Z>VITfJ- z6V(4Oi!?e!JGqGYSy*fq>7A5ai;<~2jY#M^6o2TjbL$3LCY0c85XjYc2y!qYZrGct zSVMfIVV1DNH}?D;{v`g2lPWCbJU_tGUS#p#NksHj&|W`>p@`Ap80b{c(22x5W?=A+ zpyMZdYZ5sLCbD!sTw*~C+jYf9UIeggj9)e|qE1xEztI`V;6PD5A3=e5_<7wflg-U9m*+7U@gE$>&Ung>w#QMo4ZLtNa@-jd!(ht|o9U4lj2l<&|kJC=v% z+m-jq8Qx;)`$4?Boni|ugU)0IVhTp58gny@^srk9@S6rv_f{DwBt)(iER3Jv55-(X z>ger8p`ot;2uKG^Wxxlf^6{Fa&KL*4A$meqY1*bAIM*lOcZNRqbmpz7`;m3!wY06F3Bf^#IZRiLTS%DXE41?>gW}2ZwmMm3Dy-~E;pPugXCcQm zmfA7Z(ZVKRnvN%<>UD~6CO2YCy|E+qU1&czh5-qRCh^F^6GA=>7#MkwSDC7F>m{&u zSG1%s$p`r>FpgTxV@DjwDpX{xgRpEg)V4=eehrb`VFAl82^c-c35E_vK|gJjNs3y7 zm^i{?Gu%(ILGKjzql&rkEDb=q%k+n~iW&)sj6AeRP^xo^1^Zd-D^tdPVTS~dq-;FA z2*X3S3On{8@*&fNz6((GS>D!X+M*6Ue4IAxTHIDd$oJ91NXJ*0xRrmKI*F_@Tbn#v z2@=)>e|v>&c%cpyIb<+{SJnQW@5bUfS7gkvd3Pa_JcQdOa|26`AR<ear9ms5Rkwyp)R`OsLCy-XNhSg1KLv6Y}@WFO73 zTRBK8TrX0gd}Aqoe{rn^D67j>!Cnu&_cxBhUOwuf*QohI<#UBlj*<2&WFP~>vR0F$ z@UxBDU`N!cxtQ{d>=Ui{CRLTVsM$$0j1C+u8XPPcS1=&1xd{~M|K1k*oTYUg6%TcO_Xm1Eiof#G~)yp^@7wi6rgulw*tG!b<`we(pj;T|0-pgHLS2)waq~LWena%)dW2zflFi*=l#9a0~ zLL@meJ)&3pDExlW{vQ5mu6Y@2gsU%7z?Y_K#uwtkGOuc5EXicQ9q_$)Q1vV~;&nN* zsYoe@TF(Rpux4jl!%1BLk)9OIdseX!);G!~2P+{e1tsCSOa;jE7f86U?w&<-h$LSv z-%r&eVifZyT`ef3vDV4@bC?RS37=Sz_?ODTs^_+fG>z23w#o2SsDo`7>lk+32=GuL-@8&Pn%JwG=4xdNvg|Cq z`KpLvb$*7trKA%%iI)E<){W!~$v9Gll^w^;8z=DbKax;A4FRMpj5WMl=LZF3P7?CQ zG76THL8~KWM&(sQs~MK(B@ojn(hSmdM|eS_(!5sl+i5j!i5hpT4|4pCjft$e3TwK* z1q9qsM#KzEGLrGc1r}o8(G{=lG=myJ32>GyxjGF`4KMGt%3LyHmU>!x6(0(^i^VsW zFcz|58l)^i#)?j5Eu9A?h{Q{!`fefd;GfWu$-3&fZX)pJLt;8t0TknBWoKaP0%oMj^{f5L_^sdQ7ERtn{l-aPa zBZdyQ@o*@a=)-}X)zG<4LlglBFp*Cv_+VXF9Kw1Q7+2bgS9*?#uymKH0X9P1WICPrc z5j!T=1tf3P=V|!8KvEOCP-{_aQSg#Z6_u0b7B5R-rmFRLd`OA&j$6!Ed2u^z=!J#U zo&AD8kfz2YR0J#~1`&$S{>L|o1J%Dn1x!^crKKlBN{0jigs^qK-$Xr#=?rK@lXy4X zKuVaE_7E1uGZIz;ypdbZgNYf7>UO_kk5+|7XLvr}5640syH*J8Kme;Nf|Lv{(g2>H z#W9oOjv5E(=N{GVeZtQxbGQ{VyOy%zA7Bv$Iu^;HGT#e_S{>l^mMt4V$k#gFK+3pG zgpCADq=NuP(e`Md5Es^ap#}qYH}4#ioJM>kD<-!%v{5T^hU9;9;h3R2JKRcx`3AO_ z7YPw7T^|J0DlqTYUIwS(upI+98e3A@&3@Qh(QxX(@)V%8bS|s)8?bL9UsZ*T6xh=J z4?EHIIz3PaV0wMJJx@Qa>2f!r==Hh%Z#(k(UbkD&^?t|Y^}TMdtLODOF->}Y`d!aQ zxL!`@YtiWXMk=7s(CGS|WBYm@mp`k}B(D!82ycK7w&F)9j`;s2Gji? zKhmMK=a1KS(Db)H$D{dZ8z=jIk$Cp~9p69B@U;)t=cD!rW9M!8-j9jASnYaUuHPec ze#HoG(T2#5-`FoFbL;w4|GFUB>R-N5ZC)*_A(QAWl9P~E$I3LNAE)Hw5oLsWOp@-fl_(ZzQEs})f943n zbW?|uPSR2co=rm~&I^4EWn4D`kBuagx(c|3ir#{uU-3l>i@&FTuNuJ^F-Y6RZ>1+aQdJ^|6-MK;2gai9uM zYGx9up|^|1!3^@c#umJk-s_91(8i8o)0->)k4`$h4u7A|y5FxnL|p!-t@ZscSCKAI z#t9VBJBbWK;tlSLYHbHMoXX>gn;3lkN2%fy(C#O`8zC%?MO`zpiIXkR2@H!vQ`Mua zX=5bZq9ftFVDeBJ&5veI{FfE>U;6pF8M){W`DKg_<5wST)|v$vrcsLt0oe6G12br5 z0S;Ak|8ys_A%ak74Z|5gQS5#Q4cOi}*@!J?5GOF;o`MXw!`^T+soR?i zNLl+ZziDMTBCsaqSGDUG6}jsJ$L@8z9_MG)_WeNACl|5mb^V^rH3{8JIvGI++xGhY z)j#iZ`}E1T4y6U1ihd|A>-yor`!7KHCJIU=p)cxCil_0{>K{bI*b08-J)ZBW>zg+> z2*eS6uV32rKrmAJJh$~fOVp0CJK zj8#7^crHj)t$h({?^RI0TL}|d^4!epivJe1t|Kc7!bL4>h}6M2qQ11~+|eo`-nI00 zV6;&(K}mU;A50lJS-hEbgjD0F-KO(%oBTs#zZp>R#?}iBJ6bhZ4$|$Mz!E7?!pH6Y z25)E(7o+-{8}l1C>6z(+cmIq|Bt#05XI-}Guj^8;&-%f_(Blpm;{;H&OWoV|nTVJ) zC_DfR$mZr2m(Ki!ff?!)i@MCx*4A*A$tn*h^mM=l@d8E87TUjI-l#U z@D`f>12sm$8^jgLg%hsIs8@)``~9Cw=!pr$X>i-T9`28IN{Wf9Mwb}Q$9Y|=_=alT zsOCMORZD~rW?uB{BU>kHnP$~bpRw!*YSKXCjV;nsm->~_Y`lLvXgpZMW0+b?$t13j z+Nk^FM{~KH5i}Lykz4z@$&}sY1A3QUNMrRXZT*4(69=Ngc?QNr3<>j8Mm$``iP-WdOwRpAxssonX9i>{_FX~fGs>C~R z2q2*D&oc%ESzNCZWZDp{tXGM%VnFL^$)2#_O^2b+(eL*-b79`@+!Z6Gu50~Y0CLP} zTUlTLA3^eX3yS6XeRV1PbUhYNdRVslfdukxZwSAjXjR!uMNvy_8dgIHxv&mRL9afW zUjE%AisgPn0{)b+7n&?zWI%S<#rS>`U ziCGLKV#*bxffH%QNOjN;BFh+NOA>L|ry63hfCBbSRj+1FTC6IKV6>4R^#SZ7`dFFUg_)74$(QDM^_5rKLrJ zg;G|B2xVGyl*mlz4<>4!>AxbT?(>ESZs6)=OR}O^SBx|I@)K+gXLXCo0gCY;eMazU zY-dL%l=g|bfb12%HP;~=JjeRlVKrZPv=rYGQ-&+FnMRiqz34DTL=LP@HJGF(3cs}9 z7EMqS;m0t<&ZfM48|laeapCdde&Axn)SGnS#v2V9!L-)(x{$3{o4GYtz_{^9{Qgr{ zg3JMkbGjU;OE$9^aEhkO$XIZ9B}CZ8hcNeg`+p(Z!Y7qG4}DJCW(qyP?uKCTFtB?n zi`H=mGxO_s-5d&aau_I3*Z~6pBAZtYgj2tlB594RqG55p_S~pOzJ@c*^8BC_js8%n zl5v40Q+Rbn9y3%swMh|ycT7A`-T*q>uP!@22LC-rih4ek}ihtU6*J8X`Kn2&FMdYV^tTj1SZtFI+l z0;Udd$3EK_=W1{kgs^VSh9o@7e4&Z9$9P ztBtV*kb^2@6@Ed>f)ur$TM#nlpYrH-Rv31ds7mI-cvWDqA1UW0I}x=F zwtNq#z>xN2);gNNho(iKmBkMCQC zMxm=kFg_w#W`{oEtewUPNL3aQjLqJ%M`{f=0!XJr|TwIpA}63$_<_Vuhfq+ zIZjgnadwb7!{smb%j)kr{%;mu7dJO524t~$HNbon)*j$mz4oJ>o)rsw36A=VE#l4e zekLXms=KV%?mJ$1!DI6m7xDv^x^z!09?mug)v}c#DN?{-`yq4rilDR^W07Q?GX;T* zKx@SOnhuXcYBZwKJFm+Xw%|xCn-w!QEjP`E18p%_b|?^&;>BC=`~kQNdF>&Gky7_! zgFt~6_k0gzB1J1#xK-WtDd44-kP^IQ64(gYij5$Q*AbjJw7E15y2VXVFFarXbpq+% zr-MrUm{+RT-L-&zL4?W0Bd`L3fu8ov$^{@U|IYg@NP=iuP@?{=^fYIF61k+83vP3= zL^oaJVgOeSX=^TEP~cNy-XAXLgF@XD`~sG8Ac-wo#MCDS5vL27BD9O#5jS4lhbTt1 z1REv}IDt`NNc_ z+{AX9DJ1pxO2|6#bB6Ow8w%oirNn_vID{-!#DcL!agD=?dlZcXJZf;Vz*${Gvv)Bo z4)j7&VT1b&!wsw&zzom4oZ@jT!k|(xERxMHw%)2B@AbQ?h+iqDrCI%-ci8npTiWbp zhAJ+Q&d5oQcy8_c;#?bYzCbaXvx6V5CR9TUX{^5B+otgEV3c|*!v(^4AG z7@`HfQbCJ+%+o=Ujt5KAa1f@KiqlL+yie*Apfq_$QC0uok4g_A_~9|_9<*QG(H%>u zX^*^1MoLkfHPnLswCbO@nXXbKw)cD9pJ~M}3E{w?G5#UQGYrI*K#m5Av#6WnL2#yG z3q$X4SS|b@!*heZi9nAr9+#>im>vfD93)NCt=-04{2Ix6QdPw+QN+d;m808(fvQZ` zbVi2Qr~=7-u&EdiUE21>`EhU@Cq=%j$Ez8bN!hS-0CFTj~W3hdVzCg}!1kk8Im|GqpaLcY!#4)!EQKpX;*vs+g zU`Pt?@bJNcO1q+tb@YRCBI3^Br&u?$YQa zH`RjJRxKD)lQSWIGe7EcDBnrk8YGVk0hAz2WMulUExD^79NCL=fjy5A0pw6{#@oV& z>2!tw+)gAKBQKUSKeUOg+9s$LWX5rssFaX9_91~<)=BB-Ory4gXQM@JZ zTt((%cUpB?m2zN*-DEkl=BwKVd#*#5DeE6%Sw(zf#{%}2Qf~uWi z=0LIoh>DYu|BXSB^Y{2Bq3EodohyTgMltQt74M>_MCmjI99PClZJBrZVDU z+C*G2#GnC}x>_BT$rE6;L9+3MAT*WxKD5}A+Gw0Xmv&CsumN&~b*Fypwkivd95U4eik4-flith*2x zHOLl828mUdZ2q*CFm%g20^Ut*X>fZmZV0@FdMHh$0a!Gv<&e(18N|tXDSgP z#i_pF<#E>sn@IAG3LN2=Gntny%32wm0_88bUsJWA-R^-8qo%+b&EW1pv(zbf5%Nuy zz&Hn!q%-2+vjrp!Y-ifCy}W}Z74@|U!W&?wf%f|+oXbB5r886a3$1|92%ulx4(1M% zVqJKKL2EHQJnR}%cJR+)nI{DR-3QcKOb5fgY_v#3I3Q zhc@kgad6j`B{a?=vJtzCKr|$2Ip6OVDS~kp$u^SKD%DZ$UUo88xiE$hH>RpPQ$)ps zURJI#GzSp>uI_8J*JTT9m&AxN6i&XILmpeTx8VC!g0(r<%`TZ>SQ?iT0w<QZ-pwG%_%6O-L5YeC%i-;9KYKP3Q#DQ?Wv83AL4G()ap$fl z3!d4kSIuc=xM@)w*2Z zDG9HX?B;oGBGPtp_gV=DR9&6p$8>ji6bG`%f=>lv54F3%zM5`rBe$bN2Hr)QkK0g( zk`_hKotF9`V5#L6m*AgWUCl*cwUH_EE8^K)lcHe{r_g(PK4&nA<(&j%Ka04M!~O(^C~(x>StA9D=bh z#sH3YRPO&#ep7s5mY| z2k-OHF(wnKXFs(s+c>QG>+Wf6t)1k40FB+)v#Q0n&-xm`ajtk@#wp4ampcPwh^rw+ktCWtg(UXNp=~*Ia z8gvf^fSBeKjH!~`+L4ku2<3SHi#ahyE38noMr3tL?)8=aPH8Znk6Zh|rMUR3bj~UnE=OLMhLtW4Ag@RhbEl_q>0-)@H$AZDM49L7qJ0LW44SNa00pT6llOE%=g`l62#F>bq0dYNP^g> z+|>W+J~IulbF!0 zDw;^1V~OO!uwqKQ;aQHxHrM|LQZ3ChG#mW<52$l>jQ`==2WrQ=@?4??2a zXj4!D_{ma5)aq6uMz)ilGUYVc^?-M@-s3KY-?Ov?!%;z-gb|h*9G|qxa9tXU3*2t% z5Y-^!CyU?hZ+B(EVB0Xp;;XiCgW1tC_8Y{DNlgU?Y#Gxj+Y@R$5tv)j+Uu7=q6>}& z9^hScL{(ltrnqxp4~3t;lDL5YY|ppg;V9tMah1!1Y+6{{`77%KV?80Etehk=71Iay_Z zWV{FMl);ZWmfu;{W&nr#WZa9?y{U%d0ct(R)ZejsE1O5GxVDunEKUgp<6DhgD)p?JS6?;{SX=|e8Sp&p~A#C(`W`AiAB#^ep9`n7H|;ra(WA6g58y6VD$2 zID4aW%&E#yEe#I+c`V1&JABVtj_c&`AQNslkSZ8hY}SZWbL<3vg~eoZBi4{4^cadDMy-ITv2>Y(e9ZH< z3!FgZnv`w3J?8DyT_l{GxbKv9vN^rC4JlBJuEsq~C)4XpY#pv-pS}ynO@d8KyV_PG zkWzMu_hJclgcFS2NRWcPSj?KR+KCcFMzA8n71Wg*OSd z5fc>E`wSz>rd>+75@))f|He^nL_KXQ$meENIKsL@^&cu!DkImlbSbt?)G^&_j4-9C zuQ7Qz_9kmvFZ4W$!WOyGbwHm1XO&SDRni4MJWHF#Fp0P(Xj;RQ5nX4ElRjKm0fxf` zhI2eBk&baU%>04EmKO#5o_)BLcTd6obx`!bQkuY~se&l4ahr$bWGee-WL5w?=100N z$8R|xxcQXY13IXiFlEUPE**zX_=WptXCi-JR#vE7YKm{FQky+(L-sF~o<*?%GOlHe zf;x~nb9}nc{XkMiBU$UrVcow+*)-QYc)b@^v@)=hJmPW3T8Pn=q+@vu#6}_=05;1~ zB_o?XIUJ$Fv-*|e@tlIIDBgIzeq}Iao+*lrZK{; zJ@rYwj^|) zGltr_XmaS821RZn;-N~SFdiBpLFH!)hCYgiSXgeewxuB`UQhFKx$Snon2 zvmapC1A;_A3mj4**Ll!INW5u_u$n@$*Z&uhkx4+Tm9 zMTXvSrgU5wLinx3`M5NY)}GZZB`C!ji8(F(i?)r+X4rI(2jFw&Pe%m^k3)?e(P3#^ z$WFi$a?QloGMC51T0Uy4mJp-w?uHtCx+QLt?K&yS5SBnZ-v zv&AC>Nv(k&vGOuMMI%v`bo8=7>-4HHn7kTQ2|e`5iKCKLzOjfe>8B>6zMgqHCYF%M zz7=&rml)yI3uc9 zBnzE?VFK%E2dpx+S%>8VOP>G@nemI-;v^B4t+|eehU@_O$Nr5S=|WQxBMOiNuJeBP z763{fK`l)&Mbp25^#k%*m@PcmF0o^ur}>hp=M175rw&SKLd$b(ed1+cHX%Y&}6D5;bXsWPMNMN0bjb^=x91RFUGRrskX;0$RMF<>ZN@gI5az*i%R zNTA`MKcK_us$q|r(j+vYU+c7G=sIGWhYK^fC4{Ost&Qf9@v>gI|ebc(fA|<9m-d1O`xJ?%zX(Q?Iwg2$vw|=Z{Dbc+`Jd- z&2C+}1%R6wo)DzC5Lk1(#-P1&+rS%}b&98{MxJ8~Pzy5WlM5{_05|2dyRYBn=2*K*OTG+c5^!Ex8RlKENoDR>#tEZGry;p1*!u4QDF2Fm%%E4U8`g`4= z4<95gya|t?K%;W+T<5MgHnzWKUG)}?4)4R=yh|(bZ?NE`t+q& zjgtLwB;*wOpg`_m3sGYkOTxPC$mgHQvZcw^E!|Z&>|ed4uko($_-sn^5WR`D23{ zG&+M=a{l=w?@iE(6|!57h#hhgT6J24)P*wkZ3>8CN`U0D@O{r1xL1^jQqgd$yC-sw zw`YX;sU^E(SE$gU*4T%2f)QR`-pfVuy(bDKfZI&*5czoWH5vi(jWL6a5=-#u$Rt7J z8>T?EUWrA`-*KW|<#SrLyg4F(NGJ}aqo$gQh% zDE=>TWJ++7ib*1qE=(T`ZF`n^xqEwCw5>yDgmHNF@bf_}%v>l}8spgC1QfiZ3!u3n zFNNANDxohpZ&9cUnuKviUU$m$Gz${hG{y^=W_MOrY@V1KI=w?v+s`ptli5kKj0~gP z^0x?PR_S@uYF_TIwd{6%PjEILaqCboTC3Au3hg;Pi91*odmo!3@{y=nUnUG3xHr3D zPn|xT#U}hsODPm;3QoP;pzVi+QgzeF7D7YG%A^*-r%6-lgJ~fO#KyYPKUCk`b4b@S zsCL`N?^4)7MkR-J`oio%4tccj^i{Tm#E_6?ibT;l=G{YSiK}%Y?mXbn&65>bb7zq@ z=$xJ`@gBC*Y|Z`w`2D_r@|FiNkFg2XdA`47m@p~kp6Fvf=14Oder!sOvK16I6-LGL zUZ|UeU9Wznka<$YNG7FpWWVUO_6;>3SZ?eJni}U-jyjRB{1j);0(B~h!)9PEfFYBq zB4}x+wjGjJ#MsK4No82)^WdlmBs-G1ZNyd~;!nU^T@K?7V(+N%ob$de-r04(KLw)= za9A(G7JEc4`qjH-y_VEkJWc9YaZ=J%u-9+Kl21J?R*Y{g4afilB)gU#*jV2bF(WrH z2i_pxc64rXa%O+0YuNo=KJ?fOjq+EG8NEF(k&{xh=aJ3A0`aJnsq5d6RMNcd$ov_? z%?&`Tqwp@ZZmBfy#gf$%30Ar;Kmy5il#nxTBC!rABRGx96yS>|E zNeK+B-Qz6=xh)X?wIkJ7H7VFfRz535o;#tyw{M1i-r`5-Guu)ADwL2eU@SiqJO|>+TwI-+(i=Lkxr#jm~ zYBPNZAq+y2rcy3@FCXIsgdr;;L=|8sx^cXIMM4uUiZjk)*etK(Ivs&J)mDaTZlB?# zdo6+Sr$>ixp+G7zbqRio93M)`GZyPrzQqN+UAQ|}w>HnOs+tPyF_;bgl+w-bkVB{@C#)slr|jr*SQgZS zqvEQYp2?w6DPW%ZoauTE*(HoRC&>mYGiypDw7*JkuJvDG5pEvkY9i{0id2dvvsqef z5$rJOY}x>vX2(a6;K_)_c+?p@mNKfgE;KeKfVArah@h0^+ z6$fO~6|a=8MfD{;m@8drX{!|ga-dMz<1TK87gYR=IONc&^fNK7gE~V09YW(|7W?1% zWC2-zS<*(^fNbZ~jRZMoCZ(d^yJo%@Mr+d1Hf^@5+cmW@K_-nF!P^*vs+j9VL(n_s zls3&P9}sWQ;hJ1Hm~ELAMxsESG9N85T2hSWK0-x#a28D=wJjbycd<}6NkcW*dJS3Y zE^5wDeTAh%@Rwj$3B=cwfS*_62#}=b%Ov?DR8a>qiQ!7@7i^lyUP_NkI*6(o&4*7l zTsX~rRO2tNk72q7g1A$_^Ij7mZuI>Tk@?(@ux)Cl1u!!;i4(v?UJ}4V)Uq$e{z?Wd z1NlXSF|d0f4ooy%A{qI^N$N1E`r1L$L3j%&YuMunNkp05B2>-$d-P-x3rCVX5}9NZ z&ZLPgtWfHTwo%R$v3JB&$ros&#Bq}=%r{q!W#gASirt`3hudEiK3<<1J(Y+Q3K3%a zEpj{#IGz!m)=r+x@61u6ja-ggIw@tt>XWJ9jJ&l#u_T9M8m>aO**c3H$BbcqC6}7O zf>&XXXu}o990v>a1&C>T!lNcX01W3@=0_2xK2%9|L3UiTHm-{JH5aF?%1T>I<1S2! z%%iG0lj=^R+!Gre#UOBsvf|`9D9N@Kc1Q?f&CU7C;w)F@Z!QaomH1>Olb1}_rCn|h zv9QfO!ShdSSUuTlVWf_Wou>nk1nL_7O;45mlm3tiyr{DgcCix1#?E_edez5Mi-1`S zZsD<9k|OOrOY!t_My4u5Oz<5P0|cD2Q{|Sp0-Kjh{f~Pcm^XKNgfl~PwT32gX8QY@ zU_HKOmyqAbPfdlW_)A0&)-Z#|+^Yndwo-wxfQ}9fkP=Q*7FTq4*$SsV`|pp1b+~66 z3pb}=$xSWDTw;I%v}ogPX3YOXZ)y5exr?$sF8Q2r5S6@cSZ$9h<0>-o6yS!92Dmo( z@uUW=>zG5SGE3GPX6i?}8tUoOsEzWuWjXNjqCmgM^E|fA!Ac{5gr`op^$kc7{EQW> zC}_~z!RJ$79D>UYQS=#ZqkQrZV9d3kV~PW>S+#&Vh8%RIu==BH^I_TPF=)1VSV3pB z19*;M7Q`sJot$AQoC|_tAVSIL&ZE;Ir%|h*mEqinu>8_B=}{f<8$ei2YKtF840|$D z$kl})DemG^CX6&}u=$oFYJAqAtJrbXZ7C$fNd9Y;+lm?7do`s2aqeThQ&se)l2Nj3 zJNlAb$VQ;$gXS2@bRTe}lBCg}i1bLwyHiV>LbKz=xw)apdBaQ~H`8ak!{SU@8%;ql zd$VeJzuXAif30s0+L4T-tsO@tTTa`UMhGyS!EYujeDbN{jCpM96R=7_qQ7UEjm2UH zjcy47;# z-FW^tWs`q+X-%=od_*nFRsI=tJzvwv4D{rnXY3luskUgk&l%Sd0nZ52rKNqJsFj}s z<^Na5HfM1?D zIIBd4Mbc`sI>ik9vB`S|7u=XOdEGGUR^`;(O2wln=u6Jzq}Lv(OEj_v*Uwp4*Pd4} zVaxNMo0h@4uPIu8PI|0$wcMrMUb6x%>w-nvvByf?QMeD#U%ZD5W_$FVUbx{7Lm>=6 zH`}k168&ka9)zgPTg0!GtNILi5MNDP5-){msl_j{@TxQh567665|hCV+YOo=ixAXt zY$KbZBU3rl9|QK(S*xddU&K2M0k>Q}tkgO*%;7Mo4BL--T9KyFUw;X&U&>&}feSC& zvxnt!*(^yoh{J&!6UWsi9s+o<;bs;4+q~WYIKsHZV92vg_`%fFiGUxHRP}&rswbGV z#kI}rtvDy@O9W*APq27GLr|gBUPTD#GGr?oD2SL2b<{)(zhL#Fym}-BqkVS`t`=E3 zBaJ3>jN3D4(@rFe`=pt9IU7Olmoi4d9DNpzVp#bp8oqu;TG=YB)YM-|Yy^j9P0ZSmDIQ=k=cmzq zIPf_%I<@pKP)sby?pJ!wjEE>aI-1pWmeRX+T$bD(Rm@Fp7i66*Ry(GzJS1*QCQ_ROX++=P=1#KRTL*Ht4Xo7bz`T zWu^nR_th!h^8LN<8?|&)QG(+{ttM^oMm+boct5+tHotqe4fBOBv9PcQDolTHW;(v_ zW7N(1{4j-FLT(60G*q|4UU&Wl*{sa=YS?5VPURNb4`sA+j{%$48v}a`U~@ zVp}-7G-Rp1)p;n_m8c-hpV-BCFO0Dd39`8t5aSlYVyAhk?vY7G3Df&WcW{MLPi^SL zn)~W8{_kVj_F=6sK{#XQ8_dlN)zD|Astnc~lBQR-`bM)_c5;DI(w|x`vY+;&usDUX z+1-OjeV0P7$et4?OTQ*i$YLBIj)eb$lrjQoB5sqOd$+!U zmSKn=B?iNeJ3x~3%;(__>oFjgnci9hcR8{zw02!hFe(khy59z2ytymt1)}{%as!cM zbOgX}>F$=(NxRl^#^@d?T2L;}`n}!2`pf7J@oSdIZz==Lt#A%&U<5&~nVd~jHhQl!`mZr@y(;8Zc0gbuaSVN`(GSi8p_HR| zS_2A_W;ti+ZzR2ZaU|S2f9sWO9j*=Yr_@tos1b{ptgIDVntH~J)pl%L`azZ^%wOg` z+7xG*o}nF$4Ma!)`W=A$oOyE;O^(cCPt%Yx1}E}SlNwF8l}G92=<#cp;48A-ft`dT ztc0PxxF6Ta{FR|!cz&NqwgAO4v}I>%HiOir2!#kbDhwpuw=ci+nY7b zd=HR-?eg>P-R{4=-LFpm-8oWaz%}t_#0E?R*E2tkS;{;U2a+aS&>$T*e!)PP7&bM6 zW?araNn`!wgG<`@F)b3za%*IG%22SOf*@r1qA0~&_=x3NrO4)l)X*T1Jv0ui{6CWxiur>14L%&h1 z6AGrzJl&K8fsVxbf?s`vK7m@p?~mb9T|1hKH-~mxDxR zQ$8$|7Kh$8?V-=nO!%tIz9+NJzFkgc4bTx#W@hR5xmrBIW<|!lpP)let~R;-El;Wg zpH{i`sc|v0#3;=xa1Ap@+Yv=Rx#=N+0djIfVxv9o8mY!(O(LX%(_JZ6yA2$>;O8Zs za>FD=!ehg>S2(T*N4Z6_&^)enE4g{$dbMUG4$jk){5NUaq`*!W?v|g715T&KT3KQ0 z2b`YxQs71~QW(1w7rNq>L(F=^iI^~k0Zgy*DSHs-HG+9lps`?BuoA6%!~X7YcEs8X za#OoM?+{gQ(HKHSnu%S-AP7aT$FLqD3?9&4pYcPF0ZW2lRIx%(*hQGSiw!B9kHTDJ zUeegRSK)wfz*V>Wj0`0adljUwlPYf-Wfo!-Q+(1sWFk%6bus zZB!Iu8eaqo7D9)Ft4f8O+Md?%L6WSKuPSI2Pqisb%fhfvQ~jey~k!npvrW4 zUwS5`_)cg!MB@{k8yI$jL3%RU_}DU8Ffo`5SwO=%0%dW;H89CI^s`2-mF;SzHvZ8X zKejJlYk9dRM3*!?NEnt2-FS)>Oa`pCa+Os9gyzGo81NaM?d^^+rmt1ZN>?0eT(Hqv zps4sx&%2qZijz^uJ~<7p@pa`fT=XGXW}|=^r~M-+Qkj_Acduz}vtebOb#^<^Km(9& zsJv7QK+i92DX5&`Y&?lP%o`qgFKGJ}?4H(RL+k$ONz?Y_0h*y-hP35=kLcT|3s$V+ z$3%`7K4~iiEUTlJY6SycCM87mF=^n!F}4$F`>@EmfXuLalqf6Wz&>bq>_WJBHRlz| zR40k^3Nls`sf2dBK?eFgP`QWT7M~26gdqgJXX`#Pr}L+7f86UtYV7}q>Dl1c01~~v06c7}pD;2Efsc`J60VhM$EF${|eHHH-fkve#D&p&5T^uj6 zI+TZl)>^6kqXHpB&dKE$q-o?TWYwf)bqG$%%ZW!V)9qPBWop_d65jLO6(V&7)79bR zQLa9rM%4nQ8FeeT7=PN^R4oJl^&Zo#Pp)9WBn!!HGyv=h%3RJw&|ZY-We>;wë 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%0A3ALV-{P3vX?vOS({iOkUfti!HS6 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 WFlOav3#bcXdO3t zZUAA%1e$s?XO3mBY0eICUzGA(XLi%}K`0+q_Jd|Sikh)KKeV4F6v&f;&CX2krN!N{ zmUQr9KPNK?K9muPOt&%o`iLn%;=Y{)_y`JtrgfECgVd)_LVk7&O#q;(NQhcxm z;<|9OCMHb);9C*B4__3sSc1qQ5;}pS(q`#n_!>|nluq->Tj-Y=GU)}dI415F_c-j} z$%=Z`4>>uo>YI)w?uk8ix`J3N=RDJ8O&T}wMJb1SyE|a3=fp=RE=+!aNBCff#di6( zqiSGGmkh}bzxj-%56Xje0Nwyo;(QEjHkhTq6LF3T!|PcU{PdP(=!{j^u_ZSUkD%DA zU(tb{{0R42w2g@0DW1P~{m<@V%5a{WJe$j9LkCl2tp9s2TbSOPlSfaQxX%hHL<>H2 z*9N*{Ql1814|El@x*r3f3qkrXGoDB99m~pdGbF|2*#9RRqgB_vXq8VQGeQv+_V zzmRJ;}=RT5{h_$|A(@qJ&6 zbGb&gljnF&zdxJqQAyU6{sUyv;S4Hp5eP{TfkYFk%Ke_3SmZ0dp`h0S^>_7jx3hN~ zB%dG$ztTg5ZPSql*iNp8<`$(<4&ttrj#hgdiZ9@ozeO&{=Ob}B&N2q+-l(N!G02kKyXCk>Jm@;z*NZYI(*uy%&|172lA-|zrmof34pRIClF0_K z2Ta9@ddW;pUnbq}Kx}OgCkbx?SFY&{=o}nOJa=r3FKUvE?|fATJ}-vf6;fR;qPoT`|To};zyftjbRKeX--N(2w~8}!P7 zlL`x4U(oqmlYqE2WqlLEA9w1C*fpsK?QyS<%cNxtRtLP9>FmF!yb5{e3RmTGnl1n+ zPF%nzZ0%wbAfe7_&`j`aIW##WM*!~$I9}EoBL$)A58*{c)2RK4y?ch77;g5O|a9)4@BY;}%`AN$g1OzWRt_Nar?iEdw3?-Bq_=X`mSV-X`~xV9vq~*~Jvht__Hiq{A4V8p&1h_W zV#{`wk#<1_^+4}|#Cy{I?sj-;z^i_G>jvzpK+Qnw&*ef6+kz1>&;HskzPIZ95-ZciNQuTH7+XAKkkk8L_dXj*pDAd91PRS3Ui z0xj+oyRuVDXFFu>l?VHWW`#Xm`QuxEuy?mHi&UhoIY{w5Rv2Ia&xv#2?;%ktZ`~{1~eU zjY(u*KWKP|p)))@ihvb37BT|wjipl<4oXy8x!{neruyhKE=HV}0IjTIO7||E!4x2Tb2#s|~lCN=(#!hQDzU?(H ze(o4OQc6dpUCgI!`^n&KN1PvI;&PPSOCs?ce$Jb+04s*?Yym#-1gH5HZvbIBNTtrBOOb|ASB5~4=++mfGkDz}5$Rh_m9p2s2*M9)6 zu%}z*>SFEB3I6~Bh5rC|lY3luZUp}Tw!x!lu@VZ8K(cT0wYYE2|Ke-C z&C1FRh(^RfgDFtD?78a$u|SvZx7=d}=}Q7N>{0wlscRH?K;mH>%gH5LeWY_7)2d(S zM%sC*VJaH|U}xbWCVXdZ${~Xh^}7?VrVWQ1R_tf7f`PrAFZxr16SGlYCz3Nmk~}6` zTHA>hEYo}ml%y8w0+GW~D_trWX}Uf*$yAzbOFIf~I5lA5xXg$#CQ1rlov#8nvw%DZ zS#sdTjKIW!pfs5kS{lSv4W$mJ1M^8&LDs- z**cP#e1_Y)$Yhu8Ez=ex4&UTn2k^~Hktane{@Q_Phj(t^oZOy)av^O<`>`=uxqHVVw6 zVV{f~b2s|A#9Gw}AN6_kW8>Mp^1}Ll!)0AZQws(=OCF=P z{(K&p_2r0Zdidp8^sF+H^E+H_4wkB$$gn%1pEk3i@cnb@{y5p8z}OzqQRS&nq{&ID z-e5>5EB%Nm``>0!7T2Ys(FB#sXFH(-Hr7Mx1^mNn=#ch<_qa2j3V?OHzq_d*}Trz}nSTSl9>iz0qO% ze`pr{1Gv5@oeZ$!CYl@A@cM``sFUjH9c0%2N@xT!^#ZGJ_wT~rkogAe4f97+zQ4_R zoA1Mv@JA~69HgeiHGjth{~bg#pCfsUj1AV2`bK0hM9vYRo%i!)kzrBfF_3add47CE zR4hGQd1JV1dcN!hHJ7iM(4u zdas(J7;&K23%IR%AY(W$!olU+tPf?}mDosrRfXX5C`~e}=faCgnfvc%Edlm)C$R~g z@+)t>e^arXPKCxrp*VYpn?A`ew>>2Nha@5OubW)vD-W!G?q3;8JOv_HCbnz+W(22? zCR1lVZKH!T*X2y;4BywqewaNz!6Hj?oV@0~*|rKybtq=^tonUv?q@VT7UGMs2qe}IY-$jTM{vB=o6N2HM zMVZfHpGjp;)g5fZd;7!0_Qp?x_wR``nmm7w80b$*l+kni$3oQ52)9j7-M-11a)j>Yo!Qid zkC15g9b4z;*0-+W?S6+g`r5nKR=VWx1)EDU6D)AOoK-h#{&HLyosPPtzbziEU$~ya zdg)Y`gSwvEE8@SYrqy%(g`dkA+6hWsvJH5?;0jw5v)2qXSHW9+OunFQ36OLZCLf(G zkWyCvMw)<9#k;JdN@MFPLD+O9axCpM$5S=ny8=syWpF#wAIm245aCH1jU;n8p>k|V zJILHSW@{314f7#l5NP}Axcv{{(|3DxvDPVi>ietmdg@VD)jV2=dVtd1h;pA0Y0^f{ zj`{n_MpD4}m3E0A^_~FN&LD3M?2oAELVD9{ zjN*-XS#`Q}x46cvoH7d}q?`D!&>+czeo4AU$OkXS*iVVv%_vw}3dW(l|3eOX(Q>B~ z*<68Pya`r9MhCz>UtHjHBcw8*1FGS7gk;|8os@5t=KeoO(NrB@Tvb|LZH!nR zo45{)%Lf3dg3IaDq~l$|=3h1WNtV1bir{!=R+c9*Dt2m;T#v8s#MZCdbxxcz1^5wB zlhUph(h`?m0R#yeH(y!bdQQ{}l0`LQ^sQ3lr$Ha7jgMk4Tx#2WTAf~5o25rF7spMw zC)2{V0-PnzDLVz&q6bT?e+j4-CM7u7*E`%`6?c(+9xtlQCv|Wt4)}8G_2BE|io~?$ zYxLcz?vH-Y4!>(a>z8EHKuv*Mp|M-s)OyvAO0GLBc?hurHvO&*!;6CD{&!A)nPPAy zJ47mZm@P`bi`=5YQ;^LrC^$D<6*+as7pqrh9wKV#wQKTzkg!}Xruaca*9&~7B~mSICAdC)5XM>vhIufbVjI1+Mi;8yAJ??H^lLue zWeUJ-HI>mEaIm6q+kT(Jx&{pY2(bi_%AgS=T=mdQ?BTtwFQB27F(9GzK=Y9i zQgRqa@FECo*kel`&4wTt7CTC=Ap@jEwrMFNm!Dxww7f3Nrsk46Zm&ib+GvBjo}Et5 zr{g)awcm7Qd9K1*-7wnxr2;tvgM@-=NQM}b2U{-vUJ02A-I`bmdL-2=+*><%0Ka(& zi7#ekSN!zA*yZjDgfD%~gtRSBnq!#Wv&j>^CeWhKNUH;on{M9Wxe2h|xJ_&4X6_kB zDBV(}PWdxzPDlj)9Z!4blip{l<3Ek3!>_Wj*)E9d8hRX1`6A1BYYMn07#a-6vo-EJ zzLN(u>BL-Az}oVf0w;+3Ydx67l$+;w40;AM_E;(y11+n<2aBhl)^GzaeY(tDc_h9% zR&*%tUb+>@>;dMRQGOcbu62E(W@GmZVs$^Zqo<|-lQ=b+bo?w%P%3+NVLD`^N1BB8 zy&QADLuA6yg>)bZRF*$VL`tBh8+}_Q)emkY)Z$**tX&nfIwu2Z?+W6oo8#i`whmlu zatX$3*^-vs_4TwZZX4c5px?JXDWgt>l^Y*l3je0mj+du&AHVWvB zAA5Z7Ks|t$;iEA8Z$)gPzZd?NQhpc% zy`xuy#-XL(SB^iE?sX2V5K}42vYnpf$1L&)w8M~lItI)~m70s0@GON=gz$2UkL2Y`V-ez?&h>2C+_p+Q?$#H22+^jXUj%R zV^LdSr2C0a4qF&wYK$F?y2{~NUmJ`2%Qs(Janh5l1QR9v6jk1R--Rjcj;RvOJ%UyA znLRCvz(p^8RR8SSl&PWrI1Hy~oI#Td8NXI0Fr~?cQVLsK$HJ9N_47>sM+I&q-+;H9 z?-;s(ZD@GXl5F}!3S{aG&QWdXa?5Dh@nHcR=E_1ZyAme=X|Ur2IlL4i1Qt-LA?`>{ zi##=n%v9FI=J2K+keiv&cynGbOI<42H1|QLfd>Q~hiHLSNf#h{u#$p2a7EHDAHG;t zO0HG@?YHk8JM1EaScUid9eFC2b!T-u2q-+chXCk&?VdVn_pQ?t!HOCxgA;#oHJQ7~d&qXW!pIjY*7{QC!)Uq%!ymzlh$ zPYgQbmt&cal6*ciPFnGkzd-yojDv#A{)@4gl&(h0e1+%q$9=PjCVz2%@A*dDLO(k) z!5_X`_qT?*o0Q!b8a=FqX<2!#IJ7O{`TbS`)CY%qMO{So!sVxq4DsX!D*McUh$gf% z<->mf12f@iYQxqkh8~vu%$fTcg=;4mpgm->IN?li#$l&^;eMF}YHx4yX^o1b2F99qzXv8b#5|^dP<7&Z0n4)-3QUj$i5xGneLM+be zK);@uklK;6>rL)8EzKWlkEm!8&?mcR*qs69#~_5>+mZy4YYId+K^8Ryh4hV1tlWmt zrIs9QY)AU5##j$4K8g}F90dfO0}G%yhcuufA(v4SVvQoh%Uibjagj%WAU|jn>5Z@0 z2x2OqrhfP!)_|SEGs{zP|#%-d!xC4sZK@cMue-%?1N|yHpF~W^$mJ@3A2Rg z6}_JXv2;@#UyW3L961Yo^^S6vy>8+pHX%1={dc@%mVYh}y*oC~RF)tC4=j7lhOwni ztbEAk)?DdBT}gaba<0lq!+V0p`1M60-`~H=KPZ?H3x)B;WlG2gaTUBLbx69ibGduF zESAdG*TjR%-;2ntZ}QKjKH(FX_|(cBbQxf>Jt?N{#CJ;Yv8&2iXJ7B)olUH)smtzJ zwPC#C`FnAvQ?ZDO6Fcjf3|T&IFdq_xUW+Jf*>(;?ibV_72Kn?66B(nB{39iPMz4uU zN+PQ4m!P7WJimuKsEX=#9(iBoZ>W-!kWzawFkg>2~f1+??*|JFglP*AX-C8y0WIAuo367sKNm= z4B-AoL6Vfv>bNx}xPGKUcn}(HD{kcp;Z#@@hzvwJy0`lPgw2q!fvwyoxHdw zc;<4QmLhD{@jX{7M$C*ggO&s9-gUq?o*ZwaK@n56sqF6nQBWFAE zlO&l;SR6#0y>Bore#XG>8_aJA3BP<;VC66WQS3p@%qhL;HON`gIG?}~O?r#w70(7&N=v%585S#vz?i}Cck@Gt^ zPB%Z9H)$M8JP2ju?bQjH3J%ANz?2iY=`mV!!NF$>Wb9GlFi>=FDL5qA#rDfK1GyXo zY(4y`i;Pui;#_HF_MPSyWqjW1{7R$nJEyOtfvSef(z^KRUAED^nH$c0xQfyjCNS@| z1Tfk(S#i#lo3)8=`XT4|j)>1evrSiYAZtg-`<3!bNm>?r(Y|FWan+EnP6IxirE2#y z72|g_%0~PV=54YZX#=J-yu?f`wMC>63^&j_ZB2HZ1(7ND)+%=Ob|;&10v`hAGyA;g zjQvacEQ9U_kM{bBV12i?Z$WP);^)=1wN)8q$<&nroE%*T1b_7FGma|i{cDX3hdkjDW|WnBvcJ)jY{)dd;+BNUDOokP6n_2(5rb{z(nQfL;#Rg^V5D%iN%4|? zBbtP~ye7lKJai8U7xGH6aicg(eESm*x|LyX)f6a8Fx>_fk+#`df8AgdbBqK`RF7V{ z)xz;`s*;b|fL!|H5d;zG%Q=_$$QI)uRRN}Ihr~Q$$Fo~(Ae6&=`xG}^1!o;_6 zHMSqkS~pc*^Yx93D#Pq4%yvFhpx5^ef}y`V+&G0%PyYblz?{BRx%1E0(2wzjTX2pYIEX$8ns)sXJI9sYb*5D)kBm6* z`1YX%+rZe-p+S*4i=W`b`&4(Eufzj3KhN#x5kXxl@#82{?v8d!$0Adx18o~;DwE_O z@$U&dDlyKspe(Z02DX;HgSPL%p@pfg648R%Y^7ED`CSMbHgHE)>O6Mwnymwwk1;54#=c)ko2wpRltt8Yta|IjW#Ec z4$ypeoJ1|f*fzNMOgB(g+P53ex?&DVEuOHB^MyaOA2%4w5AV0xE$JNA1myE1qG;HE zf0Xqy-zlkKrPPS8#Yj%cihgT7nWl7@f$!mBJnPb;@=o;q$Xk>_BJU7ALBwa7Yt--> zPQO{Thz5^n-s>Nit`tV#@5ZtyhCNge(TC`R3>hoKNf!yzdfu#pT;+8#YfniD6ln@% zh3*31X14S_hx5aN(jZ$)zi&tx;2_;P72!woaxDX|8SZZg2T$DTlaYh{31+dSOHIG) z2deIvx*!40y6)RlG}Ta0P6rTOk3jJpNNo}+5By@JHA)*5X2kd%EVQ_O+8T3uJPlPLz++syxw(w?D2>_k&ak1P zX3@5l8>KG`)aLCQ5NTJ`^|~^xO;?*{#rV$}35|`p}X>{bjQR~~(so4339EOvJUs+MbKVvv@y<0pP5n}GyLI3{q$uK5Q zi?rIYz$B22m8wiq#r{N{zpiHl7JXRH&uvJ6ApT24$QW-4`NoU)fQhAdxU_(Ogip=$ zBW_?NWdD7ZvGFJwD!+3AM2M`~>rST<50i*=icJ-G+XZ8~Rh|vj7lN;2_7M z!VkdG4C>t#5@Q2UnB`{SM%mO5YeBz#j+E8#*F;Gr5fSnEZ*P` zjAu18IG9z%`;4BIX(ORnQ^oN&H!al5toe@{_RN-_G|F{l8b~-QJW&RR;tA|yhMAbK z9~e!fAam8x|3Pl@f|kuM2}@Sa`CFwOUB&V%u6X|fe`*Ec5{pq`;?WOU{BYK=pQeAN z;jVt;(VHsKf=tI`$mkUmseQ*vU(kWaUYz(<;49XK&68NRdEPJ1#!sHh>T$goyDLS` z>Uc!hBmf+~i^kEiTr$>dbJ(d(^_QkKw1|V#?7%Lu%IoO*ERmA_vqJdXAVYX>0^JhY zx=Gsa9KC0KnfDkK|m%+6yJS7OX6cirN ze6FtXJBcY|nk&UtJe$_$I{5fp79sniF?5s-78BEakT_e2dgZc+>KI*WM-jSW{kg?S z8bATBp!90lF`;o zEgfs7ISRsq#NG)$KD8cO?f0v{c_N6jMVt?(udYmWBB9>>^)VZlOQcSFYpq~${=n;2 zn5;h2VfgS5HO2bBL!yhz-!tur zX_m6`WGfW4c+R>5gguCTc0n|`0WCbYD&GSS{imu;>E*0kD*H(bJc8y9(l40?Z{g zB(f5cXO7@T4qNUx{_)8jnad(?SB=r5>K}n>K67tKPm9u-$>e*sj+5!9f5nF{eAdl0 zRoz-or!FQ4|osI5HZqYe&_tGi{CHyxn?j>mXryLlIc3R);J`RdAD=ilF9jAZI<6nBw$&(EGJF*HVx(jHHQ9_WCa30(J_mvB ziE`hr@1J(LZ(sr_CnTdovQbVhm-DzA>x=z8uqCE(BGMaaV(W0Q%u1Rv*GcN+3BH(` zrNpkQ-(y-iY=uXS^qia=h-8^^4%_?8obKKzx#$=7w}ooF?qT>qYK4GN=<3r~VS66> zb1ZE2?WglsQpd8X7PwO+*(B|DYY^c^u#&&pF+H|}c#}x=qQ}9#33$qc+)2Z3-V+Pk za^Koj+)5djwCH<>KyT{s&nqzPu9|s8x1z8VKpWlC0 z+Mnhd{j2rHmx>L+bwpQlKGmBc9 zs_NlN^YmE2WHrw9*tb0&$_uCVuK?(r6*%l-6a&|pPl1vxDn_1Z$1y!CSD`93kfF-& zr~aLR4+p;^ldd{&8&Bdp7rq5+lD!*$gPr)*+;E+{ySYsA90wPNFwTn$u&MY~(;w3K*{B(x~D9ii<<|+w9(L z98xo_Um4JkZ1oe?M6cHmmaaG#4E+P3FZc@2S~4-zioI0Y~3$^H6(dBWg4m06RBjAHEl5=&|So4*si6Fqm%eT#$x z`?DbVS}9MTc!Lqyg3mG5t~15?pNHZ zUZeqj3b*+|BWKki-RwSL8hZvGEQZg_4gt~aDAmd9$_!?tf|NtVE%6k_Yb|GN*=0Lw zsEf{DWLCo5viSI_-Wwmw*PLZ+!A>0toIMtKs_X%PJ!is}d7KaQD$~Z*!=t4?we^mM zuJ46Ke&Tv5d=!}kvE;J#ImixRyKHvmsy~CorB2O>e=o zOd-Zic@(-|Y5c(k?Ey3LYZN4f`iJz~c0P*icUtsvv8Z~PjjkL%MTL&Blkk;PeZ|{U zK9Mb6st+ucQ8=pYZFvIPD8;W49mfWM&`FfoN<+7^NU@FiXAtR4>d|jNls2u$2|5EF zE>ji;5+_n=+8|-O`lU6Vvkkh$uwl3X5nNj|Lb0EHk<+=MH839$BI+eM$b9F(L#a@g zyVg;>?`h6fMM#t@8{(ws7mzc0rX@H+J&a`?TsiUsDiU5(e+P7yL3;6eUt>U!Ji`LQ zofL=${nhmc_bU^`I`}&V@GO}n^TpOnqGlE4sJ#aCk$xr%Q$&jAC0sYmvzI8bM>(BS z4oB1@e&vK>rKG+#c&N^BvwmX}!N-WgQSP(hGK$(n9rPn##XLe*XLCQPx3 zjvZYeYviJ)J>zB9qtJJT*#Tn~MSonI zU)%vn2QvgDU@35UaJ4q=KY)LJ%vI_wfgiz9aEv{Ufbtr8_A`EPGJG$&K=3oeEB>Ss zTX5K@aD45&a7>5Aj>%e@&}irEt(=xiA<~qP$4`^rDVS6l8|_m}0f@8zr>?gQimMB{ zg$ElTFu3a^cyJk9W^k7b5G1&}TL>Q93GRWQ3GO5i+?`;96WrY)AJ6;Nt@?i4`|s4L zI;VDZ_3quhy4Tv?oOCX)GH7Xx5xy2}RbCKu&)vxIdTU|9CGR&qUi_^rah`Tb_9vMP zva0#F>~wM%jyBsq3pMyh^k4_=+Q*l2Fd`>-m&uGHxSQM;<&c@dT)xt24=28H{mm1) z8JzOi2gNfl{arjGJxLhPdPwEw)mzjTGI;F^`msQ}e=dgi+96w}^9+LuZ2;w6u+iqv z!uN;rTWbZ~Zf~A5SbJy!R`5Ai9N6P(uS6O32@oqC+=F zP&U#XSUqH-J&LX*i~L8J_x#TF8y%(40d|i_S_Et#4j;t25cZ+R;YaEKtg?dPxhu7? zy!+CXU!;l5iB-&lDqUP`0I^{aDLH|28+>>QD9jAbM8cJ*AUpCNmQ%DD7CLd2MzRRRC)Io{caYBP=kbW8EV+^?84M1@bak4eg!X>wZUmo#UqM85m6yT6J{ZD;%ajFzHDS_J zmWfGX;|v{wfe?WfDI6jVH z?vG5C&arg@TpWyRS^lN*av5!3qJ3Otpo*_M^Lzc=nN-^inIT+C?Qb(MrjCqhx&qXH z;LpU@zbybB2Y0{1a!CjthQKUhTUlA7ZQ7VVbIW(M;E~4jC!9>8hx4(8|1ae~fteJH zR0iX=30G^EEy+KHcHoJEZ{pA@h^bzO33s$4rbnLH&}~_e2rD)zGA|imgu2kbj~FP>X-zUYq#mOPMV7t1g@zjfk=8|@m#l*XAD(lrZQ6i; z6J*Ypl%}_|wBzI-s6Wb1`ouj^&%>W2x0?3r?{T&62N^hBxsAE`7>CWoYC+Mbwn)tU zs?ws2V~()*vM`CyiT7`?g}+ahAoU-v7XA`dcR!5r^!qB%w0!V)Go*A)Vc&U$A%rkh zfIorzF!MbYA7A~$RpWq|`QJZUD{(gaZ_>rOma}8|Q4OzG(|Xaa|4a+d`G=CKGUoKp z(ky;0silD5q&sbd6~!@UVpu!0B1e|#_0`RgoI`0Y8en-$xa&Nsd!yKrR+Jg!p3Qk& zl9&r}L{hBSjk^{ucgZAX#&-5-;n1L2*pRsKK=j}QR-vkDftUDu(Hw=u>z>4#3e zLATP$xn}6J@4=*I8N{+=c2k&{GV4>{+A%(?&S!}_3TR1ffgxiK1N5W8V1NWQAr8M@Blo%YhNSB!k37(+19~qlz@*8SV7$aj$@6-i^ z_SG4NfZOce&J*>^=#}E_xu3)_v7RUT<}3hTN@X-Ix3dx{&*NH+I`Q_(i};iiV*qK1 zX}+k`OgNFW!5QXF)^~;~Vb|49#K9C_d|s7S3cy%jVP?Iy#Vq`8=j9A=RK!Z2IU8H2 zG8ucUU|KaNu{9y)gHJcxusNDs2jhLZq|kHC=?k?`ePOrYBbllOZ{~lwL3#f@X5&@jZNcTJ1xoEr>;0PUGS7FF!8LoU$Jo#F_rdH6_$#wL(l ze^8kVP_1kLb(Z(%%s*Atu>M(RH(3OaB05w&^E13G&apnHWp= zF#>q86{PfCbGY7b(PjG6?dIp?Z+fUWuM@<6Q-48Ab(zIbg&U~iMn}-%rSoO<5D{>R zed*cGfe|zg2#G3|urpcWRNm1kqbI0qBqK;@@xHSdvdxN=YUEQFpkqPi#2f0V@!z61 zf5sk((qO0;4rzwQ@z4L~$U87kq=o7vk7fL=M;KXnL=Ey9CNIJ41F#4`owsdnrsr5) z{*4#66R$ZgK8`D{F#}4itOWioSW<`I_&O^;^tff~5JQYEZ13%vGBDE{mBU`;aD~d= zk+bH!)|=G)+jsQea&!*QF;=u_pRkg3>>EZ8v#4vcve)WANm}o+fGWxv!DF#RlocH0G#L zvg}!sQ|)w3?9|&HxH9FpLT{P3%OotjaXo&;@nE*k;uc)^~1T?2LbEBvP>QgF@6>PYVll9LLy!+mEz)};t)7wCBNYc^7 z9T9oWDF-IX2bL^2z#|enJ6C(h9shUG2IJ{Qit?$i-q}64?0qL$^xjq!wjNutlizB3NlJmY)P5MeOq-_bZcuNOvK;QFiI`NSyhx5XqGx8>O8uz{{en*rQO6) z%Ld#^U9xQI{rG-lo4vTZj9(;qG@+S|NR{BK>Sm?4EOrXi_y)UU571B84UE`MxR}0@ zER`4s{ z2=Fce8oHq11W1v`m?}h<^iI6h%^D?TzvU-p=(KhEsPqZG*wiA!kZY ziSDn=B5>PJc#wf4yeux(cIfqACcu{xg~BVduUg;D-cV6>HU!DU!%#z9`%z~1$&%AZ zNJ;n6`Xay?Z8?$E{ z%g?dw3g@Nq(Wn?i48~}+Dn?Z5$pf-i7V|6S)j`-Gmwn0L3(HZ~Y@ZZ89pJ`eBGJJ& zdv~suF@Tk0kJ2@I6Ye` zbgE%2$$7i}Lr67BZe;yHYNqV0q(%4M0z{+|bp#MH2On{VZ9Q6djChO28v+R;x+0G# zA%*k7{;Mj6e!F;z2K#(J2f+G+eo&_jC?qg=XV@~nOW>3gx=`EJG7rl7Y9n6$(zR~) z?C+_HoE@f@PWXg-n}0nEpO#Q+D9NA5SJ;TGpSEZbvgfS4_b>hN3#!LcKb%p%lt2FF zc%{SfBe;g}b6B_3bX9yN2!qm{lrdZkJKvGgJ4orje5>W$K>$VGEM;<(HE8*9@il<)HXsV)0~RLE)Bvk^S?rZ>|61_R z{coOW)u%8_7p8YX69cBnB54xz6dfU^IHABfY*SFTcQjU+XIqY@Bhx8%2W=4Sa$zEI zVu1o9xEF!s&es(#z#tP;rxX);*H0R%yq>%bd(wu5O15zL% zzy!+acmA4~x!p4kZ8Ue7^Nmi5a5mFnn+=OcGAGmNBafcZmJvhKB9S#ZwB7K{@?(S9 zOq^82?PBD`_B$zcef4V?mD9wyMh{EeDT8_P++bz;Al4iybWPR5zTxsHz$}tmI(Wkp zeIv5=L;gI|ZK&(k0u#$oYtg~m&0iwdyIFGQH&1Lirpv@AAJu(4RJ3GS1RS_mXY5pC zX|G1ntkeBxVuaJOnx9TkF%*D3w!+CoI`@OrmVfj+0L0ze=|hR%a{d8$9Md5njLMRz zoDsKdwl&J1@|2HSAS%`fsg>f~?$aTAznAnoKa*cm-OJ?_*KPl0%)IyI-Ro#A&Trg3 z_x5w(mA^xSX`A-FN@!V0F(?lI01u_#tJg;|3I&JMm?+D%Y|>>YF;K&el5(YEx~gxN zbuxlN=D*Z?An_F%`fOC@R zzHTiK?wuvqzHG@PZN&wh-Rwy^mF`0?8Z`W&#-&d2KZKAq5XI!-?@{E8$mPBjYoJi^ zv5OG8%6K5Of6UMm00Qjd$t?<%aPf;H0e@p^4y*OlSH{W78f1iy^7GT_gKx^1zpvZ* zSN3KP<8FR8Bdl4Owu*E+4Esv(6LQjlZ+^hV`%l>Bb_d*Xx&yT z3#a=}!x^Mn8egZhU-9)*Ulz~)dAHtx-={~H(1mtvuU~Sb?$g`jP^YruB_@h~2BSbv zq8W*w|5#EIo`juI$ThSr=+G3g8B9+IpBmQOn9uUXN>T}gR!@#Yj0z#275tp)J}GSC zxqHhaC(iqhS*iVSl_F1TaLlb}Xa?_o%wOsD#v=OeoRr@f#k%B~v&TN%$}et#K7lWE zTpYSy>FuWPiXOJxnl6ri&>S+k)<6iaZ|H7@(V(IHco}~8)OZnaL&5+ADFX8WGsp`_ z#zE>N&?yKs6Uh~d;;QZ{s?@9eEp!rYu(`{VWAsS55p`bPQuA?enXRtp{G?S+53mbq zNW`Ovn%7T&Lyoq$MeRa?RvG$6m^gk?8i-;7c_r6<$drC5h3}>dw|HBj zoB4O1gg(p*|9z0?RAXJ&*`X zTkcKgk~}RiSLW~=+X3EDkMK6H1~qMo@3K`^vY^=)PdWchkP&EtLxX0Nv>T~o)@*8jFR>}pjdy&$wpvX(z{7XlzNas6m z?ve6QjDw8LQ{Wgj1xY@tL5W;#{qqpm+`5s>C#&c!H|I2so|8RR!#Do`;j_2kOAhM$ zS02Qg5bsK%O!+111&v;lr;-3Pxk|Y(joJlcyMd{b87`?P>2Ae7D?7G>Kmb+znWn3E z3R^5%*O>8AoP6BJ;*1^wBv{fR9bQF3ZBmkM&O zM)CKef)1{1K4b$i^N_4D?T6sZ<|&AiovUP@OmBxwI6D=luM?<6&JFD`4(!nt3-JirvKGpn$+vqVKJAzF0qTV!pO4A zHBTn#mMpC3GROl3KL$B9|A=19mqJyYnQVNPN5ZhKGrax>XbZ>$VCuR18f>qw1-Z!! z#Ly0%Yy=+Zi5YL-H6VxAEDF-vqJsfU4z0;R{k?1hB-81tw*Pbz@gOJm_HHX{v-Kao zRKt4Cn1}+g@$5Y<4h=Rw;-bFCWnG4|=CRhbEhga;zs(_X!6&zAzZOm=-pI^jUrr~0 zv?8;Z0^tZGuk0qO1m!tdnc;l#Kh(dJqqs8zKJtS7z>RS+@-|Ey5I!&m>*jd9tu}PW6>@xTeSy`^S zU;1>&9NWS|#O)yICNa}Ug=3M33M~M2reAUY@U6FtFn*PT{NbJ4iNLH=y|21d=qWC# znJP_qke0c`)QAXUfXyuWd`NSbe_)MmOjRFurmgHnTt?V?-_h_9WBNWCrDzguLR@f_ zFIX^rr)?2Zu=#+D^96T}3XW&(p<_WM=Rf^E@lNi*oH`8aG9cKbsPfY4y(Y-*5BBW2 zWA{cSPAeBVmJ$WP>4jUFDuRk66fprn3)~H!VMmkErB1fu{I4KtPzvg%ju|^Ln6O?w zQ@4|&)Ire$SWf`>Fz8<#3j-AymEEq*GGrT1pvIzu)G6^ba!Zw4ZKDeM8;&4;lGPrt z`uTL?p(lK74vMMkOA7Fulg6cpg`7hp$oVFxd-g0|il)u{wdTAi`Cr_&CqHS|&%EM; zqt+H#w=wYlzi0_iaR_SRM_$d*eUwPGSO$&<>a9f8BU3Dc(WK$~kJj z8Dd9Vh0+@Qw(d^gXLl_ez+g%)X)BH!={;XZ&7rdP##ni2T^&Xir{ypLu?TO{N^A)^ z?ZfOoqQmSevmPYjjLf<5Y2NqSg{YiVmZBmfp;V&t;SIhgvU(qj%MO<&CJw5tzV-=! zbFA<^YD)DcjdTc$&7Q)cJPZuJ2cy~=6tJXF41EG%ycr4>u*Q?TNyZcE$pS|nH>O=M zv&uh!E5HN|lhjfO9lwI1o+`4h9W|noaB2qncx)FNA95Wwhn7kFx%E7`#3r`%91Wir zX99*G{#G@=6?uit6OJ9vK+NVGXHf{>_G0GbF6w8MEsqA(yQDUQ{G3*(etg2y35zTE z7LK1%aw4L1TUPik3n!SB6lbzKtC6M`;*#ILHDCH2JN=8P*idctglZ{mEow8=0LdM| zObiGFj-k&7E^I##VHPzs-09>SYQ$NCsQry|t;y&6RL%jP_+W;O#cyA^@zwnTWiAiL z!`x|ndqm-T5JthbWarBiWH39vIfo(B7Aw(#jSq)ojGH-%z=jcP_87#&lH=E)Fz%Nde#gznthHHP5o;E-!(0i}#hwcIJ6vHp=fIp*9gJUc!Sx50)9RO%+<$H3xCJP%!o4k!*tuF zLp%gEL35PXfrz{ni0oJTUBjd~<^4x}>Fz-U?MCpU4kdv4#|ghcolMmcGlyK*WRDv^ zkkp?EyMH5ijuk9b3)D5o00DO?J^*)F2lcTyS4KVxXcFf|i01wUT+EOX=kXfSNyd3d`im-E6TIOVlfe;GPY9_Got8ftm(pT(z8EY_!$?PE*Q5o1)EVp z988(0Ew$JqQV}-JgAZ?uhdQ8dBo|+#blPf>vm&bZt2RrTMG;cJTNOdf`)?A9MiS$! zmqKbW>yU#SgNjhnqA+SJDNvKH--p9WJjq<*gXIcVexqvW6QcP4($3oIGC15b+Y?I3a9q zzHy0r!SU~Rah+&v)0!dd$`yy5lNAg#^|v`o{^;dc73FSvOC9q$OKdxPbviFnm9>M2 zn?^3`?C7nAfs4igdb|0@QM=3oNkFT`IXo$6)G{U9^PI^p9Z(`NoTVb!`{}M_b z2T+E2o?F~l)`Aji{}YBj$k!yl&1I#brO^(&563wW_Rd44LQ`cN+7BPtFIHgTcdK() zLyqd);J0!hM2qC~X(pj5)k4P+Uw_2^vHTseug<-Yu>= zB19=tKcnL#2E;G=2bgJfqu`SX3p56-Z8{k%KGy+6y5AFH2{d1?BfL&LjgGI@2PaoA z9u<^MB9$<7?|jZqWw1x{Q6%HyCMkFnLLa(Zh+vtQ7faSgy&RDn0JjHXQ2m#ypaVi^ z$@qE!hCu}u9* zXqWmQ$68LIIawKn6cnO(Ts?m)-vx#72!XXbZtg2!CdnX*U#p#HsXen;e7dL}cr7DH z`AHvLq5JmKW3#Gjw*_{3udMT_`vQG_W@r&E@!1B2spei%H4*(i=^|U|^ORJQT1AyP zsaaWOA4S#SpbMFk$-^nL50kQjR6SVvd*!gN7l7h=doYwuq0^6_g{4Qmn5s0KOi>*+ z-8}3o9h<1Xe64R!;)Qwe-z81_SN4!&4!)R}oMqL&lgdv+eRKevyL5h03rBpc0nCyp({JOrZ{2vsoA9C@& z?pwo*g;)(0{Ni7f{sC@ZRAVYWaUP^S_z%gvJ#ip+k! zi+7X(W&XdJIIftu;V>Vq#h_R@Q#1}OXyDN7DPx+^Mz$S-yl)gF6O84bCljy`fa zat!K6>E&2Mw2J8e^rkL5JF$-bMn=Pu(e$IR;pc1+f)?kTLap@d-R#QCCl4Kx4@m1P z%OG@=Uf1>+cj?tuY|cO4H}z7m4j0j}r`os$cd?MFfFt{`1m|Z)B~E==q^l#8`tuXp zu*7B{<7}|4b@n4-g%q)hSOzIOf6}xX){-eHyXKr5Z!75qG5u*ScG}U@b^Qm(_q%Yv zYLtR@)~IgVX0rSFNE=WJn6{dA9V}5Hfy7=rziVCVua*Ft4-bARVxpq^SC(IyZCwYoh_~f5z7bt9?JSGRMsgVWIv9sPSn^^VNjJ8g%>v z=m@H?>9~8mULESDO8kY>lDX!z7ObdB+RwZ|FGU&U&1)!FT*6P6?vX8V;7)4Q<)Yj> zmKi6nw-`Z*Qk$lKx>Iv;%QCb%nFxn`I5rQiOe(9%Qc+kCtL5?-+ChGBXYCw6!=b%> z+-ceW2bdccTdlLqJ9rhv_y_hrEIq#5mnkgl_NHDOYi|0$dEfbQOrUFD=WmZCk0)`n zeTLtMn&yYYCz9qXLDvVza+qB7HfibC;WYSs`_1#purX2kXh!BotS_teoD<$&4bZSJ zhQ1m8_1p zJ*uPcCfOfJe5eN2FJ3#fJyj&INl0JeLt^i@c|aHOvWtcWN9q#KL;JO~4+yHc>1($p zBYk(Ae}GyVOmZ|a3y4<5KDZoL}cOE&GUltR*a)^Hfd z-(0paA3GHN~^?qaI9Og(2yN99-+$sS04s$v{e-wyYb+Z*pHtR8t;%l?MfWg=go z=5OI%Wvn*1f%cjE%zZ+@((Ld)5ZK)!}KHnW`U11GMwS9N=$GJ8+a1EUNsWFMDay+Mb>PSqo8Ktb_D;L#}bE$YL8_! z-n+tRih^Q*g64dXSy4U6{d2qAbsSAF-#R)>Wj5i79~E#hy|}E-wg4^^wUh&5;>3xRj@)>I>G}u*MAt|Gc7^=N)o5gNdeb4g5Vn897Udn=hO!>FLx9uq#g$cd+T3c~SCa7yX4N_J1sdvGc#K z8dtKYxaKUhVWC{Dd`9`!glk8HFDGqF0(al#@7U>%t84mJ-y^4z9GtD@Rm38k-g(qzu4!vLy>(YJfGL+59@Z#gqnr`JiM;v`#c zAupVipHgOpi}^Fa94|bc)N%@I8_Tl9Gx8-ey`{u$P|JvHlZaC*_MPBtE`Q5&i01B! z!R|3yo>QuJ&jHrWi`3hZbMOjrPesoelI%T2lvV1mmHalI0bw_d$hSlJxlGXJ|J$8k zJRKE2UF#V$hgN*#%n!aL9xt2v`zJ%0jjIvkvpul8tc7KI?`-ev=Hi|C*dvDV zxaIbSd0=B3AnEU=(nh&+ zN1q3ZMmy0k4y=a${2yrce>RzY>^NoCZO|*%EH3AiC2k{GtODc$?$O+)`T(@MfYL{% zis_5)E4A}2Z*7r0_Mc2b_mt-Jdxu8CDSx^8$wd040x{ zRWldEm*aQ3eRD?ea5xpHUdx%k63AWQM#JY(VRm0Nec2k2*5&+^qq)1*xtE8{Wik>p zvE%Mw54E88`gM%n;7;sE8ZPph(0SlNbh+rWcH?Is#2g8tzW@_4LV%H}4<+l%9(`cd zNi~1o&XuQgkie}umeB5-BOB4?+SN@K7}lOQ%CCW*$prRH)6Pr=-VRf(jNRBFCSY^v zAewPhoXjlL@+0hdUz)Y!g}cH(S&*h1VBBX^?9vcGs%%t@FwYrXG1BSN28;;-73YW1 zv2Y2fnmf{x+Grn+d0CilP-hwDY_Im@r)Dbi2z=Dk%t=mcIOZ7q?kk6U za&K zXk%gSaKtM(ZxHT|dDSZ(&X(F%^+oOekMD#vG6t%>`rH3!Wc;6?2^%}(U7)(;OevZS z7ZvV$A{}^yi?n(rFEr#TrqlJz|H^rh$7^!tv~!J_qe`RgK7W$=Wz~Na*^jt%7aY-$ z9k8-jc^GxONN^2Q8Q6BTZ$GfQ=isMxk~cA7f;$%UI~*NCgR`iIsBAN`*rOfURGQii zCZI!~{B^tOQz{O-6@04ga@I`(#O2wq$*Kw!>C+&8k0IYIaYjc1`2lu+lF`4KN>N5i|Q%BpWmG!xl!2u1r1u^r`|jdp$n%`IKQ4@=NE9uMti8F*lRdc z7ZP`DhA_3a-yvac5#R8$|7wGVKvpK0|HF6uI;-2JSq zMs(*>9S0+j0KtSxC?$ksW;{X0j|IQXds&n2|KELEpjJPvO9E=$asl6e<=r@4`*ocg;A*a@*zNH micJq=RXs@k|8ivg|4%by9Rnm2-~Vn^`#<3u2@vvc;r{~>qhW>s literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/cimg5.jpg b/src/main/resources/static/images/cimg5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e6bf21b6acc4cb4c588bef535ac4448dbf52454 GIT binary patch literal 34346 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≤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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/cimg6.jpg b/src/main/resources/static/images/cimg6.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a72b246cba648d7f460d5b3920f2d4d3463e65e6 GIT binary patch literal 21167 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 AaR2}S literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/cimg9.jpg b/src/main/resources/static/images/cimg9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..451c79b6578beff5ea40482e84626feccbdd48f3 GIT binary patch literal 31686 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/timg1.jpg b/src/main/resources/static/images/timg1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e0112f9832f1922810b697d9c75063c55daa4c9f GIT binary patch literal 30302 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 k8Qp#D|{W>1me#Fxd0)wzy>aWzHZneZbxa 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/images/timg2.jpg b/src/main/resources/static/images/timg2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d6a05d688b2993137a3605605b1dde2e9d7262a GIT binary patch literal 110866 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