├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── README.md ├── dist ├── echarts-liquidfill.js ├── echarts-liquidfill.js.map ├── echarts-liquidfill.min.js └── echarts-liquidfill.min.js.map ├── example ├── fill-container.html ├── index.html └── test.html ├── index.js ├── license.md ├── package-lock.json ├── package.json ├── src ├── liquidFill.js ├── liquidFillSeries.js ├── liquidFillShape.js └── liquidFillView.js └── webpack.config.js /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | ```js 5 | var option = { 6 | series: [{ 7 | type: 'liquidFill', 8 | data: [0.6] 9 | }] 10 | }; 11 | ``` 12 | 13 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.swp 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Liquid Fill Chart 2 | 3 | Liquid Fill Chart plugin for [Apache ECharts](https://github.com/apache/echarts), which is usually used to represent data in percentage. 4 | 5 |  6 | 7 | ## Install ECharts 8 | 9 | To use ECharts plugins, you need to include the plugin JavaScript file after ECharts file. 10 | 11 | ```html 12 | 13 | 14 | ``` 15 | 16 | ECharts can be downloaded at [GitHub dist directory](https://github.com/apache/echarts/tree/master/dist) or [Download page of Official Website](https://echarts.apache.org/zh/download.html) (in Chinese). 17 | 18 | #### NOTE 19 | 20 | > 21 | > The minimum package of ECharts required by LiquidFill Chart is [simple version](https://github.com/apache/echarts/blob/master/dist/echarts.simple.js) on GitHub, or selecting nothing in [online builder](https://echarts.apache.org/zh/download.html) (in Chinese). If you need other chart types or components in your other chart, you should include them accordingly. 22 | 23 | ## Install echarts-liquidfill with npm 24 | 25 | ```sh 26 | # install echarts as peer dependency 27 | npm install echarts 28 | npm install echarts-liquidfill 29 | ``` 30 | 31 | NOTE: 32 | 33 | echarts-liquidfill@3 is compitable with echarts@5 34 | echarts-liquidfill@2 is compitable with echarts@4 35 | 36 | Import: 37 | 38 | ```js 39 | import * as echarts from 'echarts'; 40 | import 'echarts-liquidfill' 41 | ``` 42 | 43 | Or: 44 | 45 | ```js 46 | import * as echarts from 'echarts/core'; 47 | import 'echarts-liquidfill' 48 | ``` 49 | 50 | [Here](https://codesandbox.io/s/brave-rosalind-dj280?file=/src/index.js) is the basic example on CodeSandbox 51 | 52 | ## Download echarts-liquidfill from GitHub 53 | 54 | You may download the lastest ECharts files on [ECharts official site](https://echarts.apache.org/zh/download.html) and download this plugin in [dist directory](https://github.com/ecomfe/echarts-liquidfill/tree/master/dist). 55 | 56 | **Note that if you need tooltip for Liquid Fill Chart, you need the complete ECharts version. Otherwise, the simple version will be competent.** 57 | 58 | ## Important Notes 59 | 60 | ### Omitted `normal` 61 | 62 | Since [ECharts v4.0.0]((https://github.com/apache/echarts/releases/tag/4.0.0)), `normal` is no longer needed for `itemStyle` or `label`. 63 | 64 | ### Flatten `textStyle` 65 | 66 | Since [ECharts v3.7.0](https://github.com/apache/echarts/releases/tag/3.7.0), `textStyle` option is flatten, so that `series.label[normal|emphasis].textStyle.xxx` is now can be written in `series.label[normal|emphasis].textStyle`. This is supported from [echarts-liquidfill](https://github.com/ecomfe/echarts-liquidfill/releases/tag/v1.0.6) v1.0.6. So if you found examples with `textStyle` in old demo, don't be too surprised. 67 | 68 | 69 | 70 | ## Quick Start 71 | 72 | - [API](https://github.com/ecomfe/echarts-liquidfill#api) 73 | - [Examples at ECharts Gallery](https://www.makeapie.com/explore.html#tags=liquidFill~sort=rank~timeframe=all~author=all) 74 | 75 | Here are some common uses: 76 | 77 | - [Use multiple waves in a chart](https://github.com/ecomfe/echarts-liquidfill#multiple-waves) 78 | - [Change waves color and opacity](https://github.com/ecomfe/echarts-liquidfill#color-and-opacity) 79 | - [Make waves static](https://github.com/ecomfe/echarts-liquidfill#static-waves) 80 | - [Water with no waves](https://github.com/ecomfe/echarts-liquidfill#still-water) 81 | - [Set attributes for a single wave](https://github.com/ecomfe/echarts-liquidfill#change-a-single-wave) 82 | - [Change background and border style](https://github.com/ecomfe/echarts-liquidfill#background-style) 83 | - [Hide outline in chart](https://github.com/ecomfe/echarts-liquidfill#outline-style) 84 | - [Change shape with SVG](https://github.com/ecomfe/echarts-liquidfill#shape) 85 | - [Setup animation](https://github.com/ecomfe/echarts-liquidfill#animation) 86 | - [Change text content and style](https://github.com/ecomfe/echarts-liquidfill#change-text) 87 | - [Change shadow style](https://github.com/ecomfe/echarts-liquidfill#shadow) 88 | - [Setup tooltip](https://github.com/ecomfe/echarts-liquidfill#tooltip) 89 | - [Click event](https://github.com/ecomfe/echarts-liquidfill#click-event) 90 | - [Make an element non-interactable](https://github.com/ecomfe/echarts-liquidfill#non-interactable) 91 | 92 | To ask a question, you may fork [Liquid Fill Chart Example on Gallery](https://www.makeapie.com/editor.html?c=xr1XplzB4e) and copy your code there. Then you may [open an issue](https://github.com/ecomfe/echarts-liquidfill/issues/new) in this project. 93 | 94 | 95 | ## Examples 96 | 97 | ### A Simple Example 98 | 99 | To create a Liquid Fill Chart, you need to have a series with type of `'liquidFill'`. A basic option may be: 100 | 101 | ```js 102 | var option = { 103 | series: [{ 104 | type: 'liquidFill', 105 | data: [0.6] 106 | }] 107 | }; 108 | ``` 109 | 110 |  111 | 112 | [Run](https://www.makeapie.com/editor.html?c=xr1XplzB4e) 113 | 114 | 115 | ### Multiple Waves 116 | 117 | It is easy to create a liquid fill chart will multiple waves, either to represent multiple data, or to improve the visual effect of the chart. 118 | 119 | ```js 120 | var option = { 121 | series: [{ 122 | type: 'liquidFill', 123 | data: [0.6, 0.5, 0.4, 0.3] 124 | }] 125 | }; 126 | ``` 127 | 128 | This creates a chart wit waves at position of 60%, 50%, 40%, and 30%. 129 | 130 |  131 | 132 | [Run](https://www.makeapie.com/editor.html?c=xSyIEWMBNl) 133 | 134 | 135 | ### Color and Opacity 136 | 137 | To set colors for liquid fill chart series, set `color` to be an array of colors. To set opacity, use `itemStyle.opacity` and `itemStyle.emphasis.opacity` for normal style and hover style. 138 | 139 | ```js 140 | var option = { 141 | series: [{ 142 | type: 'liquidFill', 143 | data: [0.5, 0.4, 0.3], 144 | color: ['red', '#0f0', 'rgb(0, 0, 255)'], 145 | itemStyle: { 146 | opacity: 0.6 147 | }, 148 | emphasis: { 149 | itemStyle: { 150 | opacity: 0.9 151 | } 152 | } 153 | }] 154 | }; 155 | ``` 156 | 157 |  158 | 159 | [Run](https://www.makeapie.com/editor.html?c=xrJpDC704l) 160 | 161 | You may also set the color and opacity of a single data item by: 162 | 163 | ```js 164 | var option = { 165 | series: [{ 166 | type: 'liquidFill', 167 | data: [0.5, 0.4, { 168 | value: 0.3, 169 | itemStyle: { 170 | color: 'red', 171 | opacity: 0.6 172 | }, 173 | emphasis: { 174 | itemStyle: { 175 | opacity: 0.9 176 | } 177 | } 178 | }] 179 | }] 180 | }; 181 | ``` 182 | 183 |  184 | 185 | [Run](https://www.makeapie.com/editor.html?c=xBJPCRXR4l) 186 | 187 | 188 | ### Static Waves 189 | 190 | To provent the waves from moving left or right, you may simply set `waveAnimation` to be `false`. To disable the animation of waves raising, set `animationDuration` and `animationDurationUpdate` to be 0. 191 | 192 | ```js 193 | var option = { 194 | series: [{ 195 | type: 'liquidFill', 196 | waveAnimation: false, 197 | animationDuration: 0, 198 | animationDurationUpdate: 0, 199 | data: [0.6, 0.5, 0.4, 0.3] 200 | }] 201 | }; 202 | ``` 203 | 204 |  205 | 206 | [Run](https://www.makeapie.com/editor.html?c=xH1VfVVREx) 207 | 208 | 209 | ### Still Water 210 | 211 | You may set the `amplitude` to be 0 to make still waves. 212 | 213 | ```js 214 | var option = { 215 | series: [{ 216 | type: 'liquidFill', 217 | data: [0.6, 0.5, 0.4, 0.3], 218 | amplitude: 0, 219 | waveAnimation: 0 220 | }] 221 | }; 222 | ``` 223 | 224 | It is recommended to set `waveAnimation` to be false in this case to disable animation for performance consideration. 225 | 226 |  227 | 228 | [Run](https://www.makeapie.com/editor.html?c=xHy1NHVCNx) 229 | 230 | ### Change A Single Wave 231 | 232 | To change a single wave, overwrite the options in data item. 233 | 234 | ```js 235 | var option = { 236 | series: [{ 237 | type: 'liquidFill', 238 | data: [0.6, { 239 | value: 0.5, 240 | direction: 'left', 241 | itemStyle: { 242 | color: 'red' 243 | } 244 | }, 0.4, 0.3] 245 | }] 246 | }; 247 | ``` 248 | 249 |  250 | 251 | [Run](https://www.makeapie.com/editor.html?c=xry6CHNCVl) 252 | 253 | ### Background Style 254 | 255 | You can use backgroundStyle option to set the stroke, fill style of background shape. 256 | 257 | ```js 258 | var option = { 259 | series: [{ 260 | type: 'liquidFill', 261 | data: [0.6, 0.5, 0.4, 0.3], 262 | backgroundStyle: { 263 | borderWidth: 5, 264 | borderColor: 'red', 265 | color: 'yellow' 266 | } 267 | }] 268 | }; 269 | ``` 270 | 271 |  272 | 273 | [Run](https://www.makeapie.com/editor.html?c=xSkJoa_kBx) 274 | 275 | ### Outline Style 276 | 277 | To hide the outline, just set `outline.show` to be `false`. 278 | 279 | ```js 280 | var option = { 281 | series: [{ 282 | type: 'liquidFill', 283 | data: [0.6, 0.5, 0.4, 0.3], 284 | outline: { 285 | show: false 286 | } 287 | }] 288 | }; 289 | ``` 290 | 291 |  292 | 293 | [Run](https://www.makeapie.com/editor.html?c=xSySxR_JBg) 294 | 295 | 296 | ### Shape 297 | 298 | Shape of water fill chart. It can be: 299 | 300 | - one of the default symbols: `'circle'`, `'rect'`, `'roundRect'`, `'triangle'`, `'diamond'`, `'pin'`, `'arrow'`; 301 | - `'container'`: a shape that fully fills the container. 302 | - an SVG path starting with `'path://'`. 303 | 304 | ```js 305 | var options = [{ 306 | series: [{ 307 | type: 'liquidFill', 308 | data: [0.6, 0.5, 0.4, 0.3], 309 | shape: 'diamond' 310 | }] 311 | }]; 312 | ``` 313 | 314 |  315 | 316 | [Run](https://www.makeapie.com/editor.html?c=xry0tUfcBe) 317 | 318 | ``` 319 | option = { 320 | series: [{ 321 | type: 'liquidFill', 322 | data: [0.5, 0.4, 0.3, 0.2], 323 | shape: 'container', 324 | outline: { 325 | show: false 326 | } 327 | }] 328 | }; 329 | ``` 330 | 331 |  332 | 333 | [Run](https://www.makeapie.com/editor.html?c=xrko4E9zKb&v=1) 334 | 335 | ```js 336 | var option = { 337 | series: [{ 338 | type: 'liquidFill', 339 | data: [0.6, 0.55, 0.4, 0.25], 340 | radius: '60%', 341 | outline: { 342 | show: false 343 | }, 344 | backgroundStyle: { 345 | borderColor: '#156ACF', 346 | borderWidth: 1, 347 | shadowColor: 'rgba(0, 0, 0, 0.4)', 348 | shadowBlur: 20 349 | }, 350 | shape: 'path://M367.855,428.202c-3.674-1.385-7.452-1.966-11.146-1.794c0.659-2.922,0.844-5.85,0.58-8.719 c-0.937-10.407-7.663-19.864-18.063-23.834c-10.697-4.043-22.298-1.168-29.902,6.403c3.015,0.026,6.074,0.594,9.035,1.728 c13.626,5.151,20.465,20.379,15.32,34.004c-1.905,5.02-5.177,9.115-9.22,12.05c-6.951,4.992-16.19,6.536-24.777,3.271 c-13.625-5.137-20.471-20.371-15.32-34.004c0.673-1.768,1.523-3.423,2.526-4.992h-0.014c0,0,0,0,0,0.014 c4.386-6.853,8.145-14.279,11.146-22.187c23.294-61.505-7.689-130.278-69.215-153.579c-61.532-23.293-130.279,7.69-153.579,69.202 c-6.371,16.785-8.679,34.097-7.426,50.901c0.026,0.554,0.079,1.121,0.132,1.688c4.973,57.107,41.767,109.148,98.945,130.793 c58.162,22.008,121.303,6.529,162.839-34.465c7.103-6.893,17.826-9.444,27.679-5.719c11.858,4.491,18.565,16.6,16.719,28.643 c4.438-3.126,8.033-7.564,10.117-13.045C389.751,449.992,382.411,433.709,367.855,428.202z', 351 | label: { 352 | position: ['38%', '40%'], 353 | formatter: function() { 354 | return 'ECharts\nLiquid Fill'; 355 | }, 356 | fontSize: 40, 357 | color: '#D94854' 358 | } 359 | }] 360 | }; 361 | ``` 362 | 363 |  364 | 365 | [Run](https://www.makeapie.com/editor.html?c=xH1HouM9Sl) 366 | 367 | 368 | ### Animation 369 | 370 | Generally speaking, there are two types of animations in liquid fill charts. 371 | 372 | The first type is initial animation, which has the effect of wave raising. The easing method of this animation is controlled with `animationEasing` and its duration with `animationDuration`. 373 | 374 | The second type is the update animation, which is usually used when data changes and wave height changes. They are controlled with `animationEasingUpdate` and `animationDurationUpdate`. 375 | 376 | For example, to disable the raising animation and set update animation time to be two seconds with `cubicOut` easing, you can use the following option: 377 | 378 | ```js 379 | var option = { 380 | series: [{ 381 | type: 'liquidFill', 382 | data: [0.6, 0.5, 0.4, 0.3], 383 | animationDuration: 0, 384 | animationDurationUpdate: 2000, 385 | animationEasingUpdate: 'cubicOut' 386 | }] 387 | }; 388 | chart.setOption(option); 389 | setTimeout(function () { 390 | chart.setOption({ 391 | series: [{ 392 | type: 'liquidFill', 393 | data: [0.8, 0.6, 0.4, 0.2] 394 | }] 395 | }) 396 | }, 3000); 397 | ``` 398 | 399 |  400 | 401 | [Run](https://www.makeapie.com/editor.html?c=xSk8I5JcHe) 402 | 403 | ### Change Text 404 | 405 | By default, the text label of liquid fill chart displays percentage of the first data. For example, for a chart with data `[0.6, 0.5, 0.4, 0.3]`, default text is `60%`. 406 | 407 | To change the text, you may use `label.formatter`, which can be set to a string or function. 408 | 409 | If it is a string, `{a}` refers to series name, `{b}` to data name, and `{c}` to data value. 410 | 411 | ```js 412 | var option = { 413 | series: [{ 414 | type: 'liquidFill', 415 | name: 'Liquid Fill', 416 | data: [{ 417 | name: 'First Data', 418 | value: 0.6 419 | }, 0.5, 0.4, 0.3], 420 | label: { 421 | formatter: '{a}\n{b}\nValue: {c}', 422 | fontSize: 28 423 | } 424 | }] 425 | }; 426 | ``` 427 | 428 | Label text of this example is `'Liquid Fill\nFirst Data\nValue: 0.6'`. 429 | 430 |  431 | 432 | [Run](https://www.makeapie.com/editor.html?c=xrkwSn1qHx) 433 | 434 | This has the same result as using `formatter` as a function: 435 | 436 | ```js 437 | var option = { 438 | series: [{ 439 | type: 'liquidFill', 440 | name: 'Liquid Fill', 441 | data: [{ 442 | name: 'First Data', 443 | value: 0.6 444 | }, 0.5, 0.4, 0.3], 445 | label: { 446 | formatter: function(param) { 447 | return param.seriesName + '\n' 448 | + param.name + '\n' 449 | + 'Value:' + param.value; 450 | }, 451 | fontSize: 28 452 | } 453 | }] 454 | }; 455 | ``` 456 | 457 | [Run](https://www.makeapie.com/editor.html?c=xHk5831cHg) 458 | 459 | Text position is at the center by default. `label.position` can be set to be `'inside'`, `'left'`, `'right'`, `'top'`, `'bottom'`, or horizontal and vertical positions like `['10%', '20%']`, which means `'10%'` to the left (controlled by `label.align`, which can be `'left'`, `'center'`, or `'right'`) and `'20%'` to the top (controlled by `label.baseline`, which can be `'top'`, `'middle'`, or `'bottom'`). 460 | 461 | 462 | ### Shadow 463 | 464 | By default, waves and outline have shadow on them. Here's how to change them. 465 | 466 | ```js 467 | var option = { 468 | series: [{ 469 | type: 'liquidFill', 470 | data: [0.6, 0.5, 0.4, 0.3], 471 | itemStyle: { 472 | shadowBlur: 0 473 | }, 474 | outline: { 475 | borderDistance: 0, 476 | itemStyle: { 477 | borderWidth: 5, 478 | borderColor: '#156ACF', 479 | shadowBlur: 20, 480 | shadowColor: 'rgba(255, 0, 0, 1)' 481 | } 482 | } 483 | }] 484 | }; 485 | ``` 486 | 487 |  488 | 489 | [Run](https://www.makeapie.com/editor.html?c=xrJO4CyqSl) 490 | 491 | ### Tooltip 492 | 493 | To add tooltip: 494 | 495 | ```js 496 | var option = { 497 | series: [{ 498 | type: 'liquidFill', 499 | data: [0.6], 500 | name: 'Liquid Fill' 501 | }], 502 | tooltip: { 503 | show: true 504 | } 505 | }; 506 | ``` 507 | 508 |  509 | 510 | [Run](https://www.makeapie.com/editor.html?c=xSJqXeg5He) 511 | 512 | ### Click Event 513 | 514 | To add click event on waves: 515 | 516 | ```js 517 | chart.setOption(option); 518 | chart.on('click', function() { 519 | console.log(arguments); 520 | // do something useful here 521 | }); 522 | ``` 523 | 524 | Like any other chart types, the above code will only trigger events on waves. If you want to track events on the whole canvas or specific elements, you may add listener to zrender like: 525 | 526 | ```js 527 | chart.getZr().on('click', function() { 528 | console.log(arguments); 529 | }); 530 | ``` 531 | 532 | ### Non-interactable 533 | 534 | To make an element (e.g., a wave) non-interactable, simply set `silent` to be `true`. 535 | 536 | ```js 537 | var option = { 538 | series: [{ 539 | type: 'liquidFill', 540 | data: [0.6, 0.5, 0.4, 0.3], 541 | silent: true 542 | }] 543 | }; 544 | ``` 545 | 546 | [Run](https://www.makeapie.com/editor.html?c=xSJqev71Jb) 547 | 548 | 549 | ## API 550 | 551 | Default option for liquid fill charts are: 552 | 553 | ```js 554 | { 555 | data: [], 556 | 557 | color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'], 558 | center: ['50%', '50%'], 559 | radius: '50%', 560 | amplitude: '8%', 561 | waveLength: '80%', 562 | phase: 'auto', 563 | period: 'auto', 564 | direction: 'right', 565 | shape: 'circle', 566 | 567 | waveAnimation: true, 568 | animationEasing: 'linear', 569 | animationEasingUpdate: 'linear', 570 | animationDuration: 2000, 571 | animationDurationUpdate: 1000, 572 | 573 | outline: { 574 | show: true, 575 | borderDistance: 8, 576 | itemStyle: { 577 | color: 'none', 578 | borderColor: '#294D99', 579 | borderWidth: 8, 580 | shadowBlur: 20, 581 | shadowColor: 'rgba(0, 0, 0, 0.25)' 582 | } 583 | }, 584 | 585 | backgroundStyle: { 586 | color: '#E3F7FF' 587 | }, 588 | 589 | itemStyle: { 590 | opacity: 0.95, 591 | shadowBlur: 50, 592 | shadowColor: 'rgba(0, 0, 0, 0.4)' 593 | }, 594 | 595 | label: { 596 | show: true, 597 | color: '#294D99', 598 | insideColor: '#fff', 599 | fontSize: 50, 600 | fontWeight: 'bold', 601 | 602 | align: 'center', 603 | baseline: 'middle' 604 | position: 'inside' 605 | }, 606 | 607 | emphasis: { 608 | itemStyle: { 609 | opacity: 0.8 610 | } 611 | } 612 | } 613 | ``` 614 | 615 | 616 | ### data {(number|Object)[]} 617 | 618 | Value of each data item should be between 0 and 1. 619 | 620 | The data item can also be an object to configure the option for a single item. 621 | 622 | ```js 623 | var option = { 624 | series: [{ 625 | type: 'liquidFill', 626 | data: [0.6, { 627 | value: 0.5, 628 | itemStyle: { 629 | color: 'red' 630 | } 631 | }, 0.4, 0.3] 632 | }] 633 | }; 634 | ``` 635 | 636 | This defines a chart with the second wave of red color. 637 | 638 | 639 | ### color {string[]} 640 | 641 | Wave colors. 642 | 643 | 644 | ### shape {string} 645 | 646 | Shape of water fill chart. It can be one of the default symbols: `'circle'`, `'rect'`, `'roundRect'`, `'triangle'`, `'diamond'`, `'pin'`, `'arrow'`. Or, an SVG path starting with `'path://'`. 647 | 648 | 649 | ### center {string[]} 650 | 651 | Position of the chart. The first value is x position, the second one is the y position. Each of the values can be a relative value like `'50%'`, which is relative to the smaller value of container width and height, or an absolute value like `100px`. 652 | 653 | 654 | ### radius {string} 655 | 656 | Radius of the chart, which can be a relative value like `'50%'`, which is relative to the smaller value of container width and height, or an absolute value like `100px`. 657 | 658 | 659 | ### amplitude {number} 660 | 661 | Amplitude of the wave, in pixels or percentage. If it is in percentage, it's relative to the diameter. 662 | 663 | 664 | ### waveLength {string|number} 665 | 666 | Wave length of the wave, which can be a relative value like `'50%'`, which is relative to the diameter, or an absolute value like `'100px'` or `100`. 667 | 668 | 669 | ### phase {number} 670 | 671 | Phase of wave, in radian system. By default, it is set to be `'auto'`, when each wave has a phase of `Math.PI / 4` larger than the previous one. 672 | 673 | 674 | ### period {number|'auto'|function} 675 | 676 | Milliseconds that it takes to move forward a wave-length. By default, it is set to be `'auto'`, when the wave at the front has a greater speed. 677 | 678 | It can also be a formatter function. 679 | 680 | ```js 681 | var option = { 682 | series: [{ 683 | type: 'liquidFill', 684 | data: [0.6, 0.5, 0.4, 0.3], 685 | radius: '70%', 686 | phase: 0, 687 | period: function (value, index) { 688 | // This function is called four times, each for a data item in series. 689 | // `value` is 0.6, 0.5, 0.4, 0.3, and `index` is 0, 1, 2, 3. 690 | return 2000 * index + 1000; 691 | } 692 | }] 693 | } 694 | ``` 695 | 696 | 697 | ### direction {string} 698 | 699 | Direction that the waves moving in, which should either be `'right'`, or `'left'`. 700 | 701 | 702 | ### waveAnimation {boolean} 703 | 704 | Whether to enable wave from moving left or right. 705 | 706 | 707 | ### animationEasing {string} 708 | 709 | Easing methods for initial animation, when waves raise from the bottom at the beginning. 710 | 711 | 712 | ### animationEasingUpdate {string} 713 | 714 | Easing methods for other animation, for example, when data value changes and wave position changes. 715 | 716 | 717 | ### animationDuration {number} 718 | 719 | Initial animation duration, in milliseconds. 720 | 721 | ### animationDurationUpdate {number} 722 | 723 | Other animation duration, in milliseconds. 724 | 725 | 726 | ### outline.show {boolean} 727 | 728 | Whether to display outline. 729 | 730 | 731 | ### outline.borderDistance {number} 732 | 733 | Distance between border and inner circle. 734 | 735 | 736 | ### outline.itemStyle.borderColor {string} 737 | 738 | Border color. 739 | 740 | 741 | ### outline.itemStyle.borderWidth {number} 742 | 743 | Border width. 744 | 745 | 746 | ### outline.itemStyle.shadowBlur {number} 747 | 748 | Outline shadow blur size. 749 | 750 | 751 | ### outline.itemStyle.shadowColor {string} 752 | 753 | Outline shadow color. 754 | 755 | ### backgroundStyle.color {string} 756 | 757 | Background fill color. 758 | 759 | ### backgroundStyle.borderWidth {string} 760 | 761 | Background stroke line width. 762 | 763 | ### backgroundStyle.borderColor {string} 764 | 765 | Background stroke line width. 766 | 767 | ### backgroundStyle.itemStyle.shadowBlur {number} 768 | 769 | Background shadow blur size. 770 | 771 | ### backgroundStyle.itemStyle.shadowColor {string} 772 | 773 | Background shadow color. 774 | 775 | ### backgroundStyle.itemStyle.opacity {number} 776 | 777 | Background opacity. 778 | 779 | 780 | ### itemStyle.opacity {number} 781 | 782 | Wave opacity. 783 | 784 | 785 | ### itemStyle.shadowBlur {number} 786 | 787 | Wave shadow width. 788 | 789 | 790 | ### itemStyle.shadowColor {string} 791 | 792 | Wave shadow color. 793 | 794 | 795 | ### emphasis.itemStyle.opacity {number} 796 | 797 | Wave opacity when hover. 798 | 799 | 800 | ### label.show {boolean} 801 | 802 | Whether to display label text. 803 | 804 | 805 | ### label.color {string} 806 | 807 | Color of text when display on background. 808 | 809 | 810 | ### label.insideColor {string} 811 | 812 | Color of text when display on wave. 813 | 814 | 815 | ### label.fontSize {number} 816 | 817 | Label font size. 818 | 819 | 820 | ### label.fontWeight {string} 821 | 822 | Label font weight. 823 | 824 | 825 | ### label.align {string} 826 | 827 | Text align, which should be `'left'`, `'center'`, or `'right'`. 828 | 829 | 830 | ### label.baseline {string} 831 | 832 | Text vertical align, which should be `'top'`, `'middle'`, or `'bottom'`. 833 | 834 | 835 | ### label.position {string|string[]} 836 | 837 | Text position is at the center by default. `label.position` can be set to be `'inside'`, `'left'`, `'right'`, `'top'`, `'bottom'`, or horizontal and vertical positions like `['10%', '20%']`, which means `'10%'` to the left and `'20%'` to the top. 838 | 839 | 840 | ## Build 841 | 842 | For development: 843 | ``` 844 | $ webpack 845 | ``` 846 | 847 | For release: 848 | 849 | ``` 850 | $ webpack -p 851 | ``` 852 | 853 | ## Notice 854 | 855 | The Apache Software Foundation [Apache ECharts, ECharts](https://echarts.apache.org/), Apache, the Apache feather, and the Apache ECharts project logo are either registered trademarks or trademarks of the [Apache Software Foundation](https://www.apache.org/). 856 | -------------------------------------------------------------------------------- /dist/echarts-liquidfill.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("echarts")):"function"==typeof define&&define.amd?define(["echarts"],t):"object"==typeof exports?exports["echarts-liquidfill"]=t(require("echarts")):e["echarts-liquidfill"]=t(e.echarts)}(self,(function(e){return(()=>{"use strict";var t={245:(e,t,a)=>{a.r(t);var i=a(83);i.extendSeriesModel({type:"series.liquidFill",optionUpdated:function(){var e=this.option;e.gridSize=Math.max(Math.floor(e.gridSize),4)},getInitialData:function(e,t){var a=i.helper.createDimensions(e.data,{coordDimensions:["value"]}),r=new i.List(a,this);return r.initData(e.data),r},defaultOption:{color:["#294D99","#156ACF","#1598ED","#45BDFF"],center:["50%","50%"],radius:"50%",amplitude:"8%",waveLength:"80%",phase:"auto",period:"auto",direction:"right",shape:"circle",waveAnimation:!0,animationEasing:"linear",animationEasingUpdate:"linear",animationDuration:2e3,animationDurationUpdate:1e3,outline:{show:!0,borderDistance:8,itemStyle:{color:"none",borderColor:"#294D99",borderWidth:8,shadowBlur:20,shadowColor:"rgba(0, 0, 0, 0.25)"}},backgroundStyle:{color:"#E3F7FF"},itemStyle:{opacity:.95,shadowBlur:50,shadowColor:"rgba(0, 0, 0, 0.4)"},label:{show:!0,color:"#294D99",insideColor:"#fff",fontSize:50,fontWeight:"bold",align:"center",baseline:"middle",position:"inside"},emphasis:{itemStyle:{opacity:.8}}}});const r=i.graphic.extendShape({type:"ec-liquid-fill",shape:{waveLength:0,radius:0,radiusY:0,cx:0,cy:0,waterLevel:0,amplitude:0,phase:0,inverse:!1},buildPath:function(e,t){null==t.radiusY&&(t.radiusY=t.radius);for(var a=Math.max(2*Math.ceil(2*t.radius/t.waveLength*4),8);t.phase<2*-Math.PI;)t.phase+=2*Math.PI;for(;t.phase>0;)t.phase-=2*Math.PI;var i=t.phase/Math.PI/2*t.waveLength,r=t.cx-t.radius+i-2*t.radius;e.moveTo(r,t.waterLevel);for(var l=0,o=0;ol?(l*=2*e/n,n=2*e):(n*=2*e/l,l=2*e);var s=t?0:M-n/2,h=t?0:P-l/2;return a=i.graphic.makePath(S.slice(7),{},new i.graphic.BoundingRect(s,h,n,l)),t&&(a.x=-n/2,a.y=-l/2),a}if(I){var d=t?-e[0]:M-e[0],p=t?-e[1]:P-e[1];return i.helper.createSymbol("rect",d,p,2*e[0],2*e[1])}return d=t?-e:M-e,p=t?-e:P-e,"pin"===S?p+=e:"arrow"===S&&(p-=e),i.helper.createSymbol(S,d,p,2*e,2*e)}return new i.graphic.Circle({shape:{cx:t?0:M,cy:t?0:P,r:e}})}function Y(){var t=E(w);return t.style.fill=null,t.setStyle(e.getModel("outline.itemStyle").getItemStyle()),t}function k(t,a,n){var o=I?u[0]:u,s=I?g/2:u,d=h.getItemModel(t),p=d.getModel("itemStyle"),c=d.get("phase"),v=l(d.get("amplitude"),2*s),f=l(d.get("waveLength"),2*o),y=s-h.get("value",t)*s*2;c=n?n.shape.phase:"auto"===c?t*Math.PI/4:c;var m=p.getItemStyle();if(!m.fill){var w=e.get("color"),b=t%w.length;m.fill=w[b]}var x=new r({shape:{waveLength:f,radius:o,radiusY:s,cx:2*o,cy:0,waterLevel:y,amplitude:v,phase:c,inverse:a},style:m,x:M,y:P});x.shape._waterLevel=y;var S=d.getModel("emphasis.itemStyle").getItemStyle();S.lineWidth=0,x.ensureState("emphasis").style=S,i.helper.enableHoverEmphasis(x);var L=E(u,!0);return L.setStyle({fill:"white"}),x.setClipPath(L),x}function q(e,t,a){var i=h.getItemModel(e),r=i.get("period"),n=i.get("direction"),l=h.get("value",e),o=i.get("phase");o=a?a.shape.phase:"auto"===o?e*Math.PI/4:o;var s,d;s="auto"===r?0===(d=h.count())?5e3:5e3*(.2+(d-e)/d*.8):"function"==typeof r?r(l,e):r;var p=0;"right"===n||null==n?p=Math.PI:"left"===n?p=-Math.PI:"none"===n?p=0:console.error("Illegal direction value for liquid fill."),"none"!==n&&i.get("waveAnimation")&&t.animate("shape",!0).when(0,{phase:o}).when(s/2,{phase:p+o}).when(s,{phase:2*p+o}).during((function(){T&&T.dirty(!0)})).start()}h.diff(D).add((function(t){var a=k(t,!1),r=a.shape.waterLevel;a.shape.waterLevel=I?g/2:u,i.graphic.initProps(a,{shape:{waterLevel:r}},e),a.z2=2,q(t,a,null),s.add(a),h.setItemGraphicEl(t,a),F.push(a)})).update((function(t,a){for(var r=D.getItemGraphicEl(a),l=k(t,!1,r),d={},p=["amplitude","cx","cy","phase","radius","radiusY","waterLevel","waveLength"],u=0;u{t.exports=e}},a={};function i(e){if(a[e])return a[e].exports;var r=a[e]={exports:{}};return t[e](r,r.exports,i),r.exports}return i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i(245)})()})); 2 | //# sourceMappingURL=echarts-liquidfill.min.js.map -------------------------------------------------------------------------------- /dist/echarts-liquidfill.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://echarts-liquidfill/webpack/universalModuleDefinition","webpack://echarts-liquidfill/./src/liquidFillSeries.js","webpack://echarts-liquidfill/./src/liquidFillShape.js","webpack://echarts-liquidfill/./src/liquidFillView.js","webpack://echarts-liquidfill/./node_modules/echarts/lib/util/number.js","webpack://echarts-liquidfill/external \"echarts\"","webpack://echarts-liquidfill/webpack/bootstrap","webpack://echarts-liquidfill/webpack/startup","webpack://echarts-liquidfill/webpack/runtime/make namespace object"],"names":["root","factory","exports","module","require","define","amd","self","__WEBPACK_EXTERNAL_MODULE__83__","type","optionUpdated","option","this","gridSize","Math","max","floor","getInitialData","ecModel","dimensions","data","coordDimensions","list","initData","defaultOption","color","center","radius","amplitude","waveLength","phase","period","direction","shape","waveAnimation","animationEasing","animationEasingUpdate","animationDuration","animationDurationUpdate","outline","show","borderDistance","itemStyle","borderColor","borderWidth","shadowBlur","shadowColor","backgroundStyle","opacity","label","insideColor","fontSize","fontWeight","align","baseline","position","emphasis","radiusY","cx","cy","waterLevel","inverse","buildPath","ctx","curves","ceil","PI","left","moveTo","waveRight","c","stage","pos","getWaterPositions","bezierCurveTo","lineTo","closePath","x","percent","all","str","replace","match","parseFloat","NaN","isPathSymbol","symbol","indexOf","render","seriesModel","api","group","removeAll","getData","itemModel","getItemModel","get","width","getWidth","height","getHeight","size","min","outlineDistance","outlineBorderWidth","showOutline","outterRadius","innerRadius","paddingRadius","isFillContainer","getOutline","style","lineWidth","add","top","wavePath","strokePath","getPath","setStyle","getModel","getItemStyle","fill","z2","fillPath","stroke","getBackground","oldData","_data","waves","r","isForClipping","path","slice","bouding","getBoundingRect","w","h","y","outlinePath","getWave","idx","isInverse","oldWave","radiusX","itemStyleModel","normalStyle","seriesColor","id","length","wave","_waterLevel","hoverStyle","ensureState","clip","setClipPath","setWaveAnimation","maxSpeed","value","speed","cnt","count","phaseOffset","console","error","animate","when","during","dirty","start","diff","setItemGraphicEl","push","update","newIdx","oldIdx","waveElement","getItemGraphicEl","newWave","shapeAttrs","i","attr","hasOwnProperty","styleAttrs","isUniversalTransitionEnabled","useStyle","oldWaveClipPath","getClipPath","newWaveClipPath","_shape","isFrom","remove","execute","labelModel","formatted","defaultVal","defaultLabel","textRectOption","textConfig","silent","textOption","text","getFormattedLabel","getName","name","isNaN","toFixed","textAlign","textVerticalAlign","Object","assign","outsideTextRect","insideTextRect","disableLabelAnimation","outsideText","insideText","setTextContent","insColor","boundingCircle","paths","getText","dispose","__webpack_module_cache__","__webpack_require__","moduleId","__webpack_modules__","Symbol","toStringTag","defineProperty"],"mappings":"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","file":"echarts-liquidfill.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"echarts\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"echarts\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"echarts-liquidfill\"] = factory(require(\"echarts\"));\n\telse\n\t\troot[\"echarts-liquidfill\"] = factory(root[\"echarts\"]);\n})(self, function(__WEBPACK_EXTERNAL_MODULE__83__) {\nreturn ","import * as echarts from 'echarts/lib/echarts';\n\necharts.extendSeriesModel({\n\n type: 'series.liquidFill',\n\n optionUpdated: function () {\n var option = this.option;\n option.gridSize = Math.max(Math.floor(option.gridSize), 4);\n },\n\n getInitialData: function (option, ecModel) {\n var dimensions = echarts.helper.createDimensions(option.data, {\n coordDimensions: ['value']\n });\n var list = new echarts.List(dimensions, this);\n list.initData(option.data);\n return list;\n },\n\n defaultOption: {\n color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'],\n center: ['50%', '50%'],\n radius: '50%',\n amplitude: '8%',\n waveLength: '80%',\n phase: 'auto',\n period: 'auto',\n direction: 'right',\n shape: 'circle',\n\n waveAnimation: true,\n animationEasing: 'linear',\n animationEasingUpdate: 'linear',\n animationDuration: 2000,\n animationDurationUpdate: 1000,\n\n outline: {\n show: true,\n borderDistance: 8,\n itemStyle: {\n color: 'none',\n borderColor: '#294D99',\n borderWidth: 8,\n shadowBlur: 20,\n shadowColor: 'rgba(0, 0, 0, 0.25)'\n }\n },\n\n backgroundStyle: {\n color: '#E3F7FF'\n },\n\n itemStyle: {\n opacity: 0.95,\n shadowBlur: 50,\n shadowColor: 'rgba(0, 0, 0, 0.4)'\n },\n\n label: {\n show: true,\n color: '#294D99',\n insideColor: '#fff',\n fontSize: 50,\n fontWeight: 'bold',\n\n align: 'center',\n baseline: 'middle',\n position: 'inside'\n },\n\n emphasis: {\n itemStyle: {\n opacity: 0.8\n }\n }\n }\n});\n","import * as echarts from 'echarts/lib/echarts';\n\nexport default echarts.graphic.extendShape({\n type: 'ec-liquid-fill',\n\n shape: {\n waveLength: 0,\n radius: 0,\n radiusY: 0,\n cx: 0,\n cy: 0,\n waterLevel: 0,\n amplitude: 0,\n phase: 0,\n inverse: false\n },\n\n buildPath: function (ctx, shape) {\n if (shape.radiusY == null) {\n shape.radiusY = shape.radius;\n }\n\n /**\n * We define a sine wave having 4 waves, and make sure at least 8 curves\n * is drawn. Otherwise, it may cause blank area for some waves when\n * wave length is large enough.\n */\n var curves = Math.max(\n Math.ceil(2 * shape.radius / shape.waveLength * 4) * 2,\n 8\n );\n\n // map phase to [-Math.PI * 2, 0]\n while (shape.phase < -Math.PI * 2) {\n shape.phase += Math.PI * 2;\n }\n while (shape.phase > 0) {\n shape.phase -= Math.PI * 2;\n }\n var phase = shape.phase / Math.PI / 2 * shape.waveLength;\n\n var left = shape.cx - shape.radius + phase - shape.radius * 2;\n\n /**\n * top-left corner as start point\n *\n * draws this point\n * |\n * \\|/\n * ~~~~~~~~\n * | |\n * +------+\n */\n ctx.moveTo(left, shape.waterLevel);\n\n /**\n * top wave\n *\n * ~~~~~~~~ <- draws this sine wave\n * | |\n * +------+\n */\n var waveRight = 0;\n for (var c = 0; c < curves; ++c) {\n var stage = c % 4;\n var pos = getWaterPositions(c * shape.waveLength / 4, stage,\n shape.waveLength, shape.amplitude);\n ctx.bezierCurveTo(pos[0][0] + left, -pos[0][1] + shape.waterLevel,\n pos[1][0] + left, -pos[1][1] + shape.waterLevel,\n pos[2][0] + left, -pos[2][1] + shape.waterLevel);\n\n if (c === curves - 1) {\n waveRight = pos[2][0];\n }\n }\n\n if (shape.inverse) {\n /**\n * top-right corner\n * 2. draws this line\n * |\n * +------+\n * 3. draws this line -> | | <- 1. draws this line\n * ~~~~~~~~\n */\n ctx.lineTo(waveRight + left, shape.cy - shape.radiusY);\n ctx.lineTo(left, shape.cy - shape.radiusY);\n ctx.lineTo(left, shape.waterLevel);\n }\n else {\n /**\n * top-right corner\n *\n * ~~~~~~~~\n * 3. draws this line -> | | <- 1. draws this line\n * +------+\n * ^\n * |\n * 2. draws this line\n */\n ctx.lineTo(waveRight + left, shape.cy + shape.radiusY);\n ctx.lineTo(left, shape.cy + shape.radiusY);\n ctx.lineTo(left, shape.waterLevel);\n }\n\n ctx.closePath();\n }\n});\n\n\n\n/**\n * Using Bezier curves to fit sine wave.\n * There is 4 control points for each curve of wave,\n * which is at 1/4 wave length of the sine wave.\n *\n * The control points for a wave from (a) to (d) are a-b-c-d:\n * c *----* d\n * b *\n * |\n * ... a * ..................\n *\n * whose positions are a: (0, 0), b: (0.5, 0.5), c: (1, 1), d: (PI / 2, 1)\n *\n * @param {number} x x position of the left-most point (a)\n * @param {number} stage 0-3, stating which part of the wave it is\n * @param {number} waveLength wave length of the sine wave\n * @param {number} amplitude wave amplitude\n */\nfunction getWaterPositions(x, stage, waveLength, amplitude) {\n if (stage === 0) {\n return [\n [x + 1 / 2 * waveLength / Math.PI / 2, amplitude / 2],\n [x + 1 / 2 * waveLength / Math.PI, amplitude],\n [x + waveLength / 4, amplitude]\n ];\n }\n else if (stage === 1) {\n return [\n [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2),\n amplitude],\n [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1),\n amplitude / 2],\n [x + waveLength / 4, 0]\n ]\n }\n else if (stage === 2) {\n return [\n [x + 1 / 2 * waveLength / Math.PI / 2, -amplitude / 2],\n [x + 1 / 2 * waveLength / Math.PI, -amplitude],\n [x + waveLength / 4, -amplitude]\n ]\n }\n else {\n return [\n [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2),\n -amplitude],\n [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1),\n -amplitude / 2],\n [x + waveLength / 4, 0]\n ]\n }\n}\n","import * as echarts from 'echarts/lib/echarts';\nimport * as numberUtil from 'echarts/lib/util/number';\nimport LiquidShape from './liquidFillShape';\n\nvar parsePercent = numberUtil.parsePercent;\n\nfunction isPathSymbol(symbol) {\n return symbol && symbol.indexOf('path://') === 0\n}\n\necharts.extendChartView({\n\n type: 'liquidFill',\n\n render: function (seriesModel, ecModel, api) {\n var self = this;\n var group = this.group;\n group.removeAll();\n\n var data = seriesModel.getData();\n\n var itemModel = data.getItemModel(0);\n\n var center = itemModel.get('center');\n var radius = itemModel.get('radius');\n\n var width = api.getWidth();\n var height = api.getHeight();\n var size = Math.min(width, height);\n // itemStyle\n var outlineDistance = 0;\n var outlineBorderWidth = 0;\n var showOutline = seriesModel.get('outline.show');\n\n if (showOutline) {\n outlineDistance = seriesModel.get('outline.borderDistance');\n outlineBorderWidth = parsePercent(\n seriesModel.get('outline.itemStyle.borderWidth'), size\n );\n }\n\n var cx = parsePercent(center[0], width);\n var cy = parsePercent(center[1], height);\n\n var outterRadius;\n var innerRadius;\n var paddingRadius;\n\n var isFillContainer = false;\n\n var symbol = seriesModel.get('shape');\n if (symbol === 'container') {\n // a shape that fully fills the container\n isFillContainer = true;\n\n outterRadius = [\n width / 2,\n height / 2\n ];\n innerRadius = [\n outterRadius[0] - outlineBorderWidth / 2,\n outterRadius[1] - outlineBorderWidth / 2\n ];\n paddingRadius = [\n parsePercent(outlineDistance, width),\n parsePercent(outlineDistance, height)\n ];\n\n radius = [\n Math.max(innerRadius[0] - paddingRadius[0], 0),\n Math.max(innerRadius[1] - paddingRadius[1], 0)\n ];\n }\n else {\n outterRadius = parsePercent(radius, size) / 2;\n innerRadius = outterRadius - outlineBorderWidth / 2;\n paddingRadius = parsePercent(outlineDistance, size);\n\n radius = Math.max(innerRadius - paddingRadius, 0);\n }\n\n if (showOutline) {\n var outline = getOutline();\n outline.style.lineWidth = outlineBorderWidth;\n group.add(getOutline());\n }\n\n var left = isFillContainer ? 0 : cx - radius;\n var top = isFillContainer ? 0 : cy - radius;\n\n var wavePath = null;\n\n group.add(getBackground());\n\n // each data item for a wave\n var oldData = this._data;\n var waves = [];\n data.diff(oldData)\n .add(function (idx) {\n var wave = getWave(idx, false);\n\n var waterLevel = wave.shape.waterLevel;\n wave.shape.waterLevel = isFillContainer ? height / 2 : radius;\n echarts.graphic.initProps(wave, {\n shape: {\n waterLevel: waterLevel\n }\n }, seriesModel);\n\n wave.z2 = 2;\n setWaveAnimation(idx, wave, null);\n\n group.add(wave);\n data.setItemGraphicEl(idx, wave);\n waves.push(wave);\n })\n .update(function (newIdx, oldIdx) {\n var waveElement = oldData.getItemGraphicEl(oldIdx);\n\n // new wave is used to calculate position, but not added\n var newWave = getWave(newIdx, false, waveElement);\n\n // changes with animation\n var shape = {};\n var shapeAttrs = ['amplitude', 'cx', 'cy', 'phase', 'radius', 'radiusY', 'waterLevel', 'waveLength'];\n for (var i = 0; i < shapeAttrs.length; ++i) {\n var attr = shapeAttrs[i];\n if (newWave.shape.hasOwnProperty(attr)) {\n shape[attr] = newWave.shape[attr];\n }\n }\n\n var style = {};\n var styleAttrs = ['fill', 'opacity', 'shadowBlur', 'shadowColor'];\n for (var i = 0; i < styleAttrs.length; ++i) {\n var attr = styleAttrs[i];\n if (newWave.style.hasOwnProperty(attr)) {\n style[attr] = newWave.style[attr];\n }\n }\n\n if (isFillContainer) {\n shape.radiusY = height / 2;\n }\n\n // changes with animation\n echarts.graphic.updateProps(waveElement, {\n shape: shape,\n x: newWave.x,\n y: newWave.y\n }, seriesModel);\n\n if (seriesModel.isUniversalTransitionEnabled && seriesModel.isUniversalTransitionEnabled()) {\n echarts.graphic.updateProps(waveElement, {\n style: style\n }, seriesModel);\n }\n else {\n waveElement.useStyle(style);\n }\n\n // instant changes\n var oldWaveClipPath = waveElement.getClipPath();\n var newWaveClipPath = newWave.getClipPath();\n\n waveElement.setClipPath(newWave.getClipPath());\n waveElement.shape.inverse = newWave.inverse;\n\n if (oldWaveClipPath && newWaveClipPath\n && self._shape === symbol\n // TODO use zrender morphing to apply complex symbol animation.\n && !isPathSymbol(symbol)\n ) {\n // Can be animated.\n echarts.graphic.updateProps(newWaveClipPath, {\n shape: oldWaveClipPath.shape\n }, seriesModel, { isFrom: true });\n }\n\n setWaveAnimation(newIdx, waveElement, waveElement);\n group.add(waveElement);\n data.setItemGraphicEl(newIdx, waveElement);\n waves.push(waveElement);\n })\n .remove(function (idx) {\n var wave = oldData.getItemGraphicEl(idx);\n group.remove(wave);\n })\n .execute();\n\n if (itemModel.get('label.show')) {\n group.add(getText(waves));\n }\n\n this._shape = symbol;\n this._data = data;\n\n /**\n * Get path for outline, background and clipping\n *\n * @param {number} r outter radius of shape\n * @param {boolean|undefined} isForClipping if the shape is used\n * for clipping\n */\n function getPath(r, isForClipping) {\n if (symbol) {\n // customed symbol path\n if (isPathSymbol(symbol)) {\n var path = echarts.graphic.makePath(symbol.slice(7), {});\n var bouding = path.getBoundingRect();\n var w = bouding.width;\n var h = bouding.height;\n if (w > h) {\n h = r * 2 / w * h;\n w = r * 2;\n }\n else {\n w = r * 2 / h * w;\n h = r * 2;\n }\n\n var left = isForClipping ? 0 : cx - w / 2;\n var top = isForClipping ? 0 : cy - h / 2;\n path = echarts.graphic.makePath(\n symbol.slice(7),\n {},\n new echarts.graphic.BoundingRect(left, top, w, h)\n );\n if (isForClipping) {\n path.x = -w / 2;\n path.y = -h / 2;\n }\n return path;\n }\n else if (isFillContainer) {\n // fully fill the container\n var x = isForClipping ? -r[0] : cx - r[0];\n var y = isForClipping ? -r[1] : cy - r[1];\n return echarts.helper.createSymbol(\n 'rect', x, y, r[0] * 2, r[1] * 2\n );\n }\n else {\n var x = isForClipping ? -r : cx - r;\n var y = isForClipping ? -r : cy - r;\n if (symbol === 'pin') {\n y += r;\n }\n else if (symbol === 'arrow') {\n y -= r;\n }\n return echarts.helper.createSymbol(symbol, x, y, r * 2, r * 2);\n }\n }\n\n return new echarts.graphic.Circle({\n shape: {\n cx: isForClipping ? 0 : cx,\n cy: isForClipping ? 0 : cy,\n r: r\n }\n });\n }\n /**\n * Create outline\n */\n function getOutline() {\n var outlinePath = getPath(outterRadius);\n outlinePath.style.fill = null;\n\n outlinePath.setStyle(seriesModel.getModel('outline.itemStyle')\n .getItemStyle());\n\n return outlinePath;\n }\n\n /**\n * Create background\n */\n function getBackground() {\n // Seperate stroke and fill, so we can use stroke to cover the alias of clipping.\n var strokePath = getPath(radius);\n strokePath.setStyle(seriesModel.getModel('backgroundStyle')\n .getItemStyle());\n strokePath.style.fill = null;\n\n // Stroke is front of wave\n strokePath.z2 = 5;\n\n var fillPath = getPath(radius);\n fillPath.setStyle(seriesModel.getModel('backgroundStyle')\n .getItemStyle());\n fillPath.style.stroke = null;\n\n var group = new echarts.graphic.Group();\n group.add(strokePath);\n group.add(fillPath);\n\n return group;\n }\n\n /**\n * wave shape\n */\n function getWave(idx, isInverse, oldWave) {\n var radiusX = isFillContainer ? radius[0] : radius;\n var radiusY = isFillContainer ? height / 2 : radius;\n\n var itemModel = data.getItemModel(idx);\n var itemStyleModel = itemModel.getModel('itemStyle');\n var phase = itemModel.get('phase');\n var amplitude = parsePercent(itemModel.get('amplitude'),\n radiusY * 2);\n var waveLength = parsePercent(itemModel.get('waveLength'),\n radiusX * 2);\n\n var value = data.get('value', idx);\n var waterLevel = radiusY - value * radiusY * 2;\n phase = oldWave ? oldWave.shape.phase\n : (phase === 'auto' ? idx * Math.PI / 4 : phase);\n var normalStyle = itemStyleModel.getItemStyle();\n if (!normalStyle.fill) {\n var seriesColor = seriesModel.get('color');\n var id = idx % seriesColor.length;\n normalStyle.fill = seriesColor[id];\n }\n\n var x = radiusX * 2;\n var wave = new LiquidShape({\n shape: {\n waveLength: waveLength,\n radius: radiusX,\n radiusY: radiusY,\n cx: x,\n cy: 0,\n waterLevel: waterLevel,\n amplitude: amplitude,\n phase: phase,\n inverse: isInverse\n },\n style: normalStyle,\n x: cx,\n y: cy,\n });\n wave.shape._waterLevel = waterLevel;\n\n var hoverStyle = itemModel.getModel('emphasis.itemStyle')\n .getItemStyle();\n hoverStyle.lineWidth = 0;\n\n wave.ensureState('emphasis').style = hoverStyle;\n echarts.helper.enableHoverEmphasis(wave);\n\n // clip out the part outside the circle\n var clip = getPath(radius, true);\n // set fill for clipPath, otherwise it will not trigger hover event\n clip.setStyle({\n fill: 'white'\n });\n wave.setClipPath(clip);\n\n return wave;\n }\n\n function setWaveAnimation(idx, wave, oldWave) {\n var itemModel = data.getItemModel(idx);\n\n var maxSpeed = itemModel.get('period');\n var direction = itemModel.get('direction');\n\n var value = data.get('value', idx);\n\n var phase = itemModel.get('phase');\n phase = oldWave ? oldWave.shape.phase\n : (phase === 'auto' ? idx * Math.PI / 4 : phase);\n\n var defaultSpeed = function (maxSpeed) {\n var cnt = data.count();\n return cnt === 0 ? maxSpeed : maxSpeed *\n (0.2 + (cnt - idx) / cnt * 0.8);\n };\n var speed = 0;\n if (maxSpeed === 'auto') {\n speed = defaultSpeed(5000);\n }\n else {\n speed = typeof maxSpeed === 'function'\n ? maxSpeed(value, idx) : maxSpeed;\n }\n\n // phase for moving left/right\n var phaseOffset = 0;\n if (direction === 'right' || direction == null) {\n phaseOffset = Math.PI;\n }\n else if (direction === 'left') {\n phaseOffset = -Math.PI;\n }\n else if (direction === 'none') {\n phaseOffset = 0;\n }\n else {\n console.error('Illegal direction value for liquid fill.');\n }\n\n // wave animation of moving left/right\n if (direction !== 'none' && itemModel.get('waveAnimation')) {\n wave\n .animate('shape', true)\n .when(0, {\n phase: phase\n })\n .when(speed / 2, {\n phase: phaseOffset + phase\n })\n .when(speed, {\n phase: phaseOffset * 2 + phase\n })\n .during(function () {\n if (wavePath) {\n wavePath.dirty(true);\n }\n })\n .start();\n }\n }\n\n /**\n * text on wave\n */\n function getText(waves) {\n var labelModel = itemModel.getModel('label');\n\n function formatLabel() {\n var formatted = seriesModel.getFormattedLabel(0, 'normal');\n var defaultVal = (data.get('value', 0) * 100);\n var defaultLabel = data.getName(0) || seriesModel.name;\n if (!isNaN(defaultVal)) {\n defaultLabel = defaultVal.toFixed(0) + '%';\n }\n return formatted == null ? defaultLabel : formatted;\n }\n\n var textRectOption = {\n z2: 10,\n shape: {\n x: left,\n y: top,\n width: (isFillContainer ? radius[0] : radius) * 2,\n height: (isFillContainer ? radius[1] : radius) * 2\n },\n style: {\n fill: 'transparent'\n },\n textConfig: {\n position: labelModel.get('position') || 'inside'\n },\n silent: true\n };\n var textOption = {\n style: {\n text: formatLabel(),\n textAlign: labelModel.get('align'),\n textVerticalAlign: labelModel.get('baseline')\n }\n };\n Object.assign(textOption.style, echarts.helper.createTextStyle(labelModel));\n\n var outsideTextRect = new echarts.graphic.Rect(textRectOption);\n var insideTextRect = new echarts.graphic.Rect(textRectOption);\n insideTextRect.disableLabelAnimation = true;\n outsideTextRect.disableLabelAnimation = true;\n\n var outsideText = new echarts.graphic.Text(textOption);\n var insideText = new echarts.graphic.Text(textOption);\n outsideTextRect.setTextContent(outsideText);\n\n insideTextRect.setTextContent(insideText);\n var insColor = labelModel.get('insideColor');\n insideText.style.fill = insColor;\n\n var group = new echarts.graphic.Group();\n group.add(outsideTextRect);\n group.add(insideTextRect);\n\n // clip out waves for insideText\n var boundingCircle = getPath(radius, true);\n\n wavePath = new echarts.graphic.CompoundPath({\n shape: {\n paths: waves\n },\n x: cx,\n y: cy\n });\n\n wavePath.setClipPath(boundingCircle);\n insideTextRect.setClipPath(wavePath);\n\n return group;\n }\n },\n\n dispose: function () {\n // dispose nothing here\n }\n});\n","\n/*\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements. See the NOTICE file\n* distributed with this work for additional information\n* regarding copyright ownership. The ASF licenses this file\n* to you under the Apache License, Version 2.0 (the\n* \"License\"); you may not use this file except in compliance\n* with the License. You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied. See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\n\n\n/**\n * AUTO-GENERATED FILE. DO NOT MODIFY.\n */\n\nimport * as zrUtil from 'zrender/lib/core/util';\nvar RADIAN_EPSILON = 1e-4;\n\nfunction _trim(str) {\n return str.replace(/^\\s+|\\s+$/g, '');\n}\n\nexport function linearMap(val, domain, range, clamp) {\n var subDomain = domain[1] - domain[0];\n var subRange = range[1] - range[0];\n\n if (subDomain === 0) {\n return subRange === 0 ? range[0] : (range[0] + range[1]) / 2;\n }\n\n if (clamp) {\n if (subDomain > 0) {\n if (val <= domain[0]) {\n return range[0];\n } else if (val >= domain[1]) {\n return range[1];\n }\n } else {\n if (val >= domain[0]) {\n return range[0];\n } else if (val <= domain[1]) {\n return range[1];\n }\n }\n } else {\n if (val === domain[0]) {\n return range[0];\n }\n\n if (val === domain[1]) {\n return range[1];\n }\n }\n\n return (val - domain[0]) / subDomain * subRange + range[0];\n}\nexport function parsePercent(percent, all) {\n switch (percent) {\n case 'center':\n case 'middle':\n percent = '50%';\n break;\n\n case 'left':\n case 'top':\n percent = '0%';\n break;\n\n case 'right':\n case 'bottom':\n percent = '100%';\n break;\n }\n\n if (typeof percent === 'string') {\n if (_trim(percent).match(/%$/)) {\n return parseFloat(percent) / 100 * all;\n }\n\n return parseFloat(percent);\n }\n\n return percent == null ? NaN : +percent;\n}\nexport function round(x, precision, returnStr) {\n if (precision == null) {\n precision = 10;\n }\n\n precision = Math.min(Math.max(0, precision), 20);\n x = (+x).toFixed(precision);\n return returnStr ? x : +x;\n}\nexport function asc(arr) {\n arr.sort(function (a, b) {\n return a - b;\n });\n return arr;\n}\nexport function getPrecision(val) {\n val = +val;\n\n if (isNaN(val)) {\n return 0;\n }\n\n var e = 1;\n var count = 0;\n\n while (Math.round(val * e) / e !== val) {\n e *= 10;\n count++;\n }\n\n return count;\n}\nexport function getPrecisionSafe(val) {\n var str = val.toString();\n var eIndex = str.indexOf('e');\n\n if (eIndex > 0) {\n var precision = +str.slice(eIndex + 1);\n return precision < 0 ? -precision : 0;\n } else {\n var dotIndex = str.indexOf('.');\n return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;\n }\n}\nexport function getPixelPrecision(dataExtent, pixelExtent) {\n var log = Math.log;\n var LN10 = Math.LN10;\n var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);\n var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);\n var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);\n return !isFinite(precision) ? 20 : precision;\n}\nexport function getPercentWithPrecision(valueList, idx, precision) {\n if (!valueList[idx]) {\n return 0;\n }\n\n var sum = zrUtil.reduce(valueList, function (acc, val) {\n return acc + (isNaN(val) ? 0 : val);\n }, 0);\n\n if (sum === 0) {\n return 0;\n }\n\n var digits = Math.pow(10, precision);\n var votesPerQuota = zrUtil.map(valueList, function (val) {\n return (isNaN(val) ? 0 : val) / sum * digits * 100;\n });\n var targetSeats = digits * 100;\n var seats = zrUtil.map(votesPerQuota, function (votes) {\n return Math.floor(votes);\n });\n var currentSum = zrUtil.reduce(seats, function (acc, val) {\n return acc + val;\n }, 0);\n var remainder = zrUtil.map(votesPerQuota, function (votes, idx) {\n return votes - seats[idx];\n });\n\n while (currentSum < targetSeats) {\n var max = Number.NEGATIVE_INFINITY;\n var maxId = null;\n\n for (var i = 0, len = remainder.length; i < len; ++i) {\n if (remainder[i] > max) {\n max = remainder[i];\n maxId = i;\n }\n }\n\n ++seats[maxId];\n remainder[maxId] = 0;\n ++currentSum;\n }\n\n return seats[idx] / digits;\n}\nexport var MAX_SAFE_INTEGER = 9007199254740991;\nexport function remRadian(radian) {\n var pi2 = Math.PI * 2;\n return (radian % pi2 + pi2) % pi2;\n}\nexport function isRadianAroundZero(val) {\n return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;\n}\nvar TIME_REG = /^(?:(\\d{4})(?:[-\\/](\\d{1,2})(?:[-\\/](\\d{1,2})(?:[T ](\\d{1,2})(?::(\\d{1,2})(?::(\\d{1,2})(?:[.,](\\d+))?)?)?(Z|[\\+\\-]\\d\\d:?\\d\\d)?)?)?)?)?$/;\nexport function parseDate(value) {\n if (value instanceof Date) {\n return value;\n } else if (typeof value === 'string') {\n var match = TIME_REG.exec(value);\n\n if (!match) {\n return new Date(NaN);\n }\n\n if (!match[8]) {\n return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, +match[7] || 0);\n } else {\n var hour = +match[4] || 0;\n\n if (match[8].toUpperCase() !== 'Z') {\n hour -= +match[8].slice(0, 3);\n }\n\n return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, +match[7] || 0));\n }\n } else if (value == null) {\n return new Date(NaN);\n }\n\n return new Date(Math.round(value));\n}\nexport function quantity(val) {\n return Math.pow(10, quantityExponent(val));\n}\nexport function quantityExponent(val) {\n if (val === 0) {\n return 0;\n }\n\n var exp = Math.floor(Math.log(val) / Math.LN10);\n\n if (val / Math.pow(10, exp) >= 10) {\n exp++;\n }\n\n return exp;\n}\nexport function nice(val, round) {\n var exponent = quantityExponent(val);\n var exp10 = Math.pow(10, exponent);\n var f = val / exp10;\n var nf;\n\n if (round) {\n if (f < 1.5) {\n nf = 1;\n } else if (f < 2.5) {\n nf = 2;\n } else if (f < 4) {\n nf = 3;\n } else if (f < 7) {\n nf = 5;\n } else {\n nf = 10;\n }\n } else {\n if (f < 1) {\n nf = 1;\n } else if (f < 2) {\n nf = 2;\n } else if (f < 3) {\n nf = 3;\n } else if (f < 5) {\n nf = 5;\n } else {\n nf = 10;\n }\n }\n\n val = nf * exp10;\n return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;\n}\nexport function quantile(ascArr, p) {\n var H = (ascArr.length - 1) * p + 1;\n var h = Math.floor(H);\n var v = +ascArr[h - 1];\n var e = H - h;\n return e ? v + e * (ascArr[h] - v) : v;\n}\nexport function reformIntervals(list) {\n list.sort(function (a, b) {\n return littleThan(a, b, 0) ? -1 : 1;\n });\n var curr = -Infinity;\n var currClose = 1;\n\n for (var i = 0; i < list.length;) {\n var interval = list[i].interval;\n var close_1 = list[i].close;\n\n for (var lg = 0; lg < 2; lg++) {\n if (interval[lg] <= curr) {\n interval[lg] = curr;\n close_1[lg] = !lg ? 1 - currClose : 1;\n }\n\n curr = interval[lg];\n currClose = close_1[lg];\n }\n\n if (interval[0] === interval[1] && close_1[0] * close_1[1] !== 1) {\n list.splice(i, 1);\n } else {\n i++;\n }\n }\n\n return list;\n\n function littleThan(a, b, lg) {\n 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));\n }\n}\nexport function numericToNumber(val) {\n var valFloat = parseFloat(val);\n return valFloat == val && (valFloat !== 0 || typeof val !== 'string' || val.indexOf('x') <= 0) ? valFloat : NaN;\n}\nexport function isNumeric(val) {\n return !isNaN(numericToNumber(val));\n}\nexport function getRandomIdBase() {\n return Math.round(Math.random() * 9);\n}\nexport function getGreatestCommonDividor(a, b) {\n if (b === 0) {\n return a;\n }\n\n return getGreatestCommonDividor(b, a % b);\n}\nexport function getLeastCommonMultiple(a, b) {\n if (a == null) {\n return b;\n }\n\n if (b == null) {\n return a;\n }\n\n return a * b / getGreatestCommonDividor(a, b);\n}","module.exports = __WEBPACK_EXTERNAL_MODULE__83__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// module exports must be returned from runtime so entry inlining is disabled\n// startup\n// Load entry module and return exports\nreturn __webpack_require__(245);\n","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};"],"sourceRoot":""} -------------------------------------------------------------------------------- /example/fill-container.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 41 | ECharts LiquidFill Example 42 | This is an example showing liquidFill chart that fills the container. 43 | 44 | 45 | 46 | 47 | 82 | 83 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 90 | 91 | 92 | Liquid Fill Chart (ECharts Extension) 93 | 94 | GitHub (Doc & API) 95 | More Examples 96 | ECharts 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 365 | 366 | 367 | -------------------------------------------------------------------------------- /example/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 41 | ECharts LiquidFill Example 42 | This is an example showing liquidFill chart that fills the container. 43 | 44 | 45 | 46 | 65 | 66 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import './src/liquidFill'; 2 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Baidu Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "echarts-liquidfill", 3 | "version": "3.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@discoveryjs/json-ext": { 8 | "version": "0.5.2", 9 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", 10 | "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", 11 | "dev": true 12 | }, 13 | "@types/eslint": { 14 | "version": "7.2.6", 15 | "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", 16 | "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==", 17 | "dev": true, 18 | "requires": { 19 | "@types/estree": "*", 20 | "@types/json-schema": "*" 21 | } 22 | }, 23 | "@types/eslint-scope": { 24 | "version": "3.7.0", 25 | "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", 26 | "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", 27 | "dev": true, 28 | "requires": { 29 | "@types/eslint": "*", 30 | "@types/estree": "*" 31 | } 32 | }, 33 | "@types/estree": { 34 | "version": "0.0.45", 35 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", 36 | "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", 37 | "dev": true 38 | }, 39 | "@types/json-schema": { 40 | "version": "7.0.6", 41 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", 42 | "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", 43 | "dev": true 44 | }, 45 | "@types/node": { 46 | "version": "14.14.20", 47 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", 48 | "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", 49 | "dev": true 50 | }, 51 | "@webassemblyjs/ast": { 52 | "version": "1.9.1", 53 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.1.tgz", 54 | "integrity": "sha512-uMu1nCWn2Wxyy126LlGqRVlhdTOsO/bsBRI4dNq3+6SiSuRKRQX6ejjKgh82LoGAPSq72lDUiQ4FWVaf0PecYw==", 55 | "dev": true, 56 | "requires": { 57 | "@webassemblyjs/helper-module-context": "1.9.1", 58 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1", 59 | "@webassemblyjs/wast-parser": "1.9.1" 60 | } 61 | }, 62 | "@webassemblyjs/floating-point-hex-parser": { 63 | "version": "1.9.1", 64 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.1.tgz", 65 | "integrity": "sha512-5VEKu024RySmLKTTBl9q1eO/2K5jk9ZS+2HXDBLA9s9p5IjkaXxWiDb/+b7wSQp6FRdLaH1IVGIfOex58Na2pg==", 66 | "dev": true 67 | }, 68 | "@webassemblyjs/helper-api-error": { 69 | "version": "1.9.1", 70 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.1.tgz", 71 | "integrity": "sha512-y1lGmfm38djrScwpeL37rRR9f1D6sM8RhMpvM7CYLzOlHVboouZokXK/G88BpzW0NQBSvCCOnW5BFhten4FPfA==", 72 | "dev": true 73 | }, 74 | "@webassemblyjs/helper-buffer": { 75 | "version": "1.9.1", 76 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.1.tgz", 77 | "integrity": "sha512-uS6VSgieHbk/m4GSkMU5cqe/5TekdCzQso4revCIEQ3vpGZgqSSExi4jWpTWwDpAHOIAb1Jfrs0gUB9AA4n71w==", 78 | "dev": true 79 | }, 80 | "@webassemblyjs/helper-code-frame": { 81 | "version": "1.9.1", 82 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.1.tgz", 83 | "integrity": "sha512-ZQ2ZT6Evk4DPIfD+92AraGYaFIqGm4U20e7FpXwl7WUo2Pn1mZ1v8VGH8i+Y++IQpxPbQo/UyG0Khs7eInskzA==", 84 | "dev": true, 85 | "requires": { 86 | "@webassemblyjs/wast-printer": "1.9.1" 87 | } 88 | }, 89 | "@webassemblyjs/helper-fsm": { 90 | "version": "1.9.1", 91 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.1.tgz", 92 | "integrity": "sha512-J32HGpveEqqcKFS0YbgicB0zAlpfIxJa5MjxDxhu3i5ltPcVfY5EPvKQ1suRguFPehxiUs+/hfkwPEXom/l0lw==", 93 | "dev": true 94 | }, 95 | "@webassemblyjs/helper-module-context": { 96 | "version": "1.9.1", 97 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.1.tgz", 98 | "integrity": "sha512-IEH2cMmEQKt7fqelLWB5e/cMdZXf2rST1JIrzWmf4XBt3QTxGdnnLvV4DYoN8pJjOx0VYXsWg+yF16MmJtolZg==", 99 | "dev": true, 100 | "requires": { 101 | "@webassemblyjs/ast": "1.9.1" 102 | } 103 | }, 104 | "@webassemblyjs/helper-wasm-bytecode": { 105 | "version": "1.9.1", 106 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.1.tgz", 107 | "integrity": "sha512-i2rGTBqFUcSXxyjt2K4vm/3kkHwyzG6o427iCjcIKjOqpWH8SEem+xe82jUk1iydJO250/CvE5o7hzNAMZf0dQ==", 108 | "dev": true 109 | }, 110 | "@webassemblyjs/helper-wasm-section": { 111 | "version": "1.9.1", 112 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.1.tgz", 113 | "integrity": "sha512-FetqzjtXZr2d57IECK+aId3D0IcGweeM0CbAnJHkYJkcRTHP+YcMb7Wmc0j21h5UWBpwYGb9dSkK/93SRCTrGg==", 114 | "dev": true, 115 | "requires": { 116 | "@webassemblyjs/ast": "1.9.1", 117 | "@webassemblyjs/helper-buffer": "1.9.1", 118 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1", 119 | "@webassemblyjs/wasm-gen": "1.9.1" 120 | } 121 | }, 122 | "@webassemblyjs/ieee754": { 123 | "version": "1.9.1", 124 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.1.tgz", 125 | "integrity": "sha512-EvTG9M78zP1MmkBpUjGQHZc26DzPGZSLIPxYHCjQsBMo60Qy2W34qf8z0exRDtxBbRIoiKa5dFyWer/7r1aaSQ==", 126 | "dev": true, 127 | "requires": { 128 | "@xtuc/ieee754": "^1.2.0" 129 | } 130 | }, 131 | "@webassemblyjs/leb128": { 132 | "version": "1.9.1", 133 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.1.tgz", 134 | "integrity": "sha512-Oc04ub0vFfLnF+2/+ki3AE+anmW4sv9uNBqb+79fgTaPv6xJsOT0dhphNfL3FrME84CbX/D1T9XT8tjFo0IIiw==", 135 | "dev": true, 136 | "requires": { 137 | "@xtuc/long": "4.2.2" 138 | } 139 | }, 140 | "@webassemblyjs/utf8": { 141 | "version": "1.9.1", 142 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.1.tgz", 143 | "integrity": "sha512-llkYtppagjCodFjo0alWOUhAkfOiQPQDIc5oA6C9sFAXz7vC9QhZf/f8ijQIX+A9ToM3c9Pq85X0EX7nx9gVhg==", 144 | "dev": true 145 | }, 146 | "@webassemblyjs/wasm-edit": { 147 | "version": "1.9.1", 148 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.1.tgz", 149 | "integrity": "sha512-S2IaD6+x9B2Xi8BCT0eGsrXXd8UxAh2LVJpg1ZMtHXnrDcsTtIX2bDjHi40Hio6Lc62dWHmKdvksI+MClCYbbw==", 150 | "dev": true, 151 | "requires": { 152 | "@webassemblyjs/ast": "1.9.1", 153 | "@webassemblyjs/helper-buffer": "1.9.1", 154 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1", 155 | "@webassemblyjs/helper-wasm-section": "1.9.1", 156 | "@webassemblyjs/wasm-gen": "1.9.1", 157 | "@webassemblyjs/wasm-opt": "1.9.1", 158 | "@webassemblyjs/wasm-parser": "1.9.1", 159 | "@webassemblyjs/wast-printer": "1.9.1" 160 | } 161 | }, 162 | "@webassemblyjs/wasm-gen": { 163 | "version": "1.9.1", 164 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.1.tgz", 165 | "integrity": "sha512-bqWI0S4lBQsEN5FTZ35vYzfKUJvtjNnBobB1agCALH30xNk1LToZ7Z8eiaR/Z5iVECTlBndoRQV3F6mbEqE/fg==", 166 | "dev": true, 167 | "requires": { 168 | "@webassemblyjs/ast": "1.9.1", 169 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1", 170 | "@webassemblyjs/ieee754": "1.9.1", 171 | "@webassemblyjs/leb128": "1.9.1", 172 | "@webassemblyjs/utf8": "1.9.1" 173 | } 174 | }, 175 | "@webassemblyjs/wasm-opt": { 176 | "version": "1.9.1", 177 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.1.tgz", 178 | "integrity": "sha512-gSf7I7YWVXZ5c6XqTEqkZjVs8K1kc1k57vsB6KBQscSagDNbAdxt6MwuJoMjsE1yWY1tsuL+pga268A6u+Fdkg==", 179 | "dev": true, 180 | "requires": { 181 | "@webassemblyjs/ast": "1.9.1", 182 | "@webassemblyjs/helper-buffer": "1.9.1", 183 | "@webassemblyjs/wasm-gen": "1.9.1", 184 | "@webassemblyjs/wasm-parser": "1.9.1" 185 | } 186 | }, 187 | "@webassemblyjs/wasm-parser": { 188 | "version": "1.9.1", 189 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.1.tgz", 190 | "integrity": "sha512-ImM4N2T1MEIond0MyE3rXvStVxEmivQrDKf/ggfh5pP6EHu3lL/YTAoSrR7shrbKNPpeKpGesW1LIK/L4kqduw==", 191 | "dev": true, 192 | "requires": { 193 | "@webassemblyjs/ast": "1.9.1", 194 | "@webassemblyjs/helper-api-error": "1.9.1", 195 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1", 196 | "@webassemblyjs/ieee754": "1.9.1", 197 | "@webassemblyjs/leb128": "1.9.1", 198 | "@webassemblyjs/utf8": "1.9.1" 199 | } 200 | }, 201 | "@webassemblyjs/wast-parser": { 202 | "version": "1.9.1", 203 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.1.tgz", 204 | "integrity": "sha512-2xVxejXSvj3ls/o2TR/zI6p28qsGupjHhnHL6URULQRcXmryn3w7G83jQMcT7PHqUfyle65fZtWLukfdLdE7qw==", 205 | "dev": true, 206 | "requires": { 207 | "@webassemblyjs/ast": "1.9.1", 208 | "@webassemblyjs/floating-point-hex-parser": "1.9.1", 209 | "@webassemblyjs/helper-api-error": "1.9.1", 210 | "@webassemblyjs/helper-code-frame": "1.9.1", 211 | "@webassemblyjs/helper-fsm": "1.9.1", 212 | "@xtuc/long": "4.2.2" 213 | } 214 | }, 215 | "@webassemblyjs/wast-printer": { 216 | "version": "1.9.1", 217 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.1.tgz", 218 | "integrity": "sha512-tDV8V15wm7mmbAH6XvQRU1X+oPGmeOzYsd6h7hlRLz6QpV4Ec/KKxM8OpLtFmQPLCreGxTp+HuxtH4pRIZyL9w==", 219 | "dev": true, 220 | "requires": { 221 | "@webassemblyjs/ast": "1.9.1", 222 | "@webassemblyjs/wast-parser": "1.9.1", 223 | "@xtuc/long": "4.2.2" 224 | } 225 | }, 226 | "@webpack-cli/info": { 227 | "version": "1.2.1", 228 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", 229 | "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", 230 | "dev": true, 231 | "requires": { 232 | "envinfo": "^7.7.3" 233 | } 234 | }, 235 | "@webpack-cli/serve": { 236 | "version": "1.2.1", 237 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.1.tgz", 238 | "integrity": "sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==", 239 | "dev": true 240 | }, 241 | "@xtuc/ieee754": { 242 | "version": "1.2.0", 243 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", 244 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", 245 | "dev": true 246 | }, 247 | "@xtuc/long": { 248 | "version": "4.2.2", 249 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", 250 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", 251 | "dev": true 252 | }, 253 | "acorn": { 254 | "version": "8.0.4", 255 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", 256 | "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", 257 | "dev": true 258 | }, 259 | "ajv": { 260 | "version": "6.12.6", 261 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 262 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 263 | "dev": true, 264 | "requires": { 265 | "fast-deep-equal": "^3.1.1", 266 | "fast-json-stable-stringify": "^2.0.0", 267 | "json-schema-traverse": "^0.4.1", 268 | "uri-js": "^4.2.2" 269 | } 270 | }, 271 | "ajv-keywords": { 272 | "version": "3.5.2", 273 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", 274 | "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", 275 | "dev": true 276 | }, 277 | "ansi-colors": { 278 | "version": "4.1.1", 279 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 280 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 281 | "dev": true 282 | }, 283 | "browserslist": { 284 | "version": "4.16.1", 285 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", 286 | "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", 287 | "dev": true, 288 | "requires": { 289 | "caniuse-lite": "^1.0.30001173", 290 | "colorette": "^1.2.1", 291 | "electron-to-chromium": "^1.3.634", 292 | "escalade": "^3.1.1", 293 | "node-releases": "^1.1.69" 294 | } 295 | }, 296 | "buffer-from": { 297 | "version": "1.1.1", 298 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 299 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 300 | "dev": true 301 | }, 302 | "caniuse-lite": { 303 | "version": "1.0.30001173", 304 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001173.tgz", 305 | "integrity": "sha512-R3aqmjrICdGCTAnSXtNyvWYMK3YtV5jwudbq0T7nN9k4kmE4CBuwPqyJ+KBzepSTh0huivV2gLbSMEzTTmfeYw==", 306 | "dev": true 307 | }, 308 | "chrome-trace-event": { 309 | "version": "1.0.2", 310 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", 311 | "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", 312 | "dev": true, 313 | "requires": { 314 | "tslib": "^1.9.0" 315 | } 316 | }, 317 | "colorette": { 318 | "version": "1.2.1", 319 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", 320 | "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", 321 | "dev": true 322 | }, 323 | "commander": { 324 | "version": "2.20.3", 325 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 326 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 327 | "dev": true 328 | }, 329 | "cross-spawn": { 330 | "version": "7.0.3", 331 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 332 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 333 | "dev": true, 334 | "requires": { 335 | "path-key": "^3.1.0", 336 | "shebang-command": "^2.0.0", 337 | "which": "^2.0.1" 338 | } 339 | }, 340 | "echarts": { 341 | "version": "5.0.1", 342 | "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.1.tgz", 343 | "integrity": "sha512-JYn22Dolt2esY2jEzUsw1OxbobuW67oGjIoTjZO3rW89SWkfJ4kbrmC2OW9JjsBrD1rdkmaWBuZZ2HgmThyxJw==", 344 | "dev": true, 345 | "requires": { 346 | "tslib": "2.0.3", 347 | "zrender": "5.0.3" 348 | }, 349 | "dependencies": { 350 | "tslib": { 351 | "version": "2.0.3", 352 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", 353 | "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", 354 | "dev": true 355 | } 356 | } 357 | }, 358 | "electron-to-chromium": { 359 | "version": "1.3.634", 360 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.634.tgz", 361 | "integrity": "sha512-QPrWNYeE/A0xRvl/QP3E0nkaEvYUvH3gM04ZWYtIa6QlSpEetRlRI1xvQ7hiMIySHHEV+mwDSX8Kj4YZY6ZQAw==", 362 | "dev": true 363 | }, 364 | "enhanced-resolve": { 365 | "version": "5.4.1", 366 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz", 367 | "integrity": "sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA==", 368 | "dev": true, 369 | "requires": { 370 | "graceful-fs": "^4.2.4", 371 | "tapable": "^2.2.0" 372 | } 373 | }, 374 | "enquirer": { 375 | "version": "2.3.6", 376 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 377 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 378 | "dev": true, 379 | "requires": { 380 | "ansi-colors": "^4.1.1" 381 | } 382 | }, 383 | "envinfo": { 384 | "version": "7.7.3", 385 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", 386 | "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", 387 | "dev": true 388 | }, 389 | "escalade": { 390 | "version": "3.1.1", 391 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 392 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 393 | "dev": true 394 | }, 395 | "eslint-scope": { 396 | "version": "5.1.1", 397 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 398 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 399 | "dev": true, 400 | "requires": { 401 | "esrecurse": "^4.3.0", 402 | "estraverse": "^4.1.1" 403 | } 404 | }, 405 | "esrecurse": { 406 | "version": "4.3.0", 407 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 408 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 409 | "dev": true, 410 | "requires": { 411 | "estraverse": "^5.2.0" 412 | }, 413 | "dependencies": { 414 | "estraverse": { 415 | "version": "5.2.0", 416 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 417 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 418 | "dev": true 419 | } 420 | } 421 | }, 422 | "estraverse": { 423 | "version": "4.3.0", 424 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 425 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 426 | "dev": true 427 | }, 428 | "events": { 429 | "version": "3.2.0", 430 | "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", 431 | "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", 432 | "dev": true 433 | }, 434 | "execa": { 435 | "version": "5.0.0", 436 | "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", 437 | "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", 438 | "dev": true, 439 | "requires": { 440 | "cross-spawn": "^7.0.3", 441 | "get-stream": "^6.0.0", 442 | "human-signals": "^2.1.0", 443 | "is-stream": "^2.0.0", 444 | "merge-stream": "^2.0.0", 445 | "npm-run-path": "^4.0.1", 446 | "onetime": "^5.1.2", 447 | "signal-exit": "^3.0.3", 448 | "strip-final-newline": "^2.0.0" 449 | } 450 | }, 451 | "fast-deep-equal": { 452 | "version": "3.1.3", 453 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 454 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 455 | "dev": true 456 | }, 457 | "fast-json-stable-stringify": { 458 | "version": "2.1.0", 459 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 460 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 461 | "dev": true 462 | }, 463 | "fastest-levenshtein": { 464 | "version": "1.0.12", 465 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", 466 | "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", 467 | "dev": true 468 | }, 469 | "find-up": { 470 | "version": "5.0.0", 471 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 472 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 473 | "dev": true, 474 | "requires": { 475 | "locate-path": "^6.0.0", 476 | "path-exists": "^4.0.0" 477 | } 478 | }, 479 | "function-bind": { 480 | "version": "1.1.1", 481 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 482 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 483 | "dev": true 484 | }, 485 | "get-stream": { 486 | "version": "6.0.0", 487 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", 488 | "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", 489 | "dev": true 490 | }, 491 | "glob-to-regexp": { 492 | "version": "0.4.1", 493 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 494 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 495 | "dev": true 496 | }, 497 | "graceful-fs": { 498 | "version": "4.2.4", 499 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 500 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 501 | "dev": true 502 | }, 503 | "has": { 504 | "version": "1.0.3", 505 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 506 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 507 | "dev": true, 508 | "requires": { 509 | "function-bind": "^1.1.1" 510 | } 511 | }, 512 | "has-flag": { 513 | "version": "4.0.0", 514 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 515 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 516 | "dev": true 517 | }, 518 | "human-signals": { 519 | "version": "2.1.0", 520 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", 521 | "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", 522 | "dev": true 523 | }, 524 | "import-local": { 525 | "version": "3.0.2", 526 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", 527 | "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", 528 | "dev": true, 529 | "requires": { 530 | "pkg-dir": "^4.2.0", 531 | "resolve-cwd": "^3.0.0" 532 | }, 533 | "dependencies": { 534 | "find-up": { 535 | "version": "4.1.0", 536 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 537 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 538 | "dev": true, 539 | "requires": { 540 | "locate-path": "^5.0.0", 541 | "path-exists": "^4.0.0" 542 | } 543 | }, 544 | "locate-path": { 545 | "version": "5.0.0", 546 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 547 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 548 | "dev": true, 549 | "requires": { 550 | "p-locate": "^4.1.0" 551 | } 552 | }, 553 | "p-limit": { 554 | "version": "2.3.0", 555 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 556 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 557 | "dev": true, 558 | "requires": { 559 | "p-try": "^2.0.0" 560 | } 561 | }, 562 | "p-locate": { 563 | "version": "4.1.0", 564 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 565 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 566 | "dev": true, 567 | "requires": { 568 | "p-limit": "^2.2.0" 569 | } 570 | }, 571 | "pkg-dir": { 572 | "version": "4.2.0", 573 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 574 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 575 | "dev": true, 576 | "requires": { 577 | "find-up": "^4.0.0" 578 | } 579 | } 580 | } 581 | }, 582 | "interpret": { 583 | "version": "2.2.0", 584 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", 585 | "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", 586 | "dev": true 587 | }, 588 | "is-core-module": { 589 | "version": "2.2.0", 590 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", 591 | "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", 592 | "dev": true, 593 | "requires": { 594 | "has": "^1.0.3" 595 | } 596 | }, 597 | "is-stream": { 598 | "version": "2.0.0", 599 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", 600 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", 601 | "dev": true 602 | }, 603 | "isexe": { 604 | "version": "2.0.0", 605 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 606 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 607 | "dev": true 608 | }, 609 | "jest-worker": { 610 | "version": "26.6.2", 611 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", 612 | "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", 613 | "dev": true, 614 | "requires": { 615 | "@types/node": "*", 616 | "merge-stream": "^2.0.0", 617 | "supports-color": "^7.0.0" 618 | } 619 | }, 620 | "json-parse-better-errors": { 621 | "version": "1.0.2", 622 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 623 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", 624 | "dev": true 625 | }, 626 | "json-schema-traverse": { 627 | "version": "0.4.1", 628 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 629 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 630 | "dev": true 631 | }, 632 | "loader-runner": { 633 | "version": "4.1.0", 634 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", 635 | "integrity": "sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA==", 636 | "dev": true 637 | }, 638 | "locate-path": { 639 | "version": "6.0.0", 640 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 641 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 642 | "dev": true, 643 | "requires": { 644 | "p-locate": "^5.0.0" 645 | } 646 | }, 647 | "lodash": { 648 | "version": "4.17.20", 649 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 650 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", 651 | "dev": true 652 | }, 653 | "merge-stream": { 654 | "version": "2.0.0", 655 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 656 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 657 | "dev": true 658 | }, 659 | "mime-db": { 660 | "version": "1.45.0", 661 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", 662 | "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", 663 | "dev": true 664 | }, 665 | "mime-types": { 666 | "version": "2.1.28", 667 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", 668 | "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", 669 | "dev": true, 670 | "requires": { 671 | "mime-db": "1.45.0" 672 | } 673 | }, 674 | "mimic-fn": { 675 | "version": "2.1.0", 676 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 677 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 678 | "dev": true 679 | }, 680 | "neo-async": { 681 | "version": "2.6.2", 682 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 683 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 684 | "dev": true 685 | }, 686 | "node-releases": { 687 | "version": "1.1.69", 688 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz", 689 | "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==", 690 | "dev": true 691 | }, 692 | "npm-run-path": { 693 | "version": "4.0.1", 694 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", 695 | "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", 696 | "dev": true, 697 | "requires": { 698 | "path-key": "^3.0.0" 699 | } 700 | }, 701 | "onetime": { 702 | "version": "5.1.2", 703 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", 704 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", 705 | "dev": true, 706 | "requires": { 707 | "mimic-fn": "^2.1.0" 708 | } 709 | }, 710 | "p-limit": { 711 | "version": "3.1.0", 712 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 713 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 714 | "dev": true, 715 | "requires": { 716 | "yocto-queue": "^0.1.0" 717 | } 718 | }, 719 | "p-locate": { 720 | "version": "5.0.0", 721 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 722 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 723 | "dev": true, 724 | "requires": { 725 | "p-limit": "^3.0.2" 726 | } 727 | }, 728 | "p-try": { 729 | "version": "2.2.0", 730 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 731 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 732 | "dev": true 733 | }, 734 | "path-exists": { 735 | "version": "4.0.0", 736 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 737 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 738 | "dev": true 739 | }, 740 | "path-key": { 741 | "version": "3.1.1", 742 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 743 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 744 | "dev": true 745 | }, 746 | "path-parse": { 747 | "version": "1.0.6", 748 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 749 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 750 | "dev": true 751 | }, 752 | "pkg-dir": { 753 | "version": "5.0.0", 754 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", 755 | "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", 756 | "dev": true, 757 | "requires": { 758 | "find-up": "^5.0.0" 759 | } 760 | }, 761 | "punycode": { 762 | "version": "2.1.1", 763 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 764 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 765 | "dev": true 766 | }, 767 | "randombytes": { 768 | "version": "2.1.0", 769 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 770 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 771 | "dev": true, 772 | "requires": { 773 | "safe-buffer": "^5.1.0" 774 | } 775 | }, 776 | "rechoir": { 777 | "version": "0.7.0", 778 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", 779 | "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", 780 | "dev": true, 781 | "requires": { 782 | "resolve": "^1.9.0" 783 | } 784 | }, 785 | "resolve": { 786 | "version": "1.19.0", 787 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", 788 | "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", 789 | "dev": true, 790 | "requires": { 791 | "is-core-module": "^2.1.0", 792 | "path-parse": "^1.0.6" 793 | } 794 | }, 795 | "resolve-cwd": { 796 | "version": "3.0.0", 797 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", 798 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", 799 | "dev": true, 800 | "requires": { 801 | "resolve-from": "^5.0.0" 802 | } 803 | }, 804 | "resolve-from": { 805 | "version": "5.0.0", 806 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 807 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 808 | "dev": true 809 | }, 810 | "safe-buffer": { 811 | "version": "5.2.1", 812 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 813 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 814 | "dev": true 815 | }, 816 | "schema-utils": { 817 | "version": "3.0.0", 818 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", 819 | "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", 820 | "dev": true, 821 | "requires": { 822 | "@types/json-schema": "^7.0.6", 823 | "ajv": "^6.12.5", 824 | "ajv-keywords": "^3.5.2" 825 | } 826 | }, 827 | "serialize-javascript": { 828 | "version": "5.0.1", 829 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", 830 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", 831 | "dev": true, 832 | "requires": { 833 | "randombytes": "^2.1.0" 834 | } 835 | }, 836 | "shebang-command": { 837 | "version": "2.0.0", 838 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 839 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 840 | "dev": true, 841 | "requires": { 842 | "shebang-regex": "^3.0.0" 843 | } 844 | }, 845 | "shebang-regex": { 846 | "version": "3.0.0", 847 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 848 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 849 | "dev": true 850 | }, 851 | "signal-exit": { 852 | "version": "3.0.3", 853 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 854 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 855 | "dev": true 856 | }, 857 | "source-list-map": { 858 | "version": "2.0.1", 859 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", 860 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", 861 | "dev": true 862 | }, 863 | "source-map": { 864 | "version": "0.6.1", 865 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 866 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 867 | "dev": true 868 | }, 869 | "source-map-support": { 870 | "version": "0.5.19", 871 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 872 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 873 | "dev": true, 874 | "requires": { 875 | "buffer-from": "^1.0.0", 876 | "source-map": "^0.6.0" 877 | } 878 | }, 879 | "strip-final-newline": { 880 | "version": "2.0.0", 881 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", 882 | "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", 883 | "dev": true 884 | }, 885 | "supports-color": { 886 | "version": "7.2.0", 887 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 888 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 889 | "dev": true, 890 | "requires": { 891 | "has-flag": "^4.0.0" 892 | } 893 | }, 894 | "tapable": { 895 | "version": "2.2.0", 896 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", 897 | "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", 898 | "dev": true 899 | }, 900 | "terser": { 901 | "version": "5.5.1", 902 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", 903 | "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", 904 | "dev": true, 905 | "requires": { 906 | "commander": "^2.20.0", 907 | "source-map": "~0.7.2", 908 | "source-map-support": "~0.5.19" 909 | }, 910 | "dependencies": { 911 | "source-map": { 912 | "version": "0.7.3", 913 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", 914 | "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", 915 | "dev": true 916 | } 917 | } 918 | }, 919 | "terser-webpack-plugin": { 920 | "version": "5.0.3", 921 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz", 922 | "integrity": "sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ==", 923 | "dev": true, 924 | "requires": { 925 | "jest-worker": "^26.6.1", 926 | "p-limit": "^3.0.2", 927 | "schema-utils": "^3.0.0", 928 | "serialize-javascript": "^5.0.1", 929 | "source-map": "^0.6.1", 930 | "terser": "^5.3.8" 931 | } 932 | }, 933 | "tslib": { 934 | "version": "1.14.1", 935 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 936 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", 937 | "dev": true 938 | }, 939 | "uri-js": { 940 | "version": "4.4.0", 941 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", 942 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", 943 | "dev": true, 944 | "requires": { 945 | "punycode": "^2.1.0" 946 | } 947 | }, 948 | "v8-compile-cache": { 949 | "version": "2.2.0", 950 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", 951 | "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", 952 | "dev": true 953 | }, 954 | "watchpack": { 955 | "version": "2.1.0", 956 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", 957 | "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", 958 | "dev": true, 959 | "requires": { 960 | "glob-to-regexp": "^0.4.1", 961 | "graceful-fs": "^4.1.2" 962 | } 963 | }, 964 | "webpack": { 965 | "version": "5.11.1", 966 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.11.1.tgz", 967 | "integrity": "sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ==", 968 | "dev": true, 969 | "requires": { 970 | "@types/eslint-scope": "^3.7.0", 971 | "@types/estree": "^0.0.45", 972 | "@webassemblyjs/ast": "1.9.1", 973 | "@webassemblyjs/helper-module-context": "1.9.1", 974 | "@webassemblyjs/wasm-edit": "1.9.1", 975 | "@webassemblyjs/wasm-parser": "1.9.1", 976 | "acorn": "^8.0.4", 977 | "browserslist": "^4.14.5", 978 | "chrome-trace-event": "^1.0.2", 979 | "enhanced-resolve": "^5.3.1", 980 | "eslint-scope": "^5.1.1", 981 | "events": "^3.2.0", 982 | "glob-to-regexp": "^0.4.1", 983 | "graceful-fs": "^4.2.4", 984 | "json-parse-better-errors": "^1.0.2", 985 | "loader-runner": "^4.1.0", 986 | "mime-types": "^2.1.27", 987 | "neo-async": "^2.6.2", 988 | "pkg-dir": "^5.0.0", 989 | "schema-utils": "^3.0.0", 990 | "tapable": "^2.1.1", 991 | "terser-webpack-plugin": "^5.0.3", 992 | "watchpack": "^2.0.0", 993 | "webpack-sources": "^2.1.1" 994 | } 995 | }, 996 | "webpack-cli": { 997 | "version": "4.3.1", 998 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.3.1.tgz", 999 | "integrity": "sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==", 1000 | "dev": true, 1001 | "requires": { 1002 | "@discoveryjs/json-ext": "^0.5.0", 1003 | "@webpack-cli/info": "^1.2.1", 1004 | "@webpack-cli/serve": "^1.2.1", 1005 | "colorette": "^1.2.1", 1006 | "commander": "^6.2.0", 1007 | "enquirer": "^2.3.6", 1008 | "execa": "^5.0.0", 1009 | "fastest-levenshtein": "^1.0.12", 1010 | "import-local": "^3.0.2", 1011 | "interpret": "^2.2.0", 1012 | "rechoir": "^0.7.0", 1013 | "v8-compile-cache": "^2.2.0", 1014 | "webpack-merge": "^4.2.2" 1015 | }, 1016 | "dependencies": { 1017 | "commander": { 1018 | "version": "6.2.1", 1019 | "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", 1020 | "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", 1021 | "dev": true 1022 | } 1023 | } 1024 | }, 1025 | "webpack-merge": { 1026 | "version": "4.2.2", 1027 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", 1028 | "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", 1029 | "dev": true, 1030 | "requires": { 1031 | "lodash": "^4.17.15" 1032 | } 1033 | }, 1034 | "webpack-sources": { 1035 | "version": "2.2.0", 1036 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", 1037 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", 1038 | "dev": true, 1039 | "requires": { 1040 | "source-list-map": "^2.0.1", 1041 | "source-map": "^0.6.1" 1042 | } 1043 | }, 1044 | "which": { 1045 | "version": "2.0.2", 1046 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1047 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1048 | "dev": true, 1049 | "requires": { 1050 | "isexe": "^2.0.0" 1051 | } 1052 | }, 1053 | "yocto-queue": { 1054 | "version": "0.1.0", 1055 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1056 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1057 | "dev": true 1058 | }, 1059 | "zrender": { 1060 | "version": "5.0.3", 1061 | "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.3.tgz", 1062 | "integrity": "sha512-TVcN2IMdo7je3GEq/E4CER4AGBe/n50/izILdupppyHf/hVHuiXCRliqdu8+32Z1OmGg6RfKt5qQlkX+bOtU0g==", 1063 | "dev": true, 1064 | "requires": { 1065 | "tslib": "2.0.3" 1066 | }, 1067 | "dependencies": { 1068 | "tslib": { 1069 | "version": "2.0.3", 1070 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", 1071 | "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", 1072 | "dev": true 1073 | } 1074 | } 1075 | } 1076 | } 1077 | } 1078 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "echarts-liquidfill", 3 | "version": "3.1.0", 4 | "description": "ECharts liquid fill extension", 5 | "main": "dist/echarts-liquidfill.js", 6 | "module": "index.js", 7 | "scripts": { 8 | "dev": "webpack --mode development --watch", 9 | "build": "webpack --mode development", 10 | "release": "webpack --mode production && webpack --mode development" 11 | }, 12 | "author": { 13 | "name": "Ovilia", 14 | "email": "me@zhangwenli.com", 15 | "url": "http://zhangwenli.com" 16 | }, 17 | "license": "MIT", 18 | "peerDependencies": { 19 | "echarts": "^5.0.1" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/ecomfe/echarts-liquidfill" 24 | }, 25 | "devDependencies": { 26 | "echarts": "^5.2.0", 27 | "webpack": "^5.11.1", 28 | "webpack-cli": "^4.3.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/liquidFill.js: -------------------------------------------------------------------------------- 1 | import './liquidFillSeries'; 2 | import './liquidFillView'; -------------------------------------------------------------------------------- /src/liquidFillSeries.js: -------------------------------------------------------------------------------- 1 | import * as echarts from 'echarts/lib/echarts'; 2 | 3 | echarts.extendSeriesModel({ 4 | 5 | type: 'series.liquidFill', 6 | 7 | optionUpdated: function () { 8 | var option = this.option; 9 | option.gridSize = Math.max(Math.floor(option.gridSize), 4); 10 | }, 11 | 12 | getInitialData: function (option, ecModel) { 13 | var dimensions = echarts.helper.createDimensions(option.data, { 14 | coordDimensions: ['value'] 15 | }); 16 | var list = new echarts.List(dimensions, this); 17 | list.initData(option.data); 18 | return list; 19 | }, 20 | 21 | defaultOption: { 22 | color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'], 23 | center: ['50%', '50%'], 24 | radius: '50%', 25 | amplitude: '8%', 26 | waveLength: '80%', 27 | phase: 'auto', 28 | period: 'auto', 29 | direction: 'right', 30 | shape: 'circle', 31 | 32 | waveAnimation: true, 33 | animationEasing: 'linear', 34 | animationEasingUpdate: 'linear', 35 | animationDuration: 2000, 36 | animationDurationUpdate: 1000, 37 | 38 | outline: { 39 | show: true, 40 | borderDistance: 8, 41 | itemStyle: { 42 | color: 'none', 43 | borderColor: '#294D99', 44 | borderWidth: 8, 45 | shadowBlur: 20, 46 | shadowColor: 'rgba(0, 0, 0, 0.25)' 47 | } 48 | }, 49 | 50 | backgroundStyle: { 51 | color: '#E3F7FF' 52 | }, 53 | 54 | itemStyle: { 55 | opacity: 0.95, 56 | shadowBlur: 50, 57 | shadowColor: 'rgba(0, 0, 0, 0.4)' 58 | }, 59 | 60 | label: { 61 | show: true, 62 | color: '#294D99', 63 | insideColor: '#fff', 64 | fontSize: 50, 65 | fontWeight: 'bold', 66 | 67 | align: 'center', 68 | baseline: 'middle', 69 | position: 'inside' 70 | }, 71 | 72 | emphasis: { 73 | itemStyle: { 74 | opacity: 0.8 75 | } 76 | } 77 | } 78 | }); 79 | -------------------------------------------------------------------------------- /src/liquidFillShape.js: -------------------------------------------------------------------------------- 1 | import * as echarts from 'echarts/lib/echarts'; 2 | 3 | export default echarts.graphic.extendShape({ 4 | type: 'ec-liquid-fill', 5 | 6 | shape: { 7 | waveLength: 0, 8 | radius: 0, 9 | radiusY: 0, 10 | cx: 0, 11 | cy: 0, 12 | waterLevel: 0, 13 | amplitude: 0, 14 | phase: 0, 15 | inverse: false 16 | }, 17 | 18 | buildPath: function (ctx, shape) { 19 | if (shape.radiusY == null) { 20 | shape.radiusY = shape.radius; 21 | } 22 | 23 | /** 24 | * We define a sine wave having 4 waves, and make sure at least 8 curves 25 | * is drawn. Otherwise, it may cause blank area for some waves when 26 | * wave length is large enough. 27 | */ 28 | var curves = Math.max( 29 | Math.ceil(2 * shape.radius / shape.waveLength * 4) * 2, 30 | 8 31 | ); 32 | 33 | // map phase to [-Math.PI * 2, 0] 34 | while (shape.phase < -Math.PI * 2) { 35 | shape.phase += Math.PI * 2; 36 | } 37 | while (shape.phase > 0) { 38 | shape.phase -= Math.PI * 2; 39 | } 40 | var phase = shape.phase / Math.PI / 2 * shape.waveLength; 41 | 42 | var left = shape.cx - shape.radius + phase - shape.radius * 2; 43 | 44 | /** 45 | * top-left corner as start point 46 | * 47 | * draws this point 48 | * | 49 | * \|/ 50 | * ~~~~~~~~ 51 | * | | 52 | * +------+ 53 | */ 54 | ctx.moveTo(left, shape.waterLevel); 55 | 56 | /** 57 | * top wave 58 | * 59 | * ~~~~~~~~ <- draws this sine wave 60 | * | | 61 | * +------+ 62 | */ 63 | var waveRight = 0; 64 | for (var c = 0; c < curves; ++c) { 65 | var stage = c % 4; 66 | var pos = getWaterPositions(c * shape.waveLength / 4, stage, 67 | shape.waveLength, shape.amplitude); 68 | ctx.bezierCurveTo(pos[0][0] + left, -pos[0][1] + shape.waterLevel, 69 | pos[1][0] + left, -pos[1][1] + shape.waterLevel, 70 | pos[2][0] + left, -pos[2][1] + shape.waterLevel); 71 | 72 | if (c === curves - 1) { 73 | waveRight = pos[2][0]; 74 | } 75 | } 76 | 77 | if (shape.inverse) { 78 | /** 79 | * top-right corner 80 | * 2. draws this line 81 | * | 82 | * +------+ 83 | * 3. draws this line -> | | <- 1. draws this line 84 | * ~~~~~~~~ 85 | */ 86 | ctx.lineTo(waveRight + left, shape.cy - shape.radiusY); 87 | ctx.lineTo(left, shape.cy - shape.radiusY); 88 | ctx.lineTo(left, shape.waterLevel); 89 | } 90 | else { 91 | /** 92 | * top-right corner 93 | * 94 | * ~~~~~~~~ 95 | * 3. draws this line -> | | <- 1. draws this line 96 | * +------+ 97 | * ^ 98 | * | 99 | * 2. draws this line 100 | */ 101 | ctx.lineTo(waveRight + left, shape.cy + shape.radiusY); 102 | ctx.lineTo(left, shape.cy + shape.radiusY); 103 | ctx.lineTo(left, shape.waterLevel); 104 | } 105 | 106 | ctx.closePath(); 107 | } 108 | }); 109 | 110 | 111 | 112 | /** 113 | * Using Bezier curves to fit sine wave. 114 | * There is 4 control points for each curve of wave, 115 | * which is at 1/4 wave length of the sine wave. 116 | * 117 | * The control points for a wave from (a) to (d) are a-b-c-d: 118 | * c *----* d 119 | * b * 120 | * | 121 | * ... a * .................. 122 | * 123 | * whose positions are a: (0, 0), b: (0.5, 0.5), c: (1, 1), d: (PI / 2, 1) 124 | * 125 | * @param {number} x x position of the left-most point (a) 126 | * @param {number} stage 0-3, stating which part of the wave it is 127 | * @param {number} waveLength wave length of the sine wave 128 | * @param {number} amplitude wave amplitude 129 | */ 130 | function getWaterPositions(x, stage, waveLength, amplitude) { 131 | if (stage === 0) { 132 | return [ 133 | [x + 1 / 2 * waveLength / Math.PI / 2, amplitude / 2], 134 | [x + 1 / 2 * waveLength / Math.PI, amplitude], 135 | [x + waveLength / 4, amplitude] 136 | ]; 137 | } 138 | else if (stage === 1) { 139 | return [ 140 | [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2), 141 | amplitude], 142 | [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1), 143 | amplitude / 2], 144 | [x + waveLength / 4, 0] 145 | ] 146 | } 147 | else if (stage === 2) { 148 | return [ 149 | [x + 1 / 2 * waveLength / Math.PI / 2, -amplitude / 2], 150 | [x + 1 / 2 * waveLength / Math.PI, -amplitude], 151 | [x + waveLength / 4, -amplitude] 152 | ] 153 | } 154 | else { 155 | return [ 156 | [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2), 157 | -amplitude], 158 | [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1), 159 | -amplitude / 2], 160 | [x + waveLength / 4, 0] 161 | ] 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/liquidFillView.js: -------------------------------------------------------------------------------- 1 | import * as echarts from 'echarts/lib/echarts'; 2 | import * as numberUtil from 'echarts/lib/util/number'; 3 | import LiquidShape from './liquidFillShape'; 4 | 5 | var parsePercent = numberUtil.parsePercent; 6 | 7 | function isPathSymbol(symbol) { 8 | return symbol && symbol.indexOf('path://') === 0 9 | } 10 | 11 | echarts.extendChartView({ 12 | 13 | type: 'liquidFill', 14 | 15 | render: function (seriesModel, ecModel, api) { 16 | var self = this; 17 | var group = this.group; 18 | group.removeAll(); 19 | 20 | var data = seriesModel.getData(); 21 | 22 | var itemModel = data.getItemModel(0); 23 | 24 | var center = itemModel.get('center'); 25 | var radius = itemModel.get('radius'); 26 | 27 | var width = api.getWidth(); 28 | var height = api.getHeight(); 29 | var size = Math.min(width, height); 30 | // itemStyle 31 | var outlineDistance = 0; 32 | var outlineBorderWidth = 0; 33 | var showOutline = seriesModel.get('outline.show'); 34 | 35 | if (showOutline) { 36 | outlineDistance = seriesModel.get('outline.borderDistance'); 37 | outlineBorderWidth = parsePercent( 38 | seriesModel.get('outline.itemStyle.borderWidth'), size 39 | ); 40 | } 41 | 42 | var cx = parsePercent(center[0], width); 43 | var cy = parsePercent(center[1], height); 44 | 45 | var outterRadius; 46 | var innerRadius; 47 | var paddingRadius; 48 | 49 | var isFillContainer = false; 50 | 51 | var symbol = seriesModel.get('shape'); 52 | if (symbol === 'container') { 53 | // a shape that fully fills the container 54 | isFillContainer = true; 55 | 56 | outterRadius = [ 57 | width / 2, 58 | height / 2 59 | ]; 60 | innerRadius = [ 61 | outterRadius[0] - outlineBorderWidth / 2, 62 | outterRadius[1] - outlineBorderWidth / 2 63 | ]; 64 | paddingRadius = [ 65 | parsePercent(outlineDistance, width), 66 | parsePercent(outlineDistance, height) 67 | ]; 68 | 69 | radius = [ 70 | Math.max(innerRadius[0] - paddingRadius[0], 0), 71 | Math.max(innerRadius[1] - paddingRadius[1], 0) 72 | ]; 73 | } 74 | else { 75 | outterRadius = parsePercent(radius, size) / 2; 76 | innerRadius = outterRadius - outlineBorderWidth / 2; 77 | paddingRadius = parsePercent(outlineDistance, size); 78 | 79 | radius = Math.max(innerRadius - paddingRadius, 0); 80 | } 81 | 82 | if (showOutline) { 83 | var outline = getOutline(); 84 | outline.style.lineWidth = outlineBorderWidth; 85 | group.add(getOutline()); 86 | } 87 | 88 | var left = isFillContainer ? 0 : cx - radius; 89 | var top = isFillContainer ? 0 : cy - radius; 90 | 91 | var wavePath = null; 92 | 93 | group.add(getBackground()); 94 | 95 | // each data item for a wave 96 | var oldData = this._data; 97 | var waves = []; 98 | data.diff(oldData) 99 | .add(function (idx) { 100 | var wave = getWave(idx, false); 101 | 102 | var waterLevel = wave.shape.waterLevel; 103 | wave.shape.waterLevel = isFillContainer ? height / 2 : radius; 104 | echarts.graphic.initProps(wave, { 105 | shape: { 106 | waterLevel: waterLevel 107 | } 108 | }, seriesModel); 109 | 110 | wave.z2 = 2; 111 | setWaveAnimation(idx, wave, null); 112 | 113 | group.add(wave); 114 | data.setItemGraphicEl(idx, wave); 115 | waves.push(wave); 116 | }) 117 | .update(function (newIdx, oldIdx) { 118 | var waveElement = oldData.getItemGraphicEl(oldIdx); 119 | 120 | // new wave is used to calculate position, but not added 121 | var newWave = getWave(newIdx, false, waveElement); 122 | 123 | // changes with animation 124 | var shape = {}; 125 | var shapeAttrs = ['amplitude', 'cx', 'cy', 'phase', 'radius', 'radiusY', 'waterLevel', 'waveLength']; 126 | for (var i = 0; i < shapeAttrs.length; ++i) { 127 | var attr = shapeAttrs[i]; 128 | if (newWave.shape.hasOwnProperty(attr)) { 129 | shape[attr] = newWave.shape[attr]; 130 | } 131 | } 132 | 133 | var style = {}; 134 | var styleAttrs = ['fill', 'opacity', 'shadowBlur', 'shadowColor']; 135 | for (var i = 0; i < styleAttrs.length; ++i) { 136 | var attr = styleAttrs[i]; 137 | if (newWave.style.hasOwnProperty(attr)) { 138 | style[attr] = newWave.style[attr]; 139 | } 140 | } 141 | 142 | if (isFillContainer) { 143 | shape.radiusY = height / 2; 144 | } 145 | 146 | // changes with animation 147 | echarts.graphic.updateProps(waveElement, { 148 | shape: shape, 149 | x: newWave.x, 150 | y: newWave.y 151 | }, seriesModel); 152 | 153 | if (seriesModel.isUniversalTransitionEnabled && seriesModel.isUniversalTransitionEnabled()) { 154 | echarts.graphic.updateProps(waveElement, { 155 | style: style 156 | }, seriesModel); 157 | } 158 | else { 159 | waveElement.useStyle(style); 160 | } 161 | 162 | // instant changes 163 | var oldWaveClipPath = waveElement.getClipPath(); 164 | var newWaveClipPath = newWave.getClipPath(); 165 | 166 | waveElement.setClipPath(newWave.getClipPath()); 167 | waveElement.shape.inverse = newWave.inverse; 168 | 169 | if (oldWaveClipPath && newWaveClipPath 170 | && self._shape === symbol 171 | // TODO use zrender morphing to apply complex symbol animation. 172 | && !isPathSymbol(symbol) 173 | ) { 174 | // Can be animated. 175 | echarts.graphic.updateProps(newWaveClipPath, { 176 | shape: oldWaveClipPath.shape 177 | }, seriesModel, { isFrom: true }); 178 | } 179 | 180 | setWaveAnimation(newIdx, waveElement, waveElement); 181 | group.add(waveElement); 182 | data.setItemGraphicEl(newIdx, waveElement); 183 | waves.push(waveElement); 184 | }) 185 | .remove(function (idx) { 186 | var wave = oldData.getItemGraphicEl(idx); 187 | group.remove(wave); 188 | }) 189 | .execute(); 190 | 191 | if (itemModel.get('label.show')) { 192 | group.add(getText(waves)); 193 | } 194 | 195 | this._shape = symbol; 196 | this._data = data; 197 | 198 | /** 199 | * Get path for outline, background and clipping 200 | * 201 | * @param {number} r outter radius of shape 202 | * @param {boolean|undefined} isForClipping if the shape is used 203 | * for clipping 204 | */ 205 | function getPath(r, isForClipping) { 206 | if (symbol) { 207 | // customed symbol path 208 | if (isPathSymbol(symbol)) { 209 | var path = echarts.graphic.makePath(symbol.slice(7), {}); 210 | var bouding = path.getBoundingRect(); 211 | var w = bouding.width; 212 | var h = bouding.height; 213 | if (w > h) { 214 | h = r * 2 / w * h; 215 | w = r * 2; 216 | } 217 | else { 218 | w = r * 2 / h * w; 219 | h = r * 2; 220 | } 221 | 222 | var left = isForClipping ? 0 : cx - w / 2; 223 | var top = isForClipping ? 0 : cy - h / 2; 224 | path = echarts.graphic.makePath( 225 | symbol.slice(7), 226 | {}, 227 | new echarts.graphic.BoundingRect(left, top, w, h) 228 | ); 229 | if (isForClipping) { 230 | path.x = -w / 2; 231 | path.y = -h / 2; 232 | } 233 | return path; 234 | } 235 | else if (isFillContainer) { 236 | // fully fill the container 237 | var x = isForClipping ? -r[0] : cx - r[0]; 238 | var y = isForClipping ? -r[1] : cy - r[1]; 239 | return echarts.helper.createSymbol( 240 | 'rect', x, y, r[0] * 2, r[1] * 2 241 | ); 242 | } 243 | else { 244 | var x = isForClipping ? -r : cx - r; 245 | var y = isForClipping ? -r : cy - r; 246 | if (symbol === 'pin') { 247 | y += r; 248 | } 249 | else if (symbol === 'arrow') { 250 | y -= r; 251 | } 252 | return echarts.helper.createSymbol(symbol, x, y, r * 2, r * 2); 253 | } 254 | } 255 | 256 | return new echarts.graphic.Circle({ 257 | shape: { 258 | cx: isForClipping ? 0 : cx, 259 | cy: isForClipping ? 0 : cy, 260 | r: r 261 | } 262 | }); 263 | } 264 | /** 265 | * Create outline 266 | */ 267 | function getOutline() { 268 | var outlinePath = getPath(outterRadius); 269 | outlinePath.style.fill = null; 270 | 271 | outlinePath.setStyle(seriesModel.getModel('outline.itemStyle') 272 | .getItemStyle()); 273 | 274 | return outlinePath; 275 | } 276 | 277 | /** 278 | * Create background 279 | */ 280 | function getBackground() { 281 | // Seperate stroke and fill, so we can use stroke to cover the alias of clipping. 282 | var strokePath = getPath(radius); 283 | strokePath.setStyle(seriesModel.getModel('backgroundStyle') 284 | .getItemStyle()); 285 | strokePath.style.fill = null; 286 | 287 | // Stroke is front of wave 288 | strokePath.z2 = 5; 289 | 290 | var fillPath = getPath(radius); 291 | fillPath.setStyle(seriesModel.getModel('backgroundStyle') 292 | .getItemStyle()); 293 | fillPath.style.stroke = null; 294 | 295 | var group = new echarts.graphic.Group(); 296 | group.add(strokePath); 297 | group.add(fillPath); 298 | 299 | return group; 300 | } 301 | 302 | /** 303 | * wave shape 304 | */ 305 | function getWave(idx, isInverse, oldWave) { 306 | var radiusX = isFillContainer ? radius[0] : radius; 307 | var radiusY = isFillContainer ? height / 2 : radius; 308 | 309 | var itemModel = data.getItemModel(idx); 310 | var itemStyleModel = itemModel.getModel('itemStyle'); 311 | var phase = itemModel.get('phase'); 312 | var amplitude = parsePercent(itemModel.get('amplitude'), 313 | radiusY * 2); 314 | var waveLength = parsePercent(itemModel.get('waveLength'), 315 | radiusX * 2); 316 | 317 | var value = data.get('value', idx); 318 | var waterLevel = radiusY - value * radiusY * 2; 319 | phase = oldWave ? oldWave.shape.phase 320 | : (phase === 'auto' ? idx * Math.PI / 4 : phase); 321 | var normalStyle = itemStyleModel.getItemStyle(); 322 | if (!normalStyle.fill) { 323 | var seriesColor = seriesModel.get('color'); 324 | var id = idx % seriesColor.length; 325 | normalStyle.fill = seriesColor[id]; 326 | } 327 | 328 | var x = radiusX * 2; 329 | var wave = new LiquidShape({ 330 | shape: { 331 | waveLength: waveLength, 332 | radius: radiusX, 333 | radiusY: radiusY, 334 | cx: x, 335 | cy: 0, 336 | waterLevel: waterLevel, 337 | amplitude: amplitude, 338 | phase: phase, 339 | inverse: isInverse 340 | }, 341 | style: normalStyle, 342 | x: cx, 343 | y: cy, 344 | }); 345 | wave.shape._waterLevel = waterLevel; 346 | 347 | var hoverStyle = itemModel.getModel('emphasis.itemStyle') 348 | .getItemStyle(); 349 | hoverStyle.lineWidth = 0; 350 | 351 | wave.ensureState('emphasis').style = hoverStyle; 352 | echarts.helper.enableHoverEmphasis(wave); 353 | 354 | // clip out the part outside the circle 355 | var clip = getPath(radius, true); 356 | // set fill for clipPath, otherwise it will not trigger hover event 357 | clip.setStyle({ 358 | fill: 'white' 359 | }); 360 | wave.setClipPath(clip); 361 | 362 | return wave; 363 | } 364 | 365 | function setWaveAnimation(idx, wave, oldWave) { 366 | var itemModel = data.getItemModel(idx); 367 | 368 | var maxSpeed = itemModel.get('period'); 369 | var direction = itemModel.get('direction'); 370 | 371 | var value = data.get('value', idx); 372 | 373 | var phase = itemModel.get('phase'); 374 | phase = oldWave ? oldWave.shape.phase 375 | : (phase === 'auto' ? idx * Math.PI / 4 : phase); 376 | 377 | var defaultSpeed = function (maxSpeed) { 378 | var cnt = data.count(); 379 | return cnt === 0 ? maxSpeed : maxSpeed * 380 | (0.2 + (cnt - idx) / cnt * 0.8); 381 | }; 382 | var speed = 0; 383 | if (maxSpeed === 'auto') { 384 | speed = defaultSpeed(5000); 385 | } 386 | else { 387 | speed = typeof maxSpeed === 'function' 388 | ? maxSpeed(value, idx) : maxSpeed; 389 | } 390 | 391 | // phase for moving left/right 392 | var phaseOffset = 0; 393 | if (direction === 'right' || direction == null) { 394 | phaseOffset = Math.PI; 395 | } 396 | else if (direction === 'left') { 397 | phaseOffset = -Math.PI; 398 | } 399 | else if (direction === 'none') { 400 | phaseOffset = 0; 401 | } 402 | else { 403 | console.error('Illegal direction value for liquid fill.'); 404 | } 405 | 406 | // wave animation of moving left/right 407 | if (direction !== 'none' && itemModel.get('waveAnimation')) { 408 | wave 409 | .animate('shape', true) 410 | .when(0, { 411 | phase: phase 412 | }) 413 | .when(speed / 2, { 414 | phase: phaseOffset + phase 415 | }) 416 | .when(speed, { 417 | phase: phaseOffset * 2 + phase 418 | }) 419 | .during(function () { 420 | if (wavePath) { 421 | wavePath.dirty(true); 422 | } 423 | }) 424 | .start(); 425 | } 426 | } 427 | 428 | /** 429 | * text on wave 430 | */ 431 | function getText(waves) { 432 | var labelModel = itemModel.getModel('label'); 433 | 434 | function formatLabel() { 435 | var formatted = seriesModel.getFormattedLabel(0, 'normal'); 436 | var defaultVal = (data.get('value', 0) * 100); 437 | var defaultLabel = data.getName(0) || seriesModel.name; 438 | if (!isNaN(defaultVal)) { 439 | defaultLabel = defaultVal.toFixed(0) + '%'; 440 | } 441 | return formatted == null ? defaultLabel : formatted; 442 | } 443 | 444 | var textRectOption = { 445 | z2: 10, 446 | shape: { 447 | x: left, 448 | y: top, 449 | width: (isFillContainer ? radius[0] : radius) * 2, 450 | height: (isFillContainer ? radius[1] : radius) * 2 451 | }, 452 | style: { 453 | fill: 'transparent' 454 | }, 455 | textConfig: { 456 | position: labelModel.get('position') || 'inside' 457 | }, 458 | silent: true 459 | }; 460 | var textOption = { 461 | style: { 462 | text: formatLabel(), 463 | textAlign: labelModel.get('align'), 464 | textVerticalAlign: labelModel.get('baseline') 465 | } 466 | }; 467 | Object.assign(textOption.style, echarts.helper.createTextStyle(labelModel)); 468 | 469 | var outsideTextRect = new echarts.graphic.Rect(textRectOption); 470 | var insideTextRect = new echarts.graphic.Rect(textRectOption); 471 | insideTextRect.disableLabelAnimation = true; 472 | outsideTextRect.disableLabelAnimation = true; 473 | 474 | var outsideText = new echarts.graphic.Text(textOption); 475 | var insideText = new echarts.graphic.Text(textOption); 476 | outsideTextRect.setTextContent(outsideText); 477 | 478 | insideTextRect.setTextContent(insideText); 479 | var insColor = labelModel.get('insideColor'); 480 | insideText.style.fill = insColor; 481 | 482 | var group = new echarts.graphic.Group(); 483 | group.add(outsideTextRect); 484 | group.add(insideTextRect); 485 | 486 | // clip out waves for insideText 487 | var boundingCircle = getPath(radius, true); 488 | 489 | wavePath = new echarts.graphic.CompoundPath({ 490 | shape: { 491 | paths: waves 492 | }, 493 | x: cx, 494 | y: cy 495 | }); 496 | 497 | wavePath.setClipPath(boundingCircle); 498 | insideTextRect.setClipPath(wavePath); 499 | 500 | return group; 501 | } 502 | }, 503 | 504 | dispose: function () { 505 | // dispose nothing here 506 | } 507 | }); 508 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = (env, options) => { 2 | return { 3 | entry: { 4 | 'echarts-liquidfill': __dirname + '/index.js' 5 | }, 6 | output: { 7 | libraryTarget: 'umd', 8 | library: ['echarts-liquidfill'], 9 | path: __dirname + '/dist', 10 | filename: options.mode === 'production' ? '[name].min.js' : '[name].js' 11 | }, 12 | optimization: { 13 | concatenateModules: true 14 | }, 15 | externals: { 16 | 'echarts/lib/echarts': 'echarts' 17 | }, 18 | devtool: 'source-map', 19 | resolve: { 20 | alias: { 21 | 'echarts/lib/echarts': 'echarts' 22 | } 23 | } 24 | } 25 | }; 26 | --------------------------------------------------------------------------------
This is an example showing liquidFill chart that fills the container.