├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── config └── chart.php └── src ├── Commands └── InstallCommand.php ├── LaravelChartServiceProvider.php ├── Support ├── Chart.php └── Facades │ └── ChartFacade.php └── views └── js └── chart.js ├── LICENSE.md ├── README.md ├── auto ├── auto.esm.d.ts ├── auto.esm.js ├── auto.js └── package.json ├── dist ├── chart.esm.js ├── chart.js ├── chart.min.js ├── chunks │ └── helpers.segment.js └── helpers.esm.js ├── helpers ├── helpers.esm.d.ts ├── helpers.esm.js ├── helpers.js └── package.json ├── package.json └── types ├── adapters.d.ts ├── animation.d.ts ├── basic.d.ts ├── color.d.ts ├── element.d.ts ├── geometric.d.ts ├── helpers ├── helpers.canvas.d.ts ├── helpers.collection.d.ts ├── helpers.color.d.ts ├── helpers.core.d.ts ├── helpers.curve.d.ts ├── helpers.dom.d.ts ├── helpers.easing.d.ts ├── helpers.extras.d.ts ├── helpers.interpolation.d.ts ├── helpers.intl.d.ts ├── helpers.math.d.ts ├── helpers.options.d.ts ├── helpers.rtl.d.ts ├── helpers.segment.d.ts └── index.d.ts ├── index.esm.d.ts ├── layout.d.ts └── utils.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /.idea/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Amir Hossein Kamandlou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Chart 2 | 3 | Laravel chart is a customizable and flexible package for creating chart in Laravel. 4 | 5 | # Installation 6 | 7 | 1. Install the package and its dependencies using Composer: 8 | 9 | `composer require kamandlou/laravel-chart` 10 | 2. Publish package files using Artisan command: 11 | 12 | `php artisan chart:install` 13 | 14 | # Usage Guide 15 | 16 | ### Add scripts to your page: 17 | - `` 18 | - ``` 19 | 22 | ``` 23 | ### Create a canvas in your page: 24 | - `` 25 | ### You have two way to use 26 | ``` 27 | return Chart::chart('myChart', [ 28 | 'type' => 'bar', 29 | 'data' => [ 30 | 'labels' => ['Red', 'Blue', 'Yellow'], 31 | 'datasets' => [ 32 | [ 33 | 'label' => '# of Votes', 34 | 'data' => [12, 19, 3], 35 | 'backgroundColor' => [ 36 | 'rgba(255, 99, 132, 0.2)', 37 | 'rgba(54, 162, 235, 0.2)', 38 | 'rgba(255, 206, 86, 0.2)', 39 | ], 40 | 'borderColor' => [ 41 | 'rgba(255, 99, 132, 1)', 42 | 'rgba(54, 162, 235, 1)', 43 | 'rgba(255, 206, 86, 1)', 44 | ], 45 | 'borderWidth' => 1 46 | ] 47 | ] 48 | ], 49 | 'options' => [ 50 | 'scales' => [ 51 | 'y' => [ 52 | 'beginAtZero' => true 53 | ] 54 | ] 55 | ] 56 | ])->render('index'); 57 | ``` 58 | ### Or 59 | ``` 60 | return Chart::id('myChart') 61 | ->type('bar') 62 | ->labels(['Red', 'Blue', 'Yellow']) 63 | ->datasets([ 64 | [ 65 | 'label' => '# of Votes', 66 | 'data' => [12, 19, 3], 67 | 'backgroundColor' => [ 68 | 'rgba(255, 99, 132, 0.2)', 69 | 'rgba(54, 162, 235, 0.2)', 70 | 'rgba(255, 206, 86, 0.2)', 71 | ], 72 | 'borderColor' => [ 73 | 'rgba(255, 99, 132, 1)', 74 | 'rgba(54, 162, 235, 1)', 75 | 'rgba(255, 206, 86, 1)', 76 | ], 77 | 'borderWidth' => 1 78 | ] 79 | ]) 80 | ->options([ 81 | 'scales' => [ 82 | 'y' => [ 83 | 'beginAtZero' => true 84 | ] 85 | ] 86 | ]) 87 | ->render('index'); 88 | ``` 89 | ### for see more option go to chart.js documention 90 | 91 | [Chart.js Document](https://www.chartjs.org/docs/latest/getting-started/) 92 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kamandlou/laravel-chart", 3 | "description": "A package for create charts in laravel", 4 | "keywords": [ 5 | "chart", 6 | "laravel" 7 | ], 8 | "license": "MIT", 9 | "support": { 10 | "issues": "https://github.com/kamandlou/laravel-chart/issues", 11 | "source": "https://github.com/kamandlou/laravel-chart" 12 | }, 13 | "authors": [ 14 | { 15 | "name": "Kamandlou", 16 | "email": "ahkamandlou@gmail.com" 17 | } 18 | ], 19 | "autoload": { 20 | "psr-4": { 21 | "Kamandlou\\LaravelChart\\": "src/" 22 | } 23 | }, 24 | "require": { 25 | "php": "^7.4||^8.0", 26 | "illuminate/support": "^8.0|^9.0" 27 | }, 28 | "extra": { 29 | "laravel": { 30 | "providers": [ 31 | "Kamandlou\\LaravelChart\\LaravelChartServiceProvider" 32 | ], 33 | "aliases": { 34 | "Chart": "Kamandlou\\LaravelChart\\Support\\Facades\\ChartFacade" 35 | } 36 | } 37 | }, 38 | "config": { 39 | "sort-packages": true 40 | }, 41 | "minimum-stability": "dev", 42 | "prefer-stable": true 43 | } 44 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "d2d977f55c5d065ebc8d3682779a6c54", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "2.0.4", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", 20 | "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.2 || ^8.0" 25 | }, 26 | "require-dev": { 27 | "doctrine/coding-standard": "^8.2", 28 | "phpstan/phpstan": "^0.12", 29 | "phpstan/phpstan-phpunit": "^0.12", 30 | "phpstan/phpstan-strict-rules": "^0.12", 31 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", 32 | "vimeo/psalm": "^4.10" 33 | }, 34 | "type": "library", 35 | "autoload": { 36 | "psr-4": { 37 | "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Guilherme Blanco", 47 | "email": "guilhermeblanco@gmail.com" 48 | }, 49 | { 50 | "name": "Roman Borschel", 51 | "email": "roman@code-factory.org" 52 | }, 53 | { 54 | "name": "Benjamin Eberlei", 55 | "email": "kontakt@beberlei.de" 56 | }, 57 | { 58 | "name": "Jonathan Wage", 59 | "email": "jonwage@gmail.com" 60 | }, 61 | { 62 | "name": "Johannes Schmitt", 63 | "email": "schmittjoh@gmail.com" 64 | } 65 | ], 66 | "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", 67 | "homepage": "https://www.doctrine-project.org/projects/inflector.html", 68 | "keywords": [ 69 | "inflection", 70 | "inflector", 71 | "lowercase", 72 | "manipulation", 73 | "php", 74 | "plural", 75 | "singular", 76 | "strings", 77 | "uppercase", 78 | "words" 79 | ], 80 | "support": { 81 | "issues": "https://github.com/doctrine/inflector/issues", 82 | "source": "https://github.com/doctrine/inflector/tree/2.0.4" 83 | }, 84 | "funding": [ 85 | { 86 | "url": "https://www.doctrine-project.org/sponsorship.html", 87 | "type": "custom" 88 | }, 89 | { 90 | "url": "https://www.patreon.com/phpdoctrine", 91 | "type": "patreon" 92 | }, 93 | { 94 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", 95 | "type": "tidelift" 96 | } 97 | ], 98 | "time": "2021-10-22T20:16:43+00:00" 99 | }, 100 | { 101 | "name": "illuminate/collections", 102 | "version": "v9.1.0", 103 | "source": { 104 | "type": "git", 105 | "url": "https://github.com/illuminate/collections.git", 106 | "reference": "707ab36191228b1a4cf322985796ff7aab5578c1" 107 | }, 108 | "dist": { 109 | "type": "zip", 110 | "url": "https://api.github.com/repos/illuminate/collections/zipball/707ab36191228b1a4cf322985796ff7aab5578c1", 111 | "reference": "707ab36191228b1a4cf322985796ff7aab5578c1", 112 | "shasum": "" 113 | }, 114 | "require": { 115 | "illuminate/conditionable": "^9.0", 116 | "illuminate/contracts": "^9.0", 117 | "illuminate/macroable": "^9.0", 118 | "php": "^8.0.2" 119 | }, 120 | "suggest": { 121 | "symfony/var-dumper": "Required to use the dump method (^6.0)." 122 | }, 123 | "type": "library", 124 | "extra": { 125 | "branch-alias": { 126 | "dev-master": "9.x-dev" 127 | } 128 | }, 129 | "autoload": { 130 | "files": [ 131 | "helpers.php" 132 | ], 133 | "psr-4": { 134 | "Illuminate\\Support\\": "" 135 | } 136 | }, 137 | "notification-url": "https://packagist.org/downloads/", 138 | "license": [ 139 | "MIT" 140 | ], 141 | "authors": [ 142 | { 143 | "name": "Taylor Otwell", 144 | "email": "taylor@laravel.com" 145 | } 146 | ], 147 | "description": "The Illuminate Collections package.", 148 | "homepage": "https://laravel.com", 149 | "support": { 150 | "issues": "https://github.com/laravel/framework/issues", 151 | "source": "https://github.com/laravel/framework" 152 | }, 153 | "time": "2022-02-09T21:49:11+00:00" 154 | }, 155 | { 156 | "name": "illuminate/conditionable", 157 | "version": "v9.1.0", 158 | "source": { 159 | "type": "git", 160 | "url": "https://github.com/illuminate/conditionable.git", 161 | "reference": "4f7e3d67ceda9a6188757501748982ea9ed5f69a" 162 | }, 163 | "dist": { 164 | "type": "zip", 165 | "url": "https://api.github.com/repos/illuminate/conditionable/zipball/4f7e3d67ceda9a6188757501748982ea9ed5f69a", 166 | "reference": "4f7e3d67ceda9a6188757501748982ea9ed5f69a", 167 | "shasum": "" 168 | }, 169 | "require": { 170 | "php": "^8.0.2" 171 | }, 172 | "type": "library", 173 | "extra": { 174 | "branch-alias": { 175 | "dev-master": "9.x-dev" 176 | } 177 | }, 178 | "autoload": { 179 | "psr-4": { 180 | "Illuminate\\Support\\": "" 181 | } 182 | }, 183 | "notification-url": "https://packagist.org/downloads/", 184 | "license": [ 185 | "MIT" 186 | ], 187 | "authors": [ 188 | { 189 | "name": "Taylor Otwell", 190 | "email": "taylor@laravel.com" 191 | } 192 | ], 193 | "description": "The Illuminate Conditionable package.", 194 | "homepage": "https://laravel.com", 195 | "support": { 196 | "issues": "https://github.com/laravel/framework/issues", 197 | "source": "https://github.com/laravel/framework" 198 | }, 199 | "time": "2022-02-09T14:26:32+00:00" 200 | }, 201 | { 202 | "name": "illuminate/contracts", 203 | "version": "v9.1.0", 204 | "source": { 205 | "type": "git", 206 | "url": "https://github.com/illuminate/contracts.git", 207 | "reference": "c2e3cf2eda10fd3332af0b4a43481cc0af98c437" 208 | }, 209 | "dist": { 210 | "type": "zip", 211 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/c2e3cf2eda10fd3332af0b4a43481cc0af98c437", 212 | "reference": "c2e3cf2eda10fd3332af0b4a43481cc0af98c437", 213 | "shasum": "" 214 | }, 215 | "require": { 216 | "php": "^8.0.2", 217 | "psr/container": "^1.1.1|^2.0.1", 218 | "psr/simple-cache": "^1.0|^2.0|^3.0" 219 | }, 220 | "type": "library", 221 | "extra": { 222 | "branch-alias": { 223 | "dev-master": "9.x-dev" 224 | } 225 | }, 226 | "autoload": { 227 | "psr-4": { 228 | "Illuminate\\Contracts\\": "" 229 | } 230 | }, 231 | "notification-url": "https://packagist.org/downloads/", 232 | "license": [ 233 | "MIT" 234 | ], 235 | "authors": [ 236 | { 237 | "name": "Taylor Otwell", 238 | "email": "taylor@laravel.com" 239 | } 240 | ], 241 | "description": "The Illuminate Contracts package.", 242 | "homepage": "https://laravel.com", 243 | "support": { 244 | "issues": "https://github.com/laravel/framework/issues", 245 | "source": "https://github.com/laravel/framework" 246 | }, 247 | "time": "2022-02-11T14:24:50+00:00" 248 | }, 249 | { 250 | "name": "illuminate/macroable", 251 | "version": "v9.1.0", 252 | "source": { 253 | "type": "git", 254 | "url": "https://github.com/illuminate/macroable.git", 255 | "reference": "25a2c6dac2b7541ecbadef952702e84ae15f5354" 256 | }, 257 | "dist": { 258 | "type": "zip", 259 | "url": "https://api.github.com/repos/illuminate/macroable/zipball/25a2c6dac2b7541ecbadef952702e84ae15f5354", 260 | "reference": "25a2c6dac2b7541ecbadef952702e84ae15f5354", 261 | "shasum": "" 262 | }, 263 | "require": { 264 | "php": "^8.0.2" 265 | }, 266 | "type": "library", 267 | "extra": { 268 | "branch-alias": { 269 | "dev-master": "9.x-dev" 270 | } 271 | }, 272 | "autoload": { 273 | "psr-4": { 274 | "Illuminate\\Support\\": "" 275 | } 276 | }, 277 | "notification-url": "https://packagist.org/downloads/", 278 | "license": [ 279 | "MIT" 280 | ], 281 | "authors": [ 282 | { 283 | "name": "Taylor Otwell", 284 | "email": "taylor@laravel.com" 285 | } 286 | ], 287 | "description": "The Illuminate Macroable package.", 288 | "homepage": "https://laravel.com", 289 | "support": { 290 | "issues": "https://github.com/laravel/framework/issues", 291 | "source": "https://github.com/laravel/framework" 292 | }, 293 | "time": "2022-02-01T14:44:21+00:00" 294 | }, 295 | { 296 | "name": "illuminate/support", 297 | "version": "v9.1.0", 298 | "source": { 299 | "type": "git", 300 | "url": "https://github.com/illuminate/support.git", 301 | "reference": "cb117bc9a3358d60ade85e5a13d6b82f40ee6049" 302 | }, 303 | "dist": { 304 | "type": "zip", 305 | "url": "https://api.github.com/repos/illuminate/support/zipball/cb117bc9a3358d60ade85e5a13d6b82f40ee6049", 306 | "reference": "cb117bc9a3358d60ade85e5a13d6b82f40ee6049", 307 | "shasum": "" 308 | }, 309 | "require": { 310 | "doctrine/inflector": "^2.0", 311 | "ext-json": "*", 312 | "ext-mbstring": "*", 313 | "illuminate/collections": "^9.0", 314 | "illuminate/conditionable": "^9.0", 315 | "illuminate/contracts": "^9.0", 316 | "illuminate/macroable": "^9.0", 317 | "nesbot/carbon": "^2.53.1", 318 | "php": "^8.0.2", 319 | "voku/portable-ascii": "^2.0" 320 | }, 321 | "conflict": { 322 | "tightenco/collect": "<5.5.33" 323 | }, 324 | "suggest": { 325 | "illuminate/filesystem": "Required to use the composer class (^9.0).", 326 | "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", 327 | "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", 328 | "symfony/process": "Required to use the composer class (^6.0).", 329 | "symfony/var-dumper": "Required to use the dd function (^6.0).", 330 | "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." 331 | }, 332 | "type": "library", 333 | "extra": { 334 | "branch-alias": { 335 | "dev-master": "9.x-dev" 336 | } 337 | }, 338 | "autoload": { 339 | "files": [ 340 | "helpers.php" 341 | ], 342 | "psr-4": { 343 | "Illuminate\\Support\\": "" 344 | } 345 | }, 346 | "notification-url": "https://packagist.org/downloads/", 347 | "license": [ 348 | "MIT" 349 | ], 350 | "authors": [ 351 | { 352 | "name": "Taylor Otwell", 353 | "email": "taylor@laravel.com" 354 | } 355 | ], 356 | "description": "The Illuminate Support package.", 357 | "homepage": "https://laravel.com", 358 | "support": { 359 | "issues": "https://github.com/laravel/framework/issues", 360 | "source": "https://github.com/laravel/framework" 361 | }, 362 | "time": "2022-02-14T17:31:22+00:00" 363 | }, 364 | { 365 | "name": "nesbot/carbon", 366 | "version": "2.57.0", 367 | "source": { 368 | "type": "git", 369 | "url": "https://github.com/briannesbitt/Carbon.git", 370 | "reference": "4a54375c21eea4811dbd1149fe6b246517554e78" 371 | }, 372 | "dist": { 373 | "type": "zip", 374 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4a54375c21eea4811dbd1149fe6b246517554e78", 375 | "reference": "4a54375c21eea4811dbd1149fe6b246517554e78", 376 | "shasum": "" 377 | }, 378 | "require": { 379 | "ext-json": "*", 380 | "php": "^7.1.8 || ^8.0", 381 | "symfony/polyfill-mbstring": "^1.0", 382 | "symfony/polyfill-php80": "^1.16", 383 | "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" 384 | }, 385 | "require-dev": { 386 | "doctrine/dbal": "^2.0 || ^3.0", 387 | "doctrine/orm": "^2.7", 388 | "friendsofphp/php-cs-fixer": "^3.0", 389 | "kylekatarnls/multi-tester": "^2.0", 390 | "phpmd/phpmd": "^2.9", 391 | "phpstan/extension-installer": "^1.0", 392 | "phpstan/phpstan": "^0.12.54 || ^1.0", 393 | "phpunit/phpunit": "^7.5.20 || ^8.5.14", 394 | "squizlabs/php_codesniffer": "^3.4" 395 | }, 396 | "bin": [ 397 | "bin/carbon" 398 | ], 399 | "type": "library", 400 | "extra": { 401 | "branch-alias": { 402 | "dev-3.x": "3.x-dev", 403 | "dev-master": "2.x-dev" 404 | }, 405 | "laravel": { 406 | "providers": [ 407 | "Carbon\\Laravel\\ServiceProvider" 408 | ] 409 | }, 410 | "phpstan": { 411 | "includes": [ 412 | "extension.neon" 413 | ] 414 | } 415 | }, 416 | "autoload": { 417 | "psr-4": { 418 | "Carbon\\": "src/Carbon/" 419 | } 420 | }, 421 | "notification-url": "https://packagist.org/downloads/", 422 | "license": [ 423 | "MIT" 424 | ], 425 | "authors": [ 426 | { 427 | "name": "Brian Nesbitt", 428 | "email": "brian@nesbot.com", 429 | "homepage": "https://markido.com" 430 | }, 431 | { 432 | "name": "kylekatarnls", 433 | "homepage": "https://github.com/kylekatarnls" 434 | } 435 | ], 436 | "description": "An API extension for DateTime that supports 281 different languages.", 437 | "homepage": "https://carbon.nesbot.com", 438 | "keywords": [ 439 | "date", 440 | "datetime", 441 | "time" 442 | ], 443 | "support": { 444 | "docs": "https://carbon.nesbot.com/docs", 445 | "issues": "https://github.com/briannesbitt/Carbon/issues", 446 | "source": "https://github.com/briannesbitt/Carbon" 447 | }, 448 | "funding": [ 449 | { 450 | "url": "https://opencollective.com/Carbon", 451 | "type": "open_collective" 452 | }, 453 | { 454 | "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", 455 | "type": "tidelift" 456 | } 457 | ], 458 | "time": "2022-02-13T18:13:33+00:00" 459 | }, 460 | { 461 | "name": "psr/container", 462 | "version": "2.0.2", 463 | "source": { 464 | "type": "git", 465 | "url": "https://github.com/php-fig/container.git", 466 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 467 | }, 468 | "dist": { 469 | "type": "zip", 470 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 471 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 472 | "shasum": "" 473 | }, 474 | "require": { 475 | "php": ">=7.4.0" 476 | }, 477 | "type": "library", 478 | "extra": { 479 | "branch-alias": { 480 | "dev-master": "2.0.x-dev" 481 | } 482 | }, 483 | "autoload": { 484 | "psr-4": { 485 | "Psr\\Container\\": "src/" 486 | } 487 | }, 488 | "notification-url": "https://packagist.org/downloads/", 489 | "license": [ 490 | "MIT" 491 | ], 492 | "authors": [ 493 | { 494 | "name": "PHP-FIG", 495 | "homepage": "https://www.php-fig.org/" 496 | } 497 | ], 498 | "description": "Common Container Interface (PHP FIG PSR-11)", 499 | "homepage": "https://github.com/php-fig/container", 500 | "keywords": [ 501 | "PSR-11", 502 | "container", 503 | "container-interface", 504 | "container-interop", 505 | "psr" 506 | ], 507 | "support": { 508 | "issues": "https://github.com/php-fig/container/issues", 509 | "source": "https://github.com/php-fig/container/tree/2.0.2" 510 | }, 511 | "time": "2021-11-05T16:47:00+00:00" 512 | }, 513 | { 514 | "name": "psr/simple-cache", 515 | "version": "3.0.0", 516 | "source": { 517 | "type": "git", 518 | "url": "https://github.com/php-fig/simple-cache.git", 519 | "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" 520 | }, 521 | "dist": { 522 | "type": "zip", 523 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", 524 | "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", 525 | "shasum": "" 526 | }, 527 | "require": { 528 | "php": ">=8.0.0" 529 | }, 530 | "type": "library", 531 | "extra": { 532 | "branch-alias": { 533 | "dev-master": "3.0.x-dev" 534 | } 535 | }, 536 | "autoload": { 537 | "psr-4": { 538 | "Psr\\SimpleCache\\": "src/" 539 | } 540 | }, 541 | "notification-url": "https://packagist.org/downloads/", 542 | "license": [ 543 | "MIT" 544 | ], 545 | "authors": [ 546 | { 547 | "name": "PHP-FIG", 548 | "homepage": "https://www.php-fig.org/" 549 | } 550 | ], 551 | "description": "Common interfaces for simple caching", 552 | "keywords": [ 553 | "cache", 554 | "caching", 555 | "psr", 556 | "psr-16", 557 | "simple-cache" 558 | ], 559 | "support": { 560 | "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" 561 | }, 562 | "time": "2021-10-29T13:26:27+00:00" 563 | }, 564 | { 565 | "name": "symfony/polyfill-mbstring", 566 | "version": "v1.24.0", 567 | "source": { 568 | "type": "git", 569 | "url": "https://github.com/symfony/polyfill-mbstring.git", 570 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" 571 | }, 572 | "dist": { 573 | "type": "zip", 574 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", 575 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", 576 | "shasum": "" 577 | }, 578 | "require": { 579 | "php": ">=7.1" 580 | }, 581 | "provide": { 582 | "ext-mbstring": "*" 583 | }, 584 | "suggest": { 585 | "ext-mbstring": "For best performance" 586 | }, 587 | "type": "library", 588 | "extra": { 589 | "branch-alias": { 590 | "dev-main": "1.23-dev" 591 | }, 592 | "thanks": { 593 | "name": "symfony/polyfill", 594 | "url": "https://github.com/symfony/polyfill" 595 | } 596 | }, 597 | "autoload": { 598 | "files": [ 599 | "bootstrap.php" 600 | ], 601 | "psr-4": { 602 | "Symfony\\Polyfill\\Mbstring\\": "" 603 | } 604 | }, 605 | "notification-url": "https://packagist.org/downloads/", 606 | "license": [ 607 | "MIT" 608 | ], 609 | "authors": [ 610 | { 611 | "name": "Nicolas Grekas", 612 | "email": "p@tchwork.com" 613 | }, 614 | { 615 | "name": "Symfony Community", 616 | "homepage": "https://symfony.com/contributors" 617 | } 618 | ], 619 | "description": "Symfony polyfill for the Mbstring extension", 620 | "homepage": "https://symfony.com", 621 | "keywords": [ 622 | "compatibility", 623 | "mbstring", 624 | "polyfill", 625 | "portable", 626 | "shim" 627 | ], 628 | "support": { 629 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" 630 | }, 631 | "funding": [ 632 | { 633 | "url": "https://symfony.com/sponsor", 634 | "type": "custom" 635 | }, 636 | { 637 | "url": "https://github.com/fabpot", 638 | "type": "github" 639 | }, 640 | { 641 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 642 | "type": "tidelift" 643 | } 644 | ], 645 | "time": "2021-11-30T18:21:41+00:00" 646 | }, 647 | { 648 | "name": "symfony/polyfill-php80", 649 | "version": "v1.24.0", 650 | "source": { 651 | "type": "git", 652 | "url": "https://github.com/symfony/polyfill-php80.git", 653 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" 654 | }, 655 | "dist": { 656 | "type": "zip", 657 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", 658 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", 659 | "shasum": "" 660 | }, 661 | "require": { 662 | "php": ">=7.1" 663 | }, 664 | "type": "library", 665 | "extra": { 666 | "branch-alias": { 667 | "dev-main": "1.23-dev" 668 | }, 669 | "thanks": { 670 | "name": "symfony/polyfill", 671 | "url": "https://github.com/symfony/polyfill" 672 | } 673 | }, 674 | "autoload": { 675 | "files": [ 676 | "bootstrap.php" 677 | ], 678 | "psr-4": { 679 | "Symfony\\Polyfill\\Php80\\": "" 680 | }, 681 | "classmap": [ 682 | "Resources/stubs" 683 | ] 684 | }, 685 | "notification-url": "https://packagist.org/downloads/", 686 | "license": [ 687 | "MIT" 688 | ], 689 | "authors": [ 690 | { 691 | "name": "Ion Bazan", 692 | "email": "ion.bazan@gmail.com" 693 | }, 694 | { 695 | "name": "Nicolas Grekas", 696 | "email": "p@tchwork.com" 697 | }, 698 | { 699 | "name": "Symfony Community", 700 | "homepage": "https://symfony.com/contributors" 701 | } 702 | ], 703 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 704 | "homepage": "https://symfony.com", 705 | "keywords": [ 706 | "compatibility", 707 | "polyfill", 708 | "portable", 709 | "shim" 710 | ], 711 | "support": { 712 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" 713 | }, 714 | "funding": [ 715 | { 716 | "url": "https://symfony.com/sponsor", 717 | "type": "custom" 718 | }, 719 | { 720 | "url": "https://github.com/fabpot", 721 | "type": "github" 722 | }, 723 | { 724 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 725 | "type": "tidelift" 726 | } 727 | ], 728 | "time": "2021-09-13T13:58:33+00:00" 729 | }, 730 | { 731 | "name": "symfony/translation", 732 | "version": "v6.0.3", 733 | "source": { 734 | "type": "git", 735 | "url": "https://github.com/symfony/translation.git", 736 | "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d" 737 | }, 738 | "dist": { 739 | "type": "zip", 740 | "url": "https://api.github.com/repos/symfony/translation/zipball/71bb15335798f8c4da110911bcf2d2fead7a430d", 741 | "reference": "71bb15335798f8c4da110911bcf2d2fead7a430d", 742 | "shasum": "" 743 | }, 744 | "require": { 745 | "php": ">=8.0.2", 746 | "symfony/polyfill-mbstring": "~1.0", 747 | "symfony/translation-contracts": "^2.3|^3.0" 748 | }, 749 | "conflict": { 750 | "symfony/config": "<5.4", 751 | "symfony/console": "<5.4", 752 | "symfony/dependency-injection": "<5.4", 753 | "symfony/http-kernel": "<5.4", 754 | "symfony/twig-bundle": "<5.4", 755 | "symfony/yaml": "<5.4" 756 | }, 757 | "provide": { 758 | "symfony/translation-implementation": "2.3|3.0" 759 | }, 760 | "require-dev": { 761 | "psr/log": "^1|^2|^3", 762 | "symfony/config": "^5.4|^6.0", 763 | "symfony/console": "^5.4|^6.0", 764 | "symfony/dependency-injection": "^5.4|^6.0", 765 | "symfony/finder": "^5.4|^6.0", 766 | "symfony/http-client-contracts": "^1.1|^2.0|^3.0", 767 | "symfony/http-kernel": "^5.4|^6.0", 768 | "symfony/intl": "^5.4|^6.0", 769 | "symfony/polyfill-intl-icu": "^1.21", 770 | "symfony/service-contracts": "^1.1.2|^2|^3", 771 | "symfony/yaml": "^5.4|^6.0" 772 | }, 773 | "suggest": { 774 | "psr/log-implementation": "To use logging capability in translator", 775 | "symfony/config": "", 776 | "symfony/yaml": "" 777 | }, 778 | "type": "library", 779 | "autoload": { 780 | "files": [ 781 | "Resources/functions.php" 782 | ], 783 | "psr-4": { 784 | "Symfony\\Component\\Translation\\": "" 785 | }, 786 | "exclude-from-classmap": [ 787 | "/Tests/" 788 | ] 789 | }, 790 | "notification-url": "https://packagist.org/downloads/", 791 | "license": [ 792 | "MIT" 793 | ], 794 | "authors": [ 795 | { 796 | "name": "Fabien Potencier", 797 | "email": "fabien@symfony.com" 798 | }, 799 | { 800 | "name": "Symfony Community", 801 | "homepage": "https://symfony.com/contributors" 802 | } 803 | ], 804 | "description": "Provides tools to internationalize your application", 805 | "homepage": "https://symfony.com", 806 | "support": { 807 | "source": "https://github.com/symfony/translation/tree/v6.0.3" 808 | }, 809 | "funding": [ 810 | { 811 | "url": "https://symfony.com/sponsor", 812 | "type": "custom" 813 | }, 814 | { 815 | "url": "https://github.com/fabpot", 816 | "type": "github" 817 | }, 818 | { 819 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 820 | "type": "tidelift" 821 | } 822 | ], 823 | "time": "2022-01-07T00:29:03+00:00" 824 | }, 825 | { 826 | "name": "symfony/translation-contracts", 827 | "version": "v3.0.0", 828 | "source": { 829 | "type": "git", 830 | "url": "https://github.com/symfony/translation-contracts.git", 831 | "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77" 832 | }, 833 | "dist": { 834 | "type": "zip", 835 | "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", 836 | "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", 837 | "shasum": "" 838 | }, 839 | "require": { 840 | "php": ">=8.0.2" 841 | }, 842 | "suggest": { 843 | "symfony/translation-implementation": "" 844 | }, 845 | "type": "library", 846 | "extra": { 847 | "branch-alias": { 848 | "dev-main": "3.0-dev" 849 | }, 850 | "thanks": { 851 | "name": "symfony/contracts", 852 | "url": "https://github.com/symfony/contracts" 853 | } 854 | }, 855 | "autoload": { 856 | "psr-4": { 857 | "Symfony\\Contracts\\Translation\\": "" 858 | } 859 | }, 860 | "notification-url": "https://packagist.org/downloads/", 861 | "license": [ 862 | "MIT" 863 | ], 864 | "authors": [ 865 | { 866 | "name": "Nicolas Grekas", 867 | "email": "p@tchwork.com" 868 | }, 869 | { 870 | "name": "Symfony Community", 871 | "homepage": "https://symfony.com/contributors" 872 | } 873 | ], 874 | "description": "Generic abstractions related to translation", 875 | "homepage": "https://symfony.com", 876 | "keywords": [ 877 | "abstractions", 878 | "contracts", 879 | "decoupling", 880 | "interfaces", 881 | "interoperability", 882 | "standards" 883 | ], 884 | "support": { 885 | "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0" 886 | }, 887 | "funding": [ 888 | { 889 | "url": "https://symfony.com/sponsor", 890 | "type": "custom" 891 | }, 892 | { 893 | "url": "https://github.com/fabpot", 894 | "type": "github" 895 | }, 896 | { 897 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 898 | "type": "tidelift" 899 | } 900 | ], 901 | "time": "2021-09-07T12:43:40+00:00" 902 | }, 903 | { 904 | "name": "voku/portable-ascii", 905 | "version": "2.0.0", 906 | "source": { 907 | "type": "git", 908 | "url": "https://github.com/voku/portable-ascii.git", 909 | "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89" 910 | }, 911 | "dist": { 912 | "type": "zip", 913 | "url": "https://api.github.com/repos/voku/portable-ascii/zipball/9bd89e83cecdf8c37b64909454249eaed98b2c89", 914 | "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89", 915 | "shasum": "" 916 | }, 917 | "require": { 918 | "php": ">=7.0.0" 919 | }, 920 | "require-dev": { 921 | "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" 922 | }, 923 | "suggest": { 924 | "ext-intl": "Use Intl for transliterator_transliterate() support" 925 | }, 926 | "type": "library", 927 | "autoload": { 928 | "psr-4": { 929 | "voku\\": "src/voku/" 930 | } 931 | }, 932 | "notification-url": "https://packagist.org/downloads/", 933 | "license": [ 934 | "MIT" 935 | ], 936 | "authors": [ 937 | { 938 | "name": "Lars Moelleken", 939 | "homepage": "http://www.moelleken.org/" 940 | } 941 | ], 942 | "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", 943 | "homepage": "https://github.com/voku/portable-ascii", 944 | "keywords": [ 945 | "ascii", 946 | "clean", 947 | "php" 948 | ], 949 | "support": { 950 | "issues": "https://github.com/voku/portable-ascii/issues", 951 | "source": "https://github.com/voku/portable-ascii/tree/2.0.0" 952 | }, 953 | "funding": [ 954 | { 955 | "url": "https://www.paypal.me/moelleken", 956 | "type": "custom" 957 | }, 958 | { 959 | "url": "https://github.com/voku", 960 | "type": "github" 961 | }, 962 | { 963 | "url": "https://opencollective.com/portable-ascii", 964 | "type": "open_collective" 965 | }, 966 | { 967 | "url": "https://www.patreon.com/voku", 968 | "type": "patreon" 969 | }, 970 | { 971 | "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", 972 | "type": "tidelift" 973 | } 974 | ], 975 | "time": "2022-01-24T18:59:03+00:00" 976 | } 977 | ], 978 | "packages-dev": [], 979 | "aliases": [], 980 | "minimum-stability": "dev", 981 | "stability-flags": [], 982 | "prefer-stable": true, 983 | "prefer-lowest": false, 984 | "platform": { 985 | "php": "^7.4||^8.0" 986 | }, 987 | "platform-dev": [], 988 | "plugin-api-version": "2.2.0" 989 | } 990 | -------------------------------------------------------------------------------- /config/chart.php: -------------------------------------------------------------------------------- 1 | withProgressBar([ 42 | [ 43 | 'command' => 'vendor:publish', 44 | 'parameters' => [ 45 | '--tag' => 'laravel-chart.config' 46 | ] 47 | ], 48 | [ 49 | 'command' => 'vendor:publish', 50 | 'parameters' => [ 51 | '--tag' => 'laravel-chart.js' 52 | ] 53 | ] 54 | ], function ($command) { 55 | Artisan::call($command['command'], $command['parameters']); 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/LaravelChartServiceProvider.php: -------------------------------------------------------------------------------- 1 | configurePublishing(); 22 | $this->configureCommands(); 23 | } 24 | 25 | /** 26 | * Register the application services. 27 | * 28 | * @return void 29 | */ 30 | public function register() 31 | { 32 | $this->mergeConfigFrom( 33 | __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'chart.php', 'laravel-chart.config' 34 | ); 35 | 36 | $this->configureFacade(); 37 | } 38 | 39 | private function configureFacade() 40 | { 41 | AliasLoader::getInstance()->alias('Chart', ChartFacade::class); 42 | 43 | $this->app->bind('chart', function ($app) { 44 | return new Chart; 45 | }); 46 | } 47 | 48 | private function configurePublishing() 49 | { 50 | $this->publishes([ 51 | __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'chart.php' => config_path('chart.php'), 52 | ], 'laravel-chart.config'); 53 | 54 | $this->publishes([ 55 | __DIR__ . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'chart.js' => public_path('js/chart.js') 56 | ], 'laravel-chart.js'); 57 | } 58 | 59 | private function configureCommands() 60 | { 61 | if ($this->app->runningInConsole()) { 62 | $this->commands([ 63 | InstallCommand::class 64 | ]); 65 | } 66 | } 67 | 68 | } 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/Support/Chart.php: -------------------------------------------------------------------------------- 1 | id = $id; 13 | $this->parameters = $parameters; 14 | return $this; 15 | } 16 | 17 | public function id(string $id): Chart 18 | { 19 | $this->id = $id; 20 | return $this; 21 | } 22 | 23 | public function type(string $type): Chart 24 | { 25 | $this->parameters['type'] = $type; 26 | return $this; 27 | } 28 | 29 | public function labels(array $labels): Chart 30 | { 31 | $this->parameters['data']['labels'] = $labels; 32 | return $this; 33 | } 34 | 35 | public function datasets(array $dataasets): Chart 36 | { 37 | $this->parameters['data']['datasets'] = $dataasets; 38 | return $this; 39 | } 40 | 41 | public function options(array $options): Chart 42 | { 43 | $this->parameters['options'] = $options; 44 | return $this; 45 | } 46 | 47 | public function render(string $view, array $data = []) 48 | { 49 | $data = $this->reformatData($data); 50 | return view($view, $data); 51 | } 52 | 53 | protected function reformatData(array $data) 54 | { 55 | if (key_exists('chartScript', $data)) { 56 | throw new Exception('chartScript key is exists in array, please rename it'); 57 | } 58 | return array_merge($data, [ 59 | 'chartScript' => $this->script() 60 | ]); 61 | } 62 | 63 | protected function parameters(): string 64 | { 65 | return json_encode($this->parameters); 66 | } 67 | 68 | protected function script() 69 | { 70 | return " 71 | const ctx{$this->id} = document.getElementById('{$this->id}').getContext('2d'); 72 | const {$this->id} = new Chart(ctx{$this->id},{$this->parameters()}); 73 | "; 74 | } 75 | } 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Support/Facades/ChartFacade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://www.chartjs.org/
4 |
5 | Simple yet flexible JavaScript charting for designers & developers 6 |

7 | 8 |

9 | Downloads 10 | GitHub Workflow Status 11 | Coverage 12 | Awesome 13 | Slack 14 |

15 | 16 | ## Documentation 17 | 18 | All the links point to the new version 3 of the lib. 19 | 20 | * [Introduction](https://www.chartjs.org/docs/latest/) 21 | * [Getting Started](https://www.chartjs.org/docs/latest/getting-started/index) 22 | * [General](https://www.chartjs.org/docs/latest/general/data-structures) 23 | * [Configuration](https://www.chartjs.org/docs/latest/configuration/index) 24 | * [Charts](https://www.chartjs.org/docs/latest/charts/line) 25 | * [Axes](https://www.chartjs.org/docs/latest/axes/index) 26 | * [Developers](https://www.chartjs.org/docs/latest/developers/index) 27 | * [Popular Extensions](https://github.com/chartjs/awesome) 28 | * [Samples](https://www.chartjs.org/samples/) 29 | 30 | In case you are looking for the docs of version 2, you will have to specify the specific version in the url like this: [https://www.chartjs.org/docs/2.9.4/](https://www.chartjs.org/docs/2.9.4/) 31 | 32 | ## Contributing 33 | 34 | Instructions on building and testing Chart.js can be found in [the documentation](https://www.chartjs.org/docs/master/developers/contributing.html#building-and-testing). Before submitting an issue or a pull request, please take a moment to look over the [contributing guidelines](https://www.chartjs.org/docs/master/developers/contributing) first. For support, please post questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/chartjs) with the `chartjs` tag. 35 | 36 | ## License 37 | 38 | Chart.js is available under the [MIT license](LICENSE.md). 39 | -------------------------------------------------------------------------------- /src/views/js/chart.js/auto/auto.esm.d.ts: -------------------------------------------------------------------------------- 1 | import { Chart } from '../types/index.esm'; 2 | 3 | export * from '../types/index.esm'; 4 | export default Chart; 5 | -------------------------------------------------------------------------------- /src/views/js/chart.js/auto/auto.esm.js: -------------------------------------------------------------------------------- 1 | import {Chart, registerables} from '../dist/chart.esm'; 2 | 3 | Chart.register(...registerables); 4 | 5 | export default Chart; 6 | -------------------------------------------------------------------------------- /src/views/js/chart.js/auto/auto.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../dist/chart'); 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/auto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js-auto", 3 | "private": true, 4 | "description": "auto registering package", 5 | "main": "auto.js", 6 | "module": "auto.esm.js", 7 | "types": "auto.esm.d.ts" 8 | } 9 | -------------------------------------------------------------------------------- /src/views/js/chart.js/dist/chunks/helpers.segment.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Chart.js v3.7.1 3 | * https://www.chartjs.org 4 | * (c) 2022 Chart.js Contributors 5 | * Released under the MIT License 6 | */ 7 | function fontString(pixelSize, fontStyle, fontFamily) { 8 | return fontStyle + ' ' + pixelSize + 'px ' + fontFamily; 9 | } 10 | const requestAnimFrame = (function() { 11 | if (typeof window === 'undefined') { 12 | return function(callback) { 13 | return callback(); 14 | }; 15 | } 16 | return window.requestAnimationFrame; 17 | }()); 18 | function throttled(fn, thisArg, updateFn) { 19 | const updateArgs = updateFn || ((args) => Array.prototype.slice.call(args)); 20 | let ticking = false; 21 | let args = []; 22 | return function(...rest) { 23 | args = updateArgs(rest); 24 | if (!ticking) { 25 | ticking = true; 26 | requestAnimFrame.call(window, () => { 27 | ticking = false; 28 | fn.apply(thisArg, args); 29 | }); 30 | } 31 | }; 32 | } 33 | function debounce(fn, delay) { 34 | let timeout; 35 | return function(...args) { 36 | if (delay) { 37 | clearTimeout(timeout); 38 | timeout = setTimeout(fn, delay, args); 39 | } else { 40 | fn.apply(this, args); 41 | } 42 | return delay; 43 | }; 44 | } 45 | const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align === 'end' ? 'right' : 'center'; 46 | const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2; 47 | const _textX = (align, left, right, rtl) => { 48 | const check = rtl ? 'left' : 'right'; 49 | return align === check ? right : align === 'center' ? (left + right) / 2 : left; 50 | }; 51 | 52 | function noop() {} 53 | const uid = (function() { 54 | let id = 0; 55 | return function() { 56 | return id++; 57 | }; 58 | }()); 59 | function isNullOrUndef(value) { 60 | return value === null || typeof value === 'undefined'; 61 | } 62 | function isArray(value) { 63 | if (Array.isArray && Array.isArray(value)) { 64 | return true; 65 | } 66 | const type = Object.prototype.toString.call(value); 67 | if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { 68 | return true; 69 | } 70 | return false; 71 | } 72 | function isObject(value) { 73 | return value !== null && Object.prototype.toString.call(value) === '[object Object]'; 74 | } 75 | const isNumberFinite = (value) => (typeof value === 'number' || value instanceof Number) && isFinite(+value); 76 | function finiteOrDefault(value, defaultValue) { 77 | return isNumberFinite(value) ? value : defaultValue; 78 | } 79 | function valueOrDefault(value, defaultValue) { 80 | return typeof value === 'undefined' ? defaultValue : value; 81 | } 82 | const toPercentage = (value, dimension) => 83 | typeof value === 'string' && value.endsWith('%') ? 84 | parseFloat(value) / 100 85 | : value / dimension; 86 | const toDimension = (value, dimension) => 87 | typeof value === 'string' && value.endsWith('%') ? 88 | parseFloat(value) / 100 * dimension 89 | : +value; 90 | function callback(fn, args, thisArg) { 91 | if (fn && typeof fn.call === 'function') { 92 | return fn.apply(thisArg, args); 93 | } 94 | } 95 | function each(loopable, fn, thisArg, reverse) { 96 | let i, len, keys; 97 | if (isArray(loopable)) { 98 | len = loopable.length; 99 | if (reverse) { 100 | for (i = len - 1; i >= 0; i--) { 101 | fn.call(thisArg, loopable[i], i); 102 | } 103 | } else { 104 | for (i = 0; i < len; i++) { 105 | fn.call(thisArg, loopable[i], i); 106 | } 107 | } 108 | } else if (isObject(loopable)) { 109 | keys = Object.keys(loopable); 110 | len = keys.length; 111 | for (i = 0; i < len; i++) { 112 | fn.call(thisArg, loopable[keys[i]], keys[i]); 113 | } 114 | } 115 | } 116 | function _elementsEqual(a0, a1) { 117 | let i, ilen, v0, v1; 118 | if (!a0 || !a1 || a0.length !== a1.length) { 119 | return false; 120 | } 121 | for (i = 0, ilen = a0.length; i < ilen; ++i) { 122 | v0 = a0[i]; 123 | v1 = a1[i]; 124 | if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) { 125 | return false; 126 | } 127 | } 128 | return true; 129 | } 130 | function clone$1(source) { 131 | if (isArray(source)) { 132 | return source.map(clone$1); 133 | } 134 | if (isObject(source)) { 135 | const target = Object.create(null); 136 | const keys = Object.keys(source); 137 | const klen = keys.length; 138 | let k = 0; 139 | for (; k < klen; ++k) { 140 | target[keys[k]] = clone$1(source[keys[k]]); 141 | } 142 | return target; 143 | } 144 | return source; 145 | } 146 | function isValidKey(key) { 147 | return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1; 148 | } 149 | function _merger(key, target, source, options) { 150 | if (!isValidKey(key)) { 151 | return; 152 | } 153 | const tval = target[key]; 154 | const sval = source[key]; 155 | if (isObject(tval) && isObject(sval)) { 156 | merge(tval, sval, options); 157 | } else { 158 | target[key] = clone$1(sval); 159 | } 160 | } 161 | function merge(target, source, options) { 162 | const sources = isArray(source) ? source : [source]; 163 | const ilen = sources.length; 164 | if (!isObject(target)) { 165 | return target; 166 | } 167 | options = options || {}; 168 | const merger = options.merger || _merger; 169 | for (let i = 0; i < ilen; ++i) { 170 | source = sources[i]; 171 | if (!isObject(source)) { 172 | continue; 173 | } 174 | const keys = Object.keys(source); 175 | for (let k = 0, klen = keys.length; k < klen; ++k) { 176 | merger(keys[k], target, source, options); 177 | } 178 | } 179 | return target; 180 | } 181 | function mergeIf(target, source) { 182 | return merge(target, source, {merger: _mergerIf}); 183 | } 184 | function _mergerIf(key, target, source) { 185 | if (!isValidKey(key)) { 186 | return; 187 | } 188 | const tval = target[key]; 189 | const sval = source[key]; 190 | if (isObject(tval) && isObject(sval)) { 191 | mergeIf(tval, sval); 192 | } else if (!Object.prototype.hasOwnProperty.call(target, key)) { 193 | target[key] = clone$1(sval); 194 | } 195 | } 196 | function _deprecated(scope, value, previous, current) { 197 | if (value !== undefined) { 198 | console.warn(scope + ': "' + previous + 199 | '" is deprecated. Please use "' + current + '" instead'); 200 | } 201 | } 202 | const emptyString = ''; 203 | const dot = '.'; 204 | function indexOfDotOrLength(key, start) { 205 | const idx = key.indexOf(dot, start); 206 | return idx === -1 ? key.length : idx; 207 | } 208 | function resolveObjectKey(obj, key) { 209 | if (key === emptyString) { 210 | return obj; 211 | } 212 | let pos = 0; 213 | let idx = indexOfDotOrLength(key, pos); 214 | while (obj && idx > pos) { 215 | obj = obj[key.substr(pos, idx - pos)]; 216 | pos = idx + 1; 217 | idx = indexOfDotOrLength(key, pos); 218 | } 219 | return obj; 220 | } 221 | function _capitalize(str) { 222 | return str.charAt(0).toUpperCase() + str.slice(1); 223 | } 224 | const defined = (value) => typeof value !== 'undefined'; 225 | const isFunction = (value) => typeof value === 'function'; 226 | const setsEqual = (a, b) => { 227 | if (a.size !== b.size) { 228 | return false; 229 | } 230 | for (const item of a) { 231 | if (!b.has(item)) { 232 | return false; 233 | } 234 | } 235 | return true; 236 | }; 237 | function _isClickEvent(e) { 238 | return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu'; 239 | } 240 | 241 | const PI = Math.PI; 242 | const TAU = 2 * PI; 243 | const PITAU = TAU + PI; 244 | const INFINITY = Number.POSITIVE_INFINITY; 245 | const RAD_PER_DEG = PI / 180; 246 | const HALF_PI = PI / 2; 247 | const QUARTER_PI = PI / 4; 248 | const TWO_THIRDS_PI = PI * 2 / 3; 249 | const log10 = Math.log10; 250 | const sign = Math.sign; 251 | function niceNum(range) { 252 | const roundedRange = Math.round(range); 253 | range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range; 254 | const niceRange = Math.pow(10, Math.floor(log10(range))); 255 | const fraction = range / niceRange; 256 | const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10; 257 | return niceFraction * niceRange; 258 | } 259 | function _factorize(value) { 260 | const result = []; 261 | const sqrt = Math.sqrt(value); 262 | let i; 263 | for (i = 1; i < sqrt; i++) { 264 | if (value % i === 0) { 265 | result.push(i); 266 | result.push(value / i); 267 | } 268 | } 269 | if (sqrt === (sqrt | 0)) { 270 | result.push(sqrt); 271 | } 272 | result.sort((a, b) => a - b).pop(); 273 | return result; 274 | } 275 | function isNumber(n) { 276 | return !isNaN(parseFloat(n)) && isFinite(n); 277 | } 278 | function almostEquals(x, y, epsilon) { 279 | return Math.abs(x - y) < epsilon; 280 | } 281 | function almostWhole(x, epsilon) { 282 | const rounded = Math.round(x); 283 | return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x); 284 | } 285 | function _setMinAndMaxByKey(array, target, property) { 286 | let i, ilen, value; 287 | for (i = 0, ilen = array.length; i < ilen; i++) { 288 | value = array[i][property]; 289 | if (!isNaN(value)) { 290 | target.min = Math.min(target.min, value); 291 | target.max = Math.max(target.max, value); 292 | } 293 | } 294 | } 295 | function toRadians(degrees) { 296 | return degrees * (PI / 180); 297 | } 298 | function toDegrees(radians) { 299 | return radians * (180 / PI); 300 | } 301 | function _decimalPlaces(x) { 302 | if (!isNumberFinite(x)) { 303 | return; 304 | } 305 | let e = 1; 306 | let p = 0; 307 | while (Math.round(x * e) / e !== x) { 308 | e *= 10; 309 | p++; 310 | } 311 | return p; 312 | } 313 | function getAngleFromPoint(centrePoint, anglePoint) { 314 | const distanceFromXCenter = anglePoint.x - centrePoint.x; 315 | const distanceFromYCenter = anglePoint.y - centrePoint.y; 316 | const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); 317 | let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); 318 | if (angle < (-0.5 * PI)) { 319 | angle += TAU; 320 | } 321 | return { 322 | angle, 323 | distance: radialDistanceFromCenter 324 | }; 325 | } 326 | function distanceBetweenPoints(pt1, pt2) { 327 | return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); 328 | } 329 | function _angleDiff(a, b) { 330 | return (a - b + PITAU) % TAU - PI; 331 | } 332 | function _normalizeAngle(a) { 333 | return (a % TAU + TAU) % TAU; 334 | } 335 | function _angleBetween(angle, start, end, sameAngleIsFullCircle) { 336 | const a = _normalizeAngle(angle); 337 | const s = _normalizeAngle(start); 338 | const e = _normalizeAngle(end); 339 | const angleToStart = _normalizeAngle(s - a); 340 | const angleToEnd = _normalizeAngle(e - a); 341 | const startToAngle = _normalizeAngle(a - s); 342 | const endToAngle = _normalizeAngle(a - e); 343 | return a === s || a === e || (sameAngleIsFullCircle && s === e) 344 | || (angleToStart > angleToEnd && startToAngle < endToAngle); 345 | } 346 | function _limitValue(value, min, max) { 347 | return Math.max(min, Math.min(max, value)); 348 | } 349 | function _int16Range(value) { 350 | return _limitValue(value, -32768, 32767); 351 | } 352 | function _isBetween(value, start, end, epsilon = 1e-6) { 353 | return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon; 354 | } 355 | 356 | const atEdge = (t) => t === 0 || t === 1; 357 | const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p)); 358 | const elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1; 359 | const effects = { 360 | linear: t => t, 361 | easeInQuad: t => t * t, 362 | easeOutQuad: t => -t * (t - 2), 363 | easeInOutQuad: t => ((t /= 0.5) < 1) 364 | ? 0.5 * t * t 365 | : -0.5 * ((--t) * (t - 2) - 1), 366 | easeInCubic: t => t * t * t, 367 | easeOutCubic: t => (t -= 1) * t * t + 1, 368 | easeInOutCubic: t => ((t /= 0.5) < 1) 369 | ? 0.5 * t * t * t 370 | : 0.5 * ((t -= 2) * t * t + 2), 371 | easeInQuart: t => t * t * t * t, 372 | easeOutQuart: t => -((t -= 1) * t * t * t - 1), 373 | easeInOutQuart: t => ((t /= 0.5) < 1) 374 | ? 0.5 * t * t * t * t 375 | : -0.5 * ((t -= 2) * t * t * t - 2), 376 | easeInQuint: t => t * t * t * t * t, 377 | easeOutQuint: t => (t -= 1) * t * t * t * t + 1, 378 | easeInOutQuint: t => ((t /= 0.5) < 1) 379 | ? 0.5 * t * t * t * t * t 380 | : 0.5 * ((t -= 2) * t * t * t * t + 2), 381 | easeInSine: t => -Math.cos(t * HALF_PI) + 1, 382 | easeOutSine: t => Math.sin(t * HALF_PI), 383 | easeInOutSine: t => -0.5 * (Math.cos(PI * t) - 1), 384 | easeInExpo: t => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)), 385 | easeOutExpo: t => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1, 386 | easeInOutExpo: t => atEdge(t) ? t : t < 0.5 387 | ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) 388 | : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2), 389 | easeInCirc: t => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1), 390 | easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t), 391 | easeInOutCirc: t => ((t /= 0.5) < 1) 392 | ? -0.5 * (Math.sqrt(1 - t * t) - 1) 393 | : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1), 394 | easeInElastic: t => atEdge(t) ? t : elasticIn(t, 0.075, 0.3), 395 | easeOutElastic: t => atEdge(t) ? t : elasticOut(t, 0.075, 0.3), 396 | easeInOutElastic(t) { 397 | const s = 0.1125; 398 | const p = 0.45; 399 | return atEdge(t) ? t : 400 | t < 0.5 401 | ? 0.5 * elasticIn(t * 2, s, p) 402 | : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p); 403 | }, 404 | easeInBack(t) { 405 | const s = 1.70158; 406 | return t * t * ((s + 1) * t - s); 407 | }, 408 | easeOutBack(t) { 409 | const s = 1.70158; 410 | return (t -= 1) * t * ((s + 1) * t + s) + 1; 411 | }, 412 | easeInOutBack(t) { 413 | let s = 1.70158; 414 | if ((t /= 0.5) < 1) { 415 | return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); 416 | } 417 | return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); 418 | }, 419 | easeInBounce: t => 1 - effects.easeOutBounce(1 - t), 420 | easeOutBounce(t) { 421 | const m = 7.5625; 422 | const d = 2.75; 423 | if (t < (1 / d)) { 424 | return m * t * t; 425 | } 426 | if (t < (2 / d)) { 427 | return m * (t -= (1.5 / d)) * t + 0.75; 428 | } 429 | if (t < (2.5 / d)) { 430 | return m * (t -= (2.25 / d)) * t + 0.9375; 431 | } 432 | return m * (t -= (2.625 / d)) * t + 0.984375; 433 | }, 434 | easeInOutBounce: t => (t < 0.5) 435 | ? effects.easeInBounce(t * 2) * 0.5 436 | : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5, 437 | }; 438 | 439 | /*! 440 | * @kurkle/color v0.1.9 441 | * https://github.com/kurkle/color#readme 442 | * (c) 2020 Jukka Kurkela 443 | * Released under the MIT License 444 | */ 445 | const map = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15}; 446 | const hex = '0123456789ABCDEF'; 447 | const h1 = (b) => hex[b & 0xF]; 448 | const h2 = (b) => hex[(b & 0xF0) >> 4] + hex[b & 0xF]; 449 | const eq = (b) => (((b & 0xF0) >> 4) === (b & 0xF)); 450 | function isShort(v) { 451 | return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a); 452 | } 453 | function hexParse(str) { 454 | var len = str.length; 455 | var ret; 456 | if (str[0] === '#') { 457 | if (len === 4 || len === 5) { 458 | ret = { 459 | r: 255 & map[str[1]] * 17, 460 | g: 255 & map[str[2]] * 17, 461 | b: 255 & map[str[3]] * 17, 462 | a: len === 5 ? map[str[4]] * 17 : 255 463 | }; 464 | } else if (len === 7 || len === 9) { 465 | ret = { 466 | r: map[str[1]] << 4 | map[str[2]], 467 | g: map[str[3]] << 4 | map[str[4]], 468 | b: map[str[5]] << 4 | map[str[6]], 469 | a: len === 9 ? (map[str[7]] << 4 | map[str[8]]) : 255 470 | }; 471 | } 472 | } 473 | return ret; 474 | } 475 | function hexString(v) { 476 | var f = isShort(v) ? h1 : h2; 477 | return v 478 | ? '#' + f(v.r) + f(v.g) + f(v.b) + (v.a < 255 ? f(v.a) : '') 479 | : v; 480 | } 481 | function round(v) { 482 | return v + 0.5 | 0; 483 | } 484 | const lim = (v, l, h) => Math.max(Math.min(v, h), l); 485 | function p2b(v) { 486 | return lim(round(v * 2.55), 0, 255); 487 | } 488 | function n2b(v) { 489 | return lim(round(v * 255), 0, 255); 490 | } 491 | function b2n(v) { 492 | return lim(round(v / 2.55) / 100, 0, 1); 493 | } 494 | function n2p(v) { 495 | return lim(round(v * 100), 0, 100); 496 | } 497 | const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; 498 | function rgbParse(str) { 499 | const m = RGB_RE.exec(str); 500 | let a = 255; 501 | let r, g, b; 502 | if (!m) { 503 | return; 504 | } 505 | if (m[7] !== r) { 506 | const v = +m[7]; 507 | a = 255 & (m[8] ? p2b(v) : v * 255); 508 | } 509 | r = +m[1]; 510 | g = +m[3]; 511 | b = +m[5]; 512 | r = 255 & (m[2] ? p2b(r) : r); 513 | g = 255 & (m[4] ? p2b(g) : g); 514 | b = 255 & (m[6] ? p2b(b) : b); 515 | return { 516 | r: r, 517 | g: g, 518 | b: b, 519 | a: a 520 | }; 521 | } 522 | function rgbString(v) { 523 | return v && ( 524 | v.a < 255 525 | ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})` 526 | : `rgb(${v.r}, ${v.g}, ${v.b})` 527 | ); 528 | } 529 | const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; 530 | function hsl2rgbn(h, s, l) { 531 | const a = s * Math.min(l, 1 - l); 532 | const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); 533 | return [f(0), f(8), f(4)]; 534 | } 535 | function hsv2rgbn(h, s, v) { 536 | const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0); 537 | return [f(5), f(3), f(1)]; 538 | } 539 | function hwb2rgbn(h, w, b) { 540 | const rgb = hsl2rgbn(h, 1, 0.5); 541 | let i; 542 | if (w + b > 1) { 543 | i = 1 / (w + b); 544 | w *= i; 545 | b *= i; 546 | } 547 | for (i = 0; i < 3; i++) { 548 | rgb[i] *= 1 - w - b; 549 | rgb[i] += w; 550 | } 551 | return rgb; 552 | } 553 | function rgb2hsl(v) { 554 | const range = 255; 555 | const r = v.r / range; 556 | const g = v.g / range; 557 | const b = v.b / range; 558 | const max = Math.max(r, g, b); 559 | const min = Math.min(r, g, b); 560 | const l = (max + min) / 2; 561 | let h, s, d; 562 | if (max !== min) { 563 | d = max - min; 564 | s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 565 | h = max === r 566 | ? ((g - b) / d) + (g < b ? 6 : 0) 567 | : max === g 568 | ? (b - r) / d + 2 569 | : (r - g) / d + 4; 570 | h = h * 60 + 0.5; 571 | } 572 | return [h | 0, s || 0, l]; 573 | } 574 | function calln(f, a, b, c) { 575 | return ( 576 | Array.isArray(a) 577 | ? f(a[0], a[1], a[2]) 578 | : f(a, b, c) 579 | ).map(n2b); 580 | } 581 | function hsl2rgb(h, s, l) { 582 | return calln(hsl2rgbn, h, s, l); 583 | } 584 | function hwb2rgb(h, w, b) { 585 | return calln(hwb2rgbn, h, w, b); 586 | } 587 | function hsv2rgb(h, s, v) { 588 | return calln(hsv2rgbn, h, s, v); 589 | } 590 | function hue(h) { 591 | return (h % 360 + 360) % 360; 592 | } 593 | function hueParse(str) { 594 | const m = HUE_RE.exec(str); 595 | let a = 255; 596 | let v; 597 | if (!m) { 598 | return; 599 | } 600 | if (m[5] !== v) { 601 | a = m[6] ? p2b(+m[5]) : n2b(+m[5]); 602 | } 603 | const h = hue(+m[2]); 604 | const p1 = +m[3] / 100; 605 | const p2 = +m[4] / 100; 606 | if (m[1] === 'hwb') { 607 | v = hwb2rgb(h, p1, p2); 608 | } else if (m[1] === 'hsv') { 609 | v = hsv2rgb(h, p1, p2); 610 | } else { 611 | v = hsl2rgb(h, p1, p2); 612 | } 613 | return { 614 | r: v[0], 615 | g: v[1], 616 | b: v[2], 617 | a: a 618 | }; 619 | } 620 | function rotate(v, deg) { 621 | var h = rgb2hsl(v); 622 | h[0] = hue(h[0] + deg); 623 | h = hsl2rgb(h); 624 | v.r = h[0]; 625 | v.g = h[1]; 626 | v.b = h[2]; 627 | } 628 | function hslString(v) { 629 | if (!v) { 630 | return; 631 | } 632 | const a = rgb2hsl(v); 633 | const h = a[0]; 634 | const s = n2p(a[1]); 635 | const l = n2p(a[2]); 636 | return v.a < 255 637 | ? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})` 638 | : `hsl(${h}, ${s}%, ${l}%)`; 639 | } 640 | const map$1 = { 641 | x: 'dark', 642 | Z: 'light', 643 | Y: 're', 644 | X: 'blu', 645 | W: 'gr', 646 | V: 'medium', 647 | U: 'slate', 648 | A: 'ee', 649 | T: 'ol', 650 | S: 'or', 651 | B: 'ra', 652 | C: 'lateg', 653 | D: 'ights', 654 | R: 'in', 655 | Q: 'turquois', 656 | E: 'hi', 657 | P: 'ro', 658 | O: 'al', 659 | N: 'le', 660 | M: 'de', 661 | L: 'yello', 662 | F: 'en', 663 | K: 'ch', 664 | G: 'arks', 665 | H: 'ea', 666 | I: 'ightg', 667 | J: 'wh' 668 | }; 669 | const names = { 670 | OiceXe: 'f0f8ff', 671 | antiquewEte: 'faebd7', 672 | aqua: 'ffff', 673 | aquamarRe: '7fffd4', 674 | azuY: 'f0ffff', 675 | beige: 'f5f5dc', 676 | bisque: 'ffe4c4', 677 | black: '0', 678 | blanKedOmond: 'ffebcd', 679 | Xe: 'ff', 680 | XeviTet: '8a2be2', 681 | bPwn: 'a52a2a', 682 | burlywood: 'deb887', 683 | caMtXe: '5f9ea0', 684 | KartYuse: '7fff00', 685 | KocTate: 'd2691e', 686 | cSO: 'ff7f50', 687 | cSnflowerXe: '6495ed', 688 | cSnsilk: 'fff8dc', 689 | crimson: 'dc143c', 690 | cyan: 'ffff', 691 | xXe: '8b', 692 | xcyan: '8b8b', 693 | xgTMnPd: 'b8860b', 694 | xWay: 'a9a9a9', 695 | xgYF: '6400', 696 | xgYy: 'a9a9a9', 697 | xkhaki: 'bdb76b', 698 | xmagFta: '8b008b', 699 | xTivegYF: '556b2f', 700 | xSange: 'ff8c00', 701 | xScEd: '9932cc', 702 | xYd: '8b0000', 703 | xsOmon: 'e9967a', 704 | xsHgYF: '8fbc8f', 705 | xUXe: '483d8b', 706 | xUWay: '2f4f4f', 707 | xUgYy: '2f4f4f', 708 | xQe: 'ced1', 709 | xviTet: '9400d3', 710 | dAppRk: 'ff1493', 711 | dApskyXe: 'bfff', 712 | dimWay: '696969', 713 | dimgYy: '696969', 714 | dodgerXe: '1e90ff', 715 | fiYbrick: 'b22222', 716 | flSOwEte: 'fffaf0', 717 | foYstWAn: '228b22', 718 | fuKsia: 'ff00ff', 719 | gaRsbSo: 'dcdcdc', 720 | ghostwEte: 'f8f8ff', 721 | gTd: 'ffd700', 722 | gTMnPd: 'daa520', 723 | Way: '808080', 724 | gYF: '8000', 725 | gYFLw: 'adff2f', 726 | gYy: '808080', 727 | honeyMw: 'f0fff0', 728 | hotpRk: 'ff69b4', 729 | RdianYd: 'cd5c5c', 730 | Rdigo: '4b0082', 731 | ivSy: 'fffff0', 732 | khaki: 'f0e68c', 733 | lavFMr: 'e6e6fa', 734 | lavFMrXsh: 'fff0f5', 735 | lawngYF: '7cfc00', 736 | NmoncEffon: 'fffacd', 737 | ZXe: 'add8e6', 738 | ZcSO: 'f08080', 739 | Zcyan: 'e0ffff', 740 | ZgTMnPdLw: 'fafad2', 741 | ZWay: 'd3d3d3', 742 | ZgYF: '90ee90', 743 | ZgYy: 'd3d3d3', 744 | ZpRk: 'ffb6c1', 745 | ZsOmon: 'ffa07a', 746 | ZsHgYF: '20b2aa', 747 | ZskyXe: '87cefa', 748 | ZUWay: '778899', 749 | ZUgYy: '778899', 750 | ZstAlXe: 'b0c4de', 751 | ZLw: 'ffffe0', 752 | lime: 'ff00', 753 | limegYF: '32cd32', 754 | lRF: 'faf0e6', 755 | magFta: 'ff00ff', 756 | maPon: '800000', 757 | VaquamarRe: '66cdaa', 758 | VXe: 'cd', 759 | VScEd: 'ba55d3', 760 | VpurpN: '9370db', 761 | VsHgYF: '3cb371', 762 | VUXe: '7b68ee', 763 | VsprRggYF: 'fa9a', 764 | VQe: '48d1cc', 765 | VviTetYd: 'c71585', 766 | midnightXe: '191970', 767 | mRtcYam: 'f5fffa', 768 | mistyPse: 'ffe4e1', 769 | moccasR: 'ffe4b5', 770 | navajowEte: 'ffdead', 771 | navy: '80', 772 | Tdlace: 'fdf5e6', 773 | Tive: '808000', 774 | TivedBb: '6b8e23', 775 | Sange: 'ffa500', 776 | SangeYd: 'ff4500', 777 | ScEd: 'da70d6', 778 | pOegTMnPd: 'eee8aa', 779 | pOegYF: '98fb98', 780 | pOeQe: 'afeeee', 781 | pOeviTetYd: 'db7093', 782 | papayawEp: 'ffefd5', 783 | pHKpuff: 'ffdab9', 784 | peru: 'cd853f', 785 | pRk: 'ffc0cb', 786 | plum: 'dda0dd', 787 | powMrXe: 'b0e0e6', 788 | purpN: '800080', 789 | YbeccapurpN: '663399', 790 | Yd: 'ff0000', 791 | Psybrown: 'bc8f8f', 792 | PyOXe: '4169e1', 793 | saddNbPwn: '8b4513', 794 | sOmon: 'fa8072', 795 | sandybPwn: 'f4a460', 796 | sHgYF: '2e8b57', 797 | sHshell: 'fff5ee', 798 | siFna: 'a0522d', 799 | silver: 'c0c0c0', 800 | skyXe: '87ceeb', 801 | UXe: '6a5acd', 802 | UWay: '708090', 803 | UgYy: '708090', 804 | snow: 'fffafa', 805 | sprRggYF: 'ff7f', 806 | stAlXe: '4682b4', 807 | tan: 'd2b48c', 808 | teO: '8080', 809 | tEstN: 'd8bfd8', 810 | tomato: 'ff6347', 811 | Qe: '40e0d0', 812 | viTet: 'ee82ee', 813 | JHt: 'f5deb3', 814 | wEte: 'ffffff', 815 | wEtesmoke: 'f5f5f5', 816 | Lw: 'ffff00', 817 | LwgYF: '9acd32' 818 | }; 819 | function unpack() { 820 | const unpacked = {}; 821 | const keys = Object.keys(names); 822 | const tkeys = Object.keys(map$1); 823 | let i, j, k, ok, nk; 824 | for (i = 0; i < keys.length; i++) { 825 | ok = nk = keys[i]; 826 | for (j = 0; j < tkeys.length; j++) { 827 | k = tkeys[j]; 828 | nk = nk.replace(k, map$1[k]); 829 | } 830 | k = parseInt(names[ok], 16); 831 | unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF]; 832 | } 833 | return unpacked; 834 | } 835 | let names$1; 836 | function nameParse(str) { 837 | if (!names$1) { 838 | names$1 = unpack(); 839 | names$1.transparent = [0, 0, 0, 0]; 840 | } 841 | const a = names$1[str.toLowerCase()]; 842 | return a && { 843 | r: a[0], 844 | g: a[1], 845 | b: a[2], 846 | a: a.length === 4 ? a[3] : 255 847 | }; 848 | } 849 | function modHSL(v, i, ratio) { 850 | if (v) { 851 | let tmp = rgb2hsl(v); 852 | tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1)); 853 | tmp = hsl2rgb(tmp); 854 | v.r = tmp[0]; 855 | v.g = tmp[1]; 856 | v.b = tmp[2]; 857 | } 858 | } 859 | function clone(v, proto) { 860 | return v ? Object.assign(proto || {}, v) : v; 861 | } 862 | function fromObject(input) { 863 | var v = {r: 0, g: 0, b: 0, a: 255}; 864 | if (Array.isArray(input)) { 865 | if (input.length >= 3) { 866 | v = {r: input[0], g: input[1], b: input[2], a: 255}; 867 | if (input.length > 3) { 868 | v.a = n2b(input[3]); 869 | } 870 | } 871 | } else { 872 | v = clone(input, {r: 0, g: 0, b: 0, a: 1}); 873 | v.a = n2b(v.a); 874 | } 875 | return v; 876 | } 877 | function functionParse(str) { 878 | if (str.charAt(0) === 'r') { 879 | return rgbParse(str); 880 | } 881 | return hueParse(str); 882 | } 883 | class Color { 884 | constructor(input) { 885 | if (input instanceof Color) { 886 | return input; 887 | } 888 | const type = typeof input; 889 | let v; 890 | if (type === 'object') { 891 | v = fromObject(input); 892 | } else if (type === 'string') { 893 | v = hexParse(input) || nameParse(input) || functionParse(input); 894 | } 895 | this._rgb = v; 896 | this._valid = !!v; 897 | } 898 | get valid() { 899 | return this._valid; 900 | } 901 | get rgb() { 902 | var v = clone(this._rgb); 903 | if (v) { 904 | v.a = b2n(v.a); 905 | } 906 | return v; 907 | } 908 | set rgb(obj) { 909 | this._rgb = fromObject(obj); 910 | } 911 | rgbString() { 912 | return this._valid ? rgbString(this._rgb) : this._rgb; 913 | } 914 | hexString() { 915 | return this._valid ? hexString(this._rgb) : this._rgb; 916 | } 917 | hslString() { 918 | return this._valid ? hslString(this._rgb) : this._rgb; 919 | } 920 | mix(color, weight) { 921 | const me = this; 922 | if (color) { 923 | const c1 = me.rgb; 924 | const c2 = color.rgb; 925 | let w2; 926 | const p = weight === w2 ? 0.5 : weight; 927 | const w = 2 * p - 1; 928 | const a = c1.a - c2.a; 929 | const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0; 930 | w2 = 1 - w1; 931 | c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5; 932 | c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5; 933 | c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5; 934 | c1.a = p * c1.a + (1 - p) * c2.a; 935 | me.rgb = c1; 936 | } 937 | return me; 938 | } 939 | clone() { 940 | return new Color(this.rgb); 941 | } 942 | alpha(a) { 943 | this._rgb.a = n2b(a); 944 | return this; 945 | } 946 | clearer(ratio) { 947 | const rgb = this._rgb; 948 | rgb.a *= 1 - ratio; 949 | return this; 950 | } 951 | greyscale() { 952 | const rgb = this._rgb; 953 | const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11); 954 | rgb.r = rgb.g = rgb.b = val; 955 | return this; 956 | } 957 | opaquer(ratio) { 958 | const rgb = this._rgb; 959 | rgb.a *= 1 + ratio; 960 | return this; 961 | } 962 | negate() { 963 | const v = this._rgb; 964 | v.r = 255 - v.r; 965 | v.g = 255 - v.g; 966 | v.b = 255 - v.b; 967 | return this; 968 | } 969 | lighten(ratio) { 970 | modHSL(this._rgb, 2, ratio); 971 | return this; 972 | } 973 | darken(ratio) { 974 | modHSL(this._rgb, 2, -ratio); 975 | return this; 976 | } 977 | saturate(ratio) { 978 | modHSL(this._rgb, 1, ratio); 979 | return this; 980 | } 981 | desaturate(ratio) { 982 | modHSL(this._rgb, 1, -ratio); 983 | return this; 984 | } 985 | rotate(deg) { 986 | rotate(this._rgb, deg); 987 | return this; 988 | } 989 | } 990 | function index_esm(input) { 991 | return new Color(input); 992 | } 993 | 994 | const isPatternOrGradient = (value) => value instanceof CanvasGradient || value instanceof CanvasPattern; 995 | function color(value) { 996 | return isPatternOrGradient(value) ? value : index_esm(value); 997 | } 998 | function getHoverColor(value) { 999 | return isPatternOrGradient(value) 1000 | ? value 1001 | : index_esm(value).saturate(0.5).darken(0.1).hexString(); 1002 | } 1003 | 1004 | const overrides = Object.create(null); 1005 | const descriptors = Object.create(null); 1006 | function getScope$1(node, key) { 1007 | if (!key) { 1008 | return node; 1009 | } 1010 | const keys = key.split('.'); 1011 | for (let i = 0, n = keys.length; i < n; ++i) { 1012 | const k = keys[i]; 1013 | node = node[k] || (node[k] = Object.create(null)); 1014 | } 1015 | return node; 1016 | } 1017 | function set(root, scope, values) { 1018 | if (typeof scope === 'string') { 1019 | return merge(getScope$1(root, scope), values); 1020 | } 1021 | return merge(getScope$1(root, ''), scope); 1022 | } 1023 | class Defaults { 1024 | constructor(_descriptors) { 1025 | this.animation = undefined; 1026 | this.backgroundColor = 'rgba(0,0,0,0.1)'; 1027 | this.borderColor = 'rgba(0,0,0,0.1)'; 1028 | this.color = '#666'; 1029 | this.datasets = {}; 1030 | this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio(); 1031 | this.elements = {}; 1032 | this.events = [ 1033 | 'mousemove', 1034 | 'mouseout', 1035 | 'click', 1036 | 'touchstart', 1037 | 'touchmove' 1038 | ]; 1039 | this.font = { 1040 | family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", 1041 | size: 12, 1042 | style: 'normal', 1043 | lineHeight: 1.2, 1044 | weight: null 1045 | }; 1046 | this.hover = {}; 1047 | this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor); 1048 | this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor); 1049 | this.hoverColor = (ctx, options) => getHoverColor(options.color); 1050 | this.indexAxis = 'x'; 1051 | this.interaction = { 1052 | mode: 'nearest', 1053 | intersect: true 1054 | }; 1055 | this.maintainAspectRatio = true; 1056 | this.onHover = null; 1057 | this.onClick = null; 1058 | this.parsing = true; 1059 | this.plugins = {}; 1060 | this.responsive = true; 1061 | this.scale = undefined; 1062 | this.scales = {}; 1063 | this.showLine = true; 1064 | this.drawActiveElementsOnTop = true; 1065 | this.describe(_descriptors); 1066 | } 1067 | set(scope, values) { 1068 | return set(this, scope, values); 1069 | } 1070 | get(scope) { 1071 | return getScope$1(this, scope); 1072 | } 1073 | describe(scope, values) { 1074 | return set(descriptors, scope, values); 1075 | } 1076 | override(scope, values) { 1077 | return set(overrides, scope, values); 1078 | } 1079 | route(scope, name, targetScope, targetName) { 1080 | const scopeObject = getScope$1(this, scope); 1081 | const targetScopeObject = getScope$1(this, targetScope); 1082 | const privateName = '_' + name; 1083 | Object.defineProperties(scopeObject, { 1084 | [privateName]: { 1085 | value: scopeObject[name], 1086 | writable: true 1087 | }, 1088 | [name]: { 1089 | enumerable: true, 1090 | get() { 1091 | const local = this[privateName]; 1092 | const target = targetScopeObject[targetName]; 1093 | if (isObject(local)) { 1094 | return Object.assign({}, target, local); 1095 | } 1096 | return valueOrDefault(local, target); 1097 | }, 1098 | set(value) { 1099 | this[privateName] = value; 1100 | } 1101 | } 1102 | }); 1103 | } 1104 | } 1105 | var defaults = new Defaults({ 1106 | _scriptable: (name) => !name.startsWith('on'), 1107 | _indexable: (name) => name !== 'events', 1108 | hover: { 1109 | _fallback: 'interaction' 1110 | }, 1111 | interaction: { 1112 | _scriptable: false, 1113 | _indexable: false, 1114 | } 1115 | }); 1116 | 1117 | function toFontString(font) { 1118 | if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { 1119 | return null; 1120 | } 1121 | return (font.style ? font.style + ' ' : '') 1122 | + (font.weight ? font.weight + ' ' : '') 1123 | + font.size + 'px ' 1124 | + font.family; 1125 | } 1126 | function _measureText(ctx, data, gc, longest, string) { 1127 | let textWidth = data[string]; 1128 | if (!textWidth) { 1129 | textWidth = data[string] = ctx.measureText(string).width; 1130 | gc.push(string); 1131 | } 1132 | if (textWidth > longest) { 1133 | longest = textWidth; 1134 | } 1135 | return longest; 1136 | } 1137 | function _longestText(ctx, font, arrayOfThings, cache) { 1138 | cache = cache || {}; 1139 | let data = cache.data = cache.data || {}; 1140 | let gc = cache.garbageCollect = cache.garbageCollect || []; 1141 | if (cache.font !== font) { 1142 | data = cache.data = {}; 1143 | gc = cache.garbageCollect = []; 1144 | cache.font = font; 1145 | } 1146 | ctx.save(); 1147 | ctx.font = font; 1148 | let longest = 0; 1149 | const ilen = arrayOfThings.length; 1150 | let i, j, jlen, thing, nestedThing; 1151 | for (i = 0; i < ilen; i++) { 1152 | thing = arrayOfThings[i]; 1153 | if (thing !== undefined && thing !== null && isArray(thing) !== true) { 1154 | longest = _measureText(ctx, data, gc, longest, thing); 1155 | } else if (isArray(thing)) { 1156 | for (j = 0, jlen = thing.length; j < jlen; j++) { 1157 | nestedThing = thing[j]; 1158 | if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) { 1159 | longest = _measureText(ctx, data, gc, longest, nestedThing); 1160 | } 1161 | } 1162 | } 1163 | } 1164 | ctx.restore(); 1165 | const gcLen = gc.length / 2; 1166 | if (gcLen > arrayOfThings.length) { 1167 | for (i = 0; i < gcLen; i++) { 1168 | delete data[gc[i]]; 1169 | } 1170 | gc.splice(0, gcLen); 1171 | } 1172 | return longest; 1173 | } 1174 | function _alignPixel(chart, pixel, width) { 1175 | const devicePixelRatio = chart.currentDevicePixelRatio; 1176 | const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; 1177 | return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; 1178 | } 1179 | function clearCanvas(canvas, ctx) { 1180 | ctx = ctx || canvas.getContext('2d'); 1181 | ctx.save(); 1182 | ctx.resetTransform(); 1183 | ctx.clearRect(0, 0, canvas.width, canvas.height); 1184 | ctx.restore(); 1185 | } 1186 | function drawPoint(ctx, options, x, y) { 1187 | let type, xOffset, yOffset, size, cornerRadius; 1188 | const style = options.pointStyle; 1189 | const rotation = options.rotation; 1190 | const radius = options.radius; 1191 | let rad = (rotation || 0) * RAD_PER_DEG; 1192 | if (style && typeof style === 'object') { 1193 | type = style.toString(); 1194 | if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { 1195 | ctx.save(); 1196 | ctx.translate(x, y); 1197 | ctx.rotate(rad); 1198 | ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); 1199 | ctx.restore(); 1200 | return; 1201 | } 1202 | } 1203 | if (isNaN(radius) || radius <= 0) { 1204 | return; 1205 | } 1206 | ctx.beginPath(); 1207 | switch (style) { 1208 | default: 1209 | ctx.arc(x, y, radius, 0, TAU); 1210 | ctx.closePath(); 1211 | break; 1212 | case 'triangle': 1213 | ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); 1214 | rad += TWO_THIRDS_PI; 1215 | ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); 1216 | rad += TWO_THIRDS_PI; 1217 | ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); 1218 | ctx.closePath(); 1219 | break; 1220 | case 'rectRounded': 1221 | cornerRadius = radius * 0.516; 1222 | size = radius - cornerRadius; 1223 | xOffset = Math.cos(rad + QUARTER_PI) * size; 1224 | yOffset = Math.sin(rad + QUARTER_PI) * size; 1225 | ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); 1226 | ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); 1227 | ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); 1228 | ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); 1229 | ctx.closePath(); 1230 | break; 1231 | case 'rect': 1232 | if (!rotation) { 1233 | size = Math.SQRT1_2 * radius; 1234 | ctx.rect(x - size, y - size, 2 * size, 2 * size); 1235 | break; 1236 | } 1237 | rad += QUARTER_PI; 1238 | case 'rectRot': 1239 | xOffset = Math.cos(rad) * radius; 1240 | yOffset = Math.sin(rad) * radius; 1241 | ctx.moveTo(x - xOffset, y - yOffset); 1242 | ctx.lineTo(x + yOffset, y - xOffset); 1243 | ctx.lineTo(x + xOffset, y + yOffset); 1244 | ctx.lineTo(x - yOffset, y + xOffset); 1245 | ctx.closePath(); 1246 | break; 1247 | case 'crossRot': 1248 | rad += QUARTER_PI; 1249 | case 'cross': 1250 | xOffset = Math.cos(rad) * radius; 1251 | yOffset = Math.sin(rad) * radius; 1252 | ctx.moveTo(x - xOffset, y - yOffset); 1253 | ctx.lineTo(x + xOffset, y + yOffset); 1254 | ctx.moveTo(x + yOffset, y - xOffset); 1255 | ctx.lineTo(x - yOffset, y + xOffset); 1256 | break; 1257 | case 'star': 1258 | xOffset = Math.cos(rad) * radius; 1259 | yOffset = Math.sin(rad) * radius; 1260 | ctx.moveTo(x - xOffset, y - yOffset); 1261 | ctx.lineTo(x + xOffset, y + yOffset); 1262 | ctx.moveTo(x + yOffset, y - xOffset); 1263 | ctx.lineTo(x - yOffset, y + xOffset); 1264 | rad += QUARTER_PI; 1265 | xOffset = Math.cos(rad) * radius; 1266 | yOffset = Math.sin(rad) * radius; 1267 | ctx.moveTo(x - xOffset, y - yOffset); 1268 | ctx.lineTo(x + xOffset, y + yOffset); 1269 | ctx.moveTo(x + yOffset, y - xOffset); 1270 | ctx.lineTo(x - yOffset, y + xOffset); 1271 | break; 1272 | case 'line': 1273 | xOffset = Math.cos(rad) * radius; 1274 | yOffset = Math.sin(rad) * radius; 1275 | ctx.moveTo(x - xOffset, y - yOffset); 1276 | ctx.lineTo(x + xOffset, y + yOffset); 1277 | break; 1278 | case 'dash': 1279 | ctx.moveTo(x, y); 1280 | ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); 1281 | break; 1282 | } 1283 | ctx.fill(); 1284 | if (options.borderWidth > 0) { 1285 | ctx.stroke(); 1286 | } 1287 | } 1288 | function _isPointInArea(point, area, margin) { 1289 | margin = margin || 0.5; 1290 | return !area || (point && point.x > area.left - margin && point.x < area.right + margin && 1291 | point.y > area.top - margin && point.y < area.bottom + margin); 1292 | } 1293 | function clipArea(ctx, area) { 1294 | ctx.save(); 1295 | ctx.beginPath(); 1296 | ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); 1297 | ctx.clip(); 1298 | } 1299 | function unclipArea(ctx) { 1300 | ctx.restore(); 1301 | } 1302 | function _steppedLineTo(ctx, previous, target, flip, mode) { 1303 | if (!previous) { 1304 | return ctx.lineTo(target.x, target.y); 1305 | } 1306 | if (mode === 'middle') { 1307 | const midpoint = (previous.x + target.x) / 2.0; 1308 | ctx.lineTo(midpoint, previous.y); 1309 | ctx.lineTo(midpoint, target.y); 1310 | } else if (mode === 'after' !== !!flip) { 1311 | ctx.lineTo(previous.x, target.y); 1312 | } else { 1313 | ctx.lineTo(target.x, previous.y); 1314 | } 1315 | ctx.lineTo(target.x, target.y); 1316 | } 1317 | function _bezierCurveTo(ctx, previous, target, flip) { 1318 | if (!previous) { 1319 | return ctx.lineTo(target.x, target.y); 1320 | } 1321 | ctx.bezierCurveTo( 1322 | flip ? previous.cp1x : previous.cp2x, 1323 | flip ? previous.cp1y : previous.cp2y, 1324 | flip ? target.cp2x : target.cp1x, 1325 | flip ? target.cp2y : target.cp1y, 1326 | target.x, 1327 | target.y); 1328 | } 1329 | function renderText(ctx, text, x, y, font, opts = {}) { 1330 | const lines = isArray(text) ? text : [text]; 1331 | const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ''; 1332 | let i, line; 1333 | ctx.save(); 1334 | ctx.font = font.string; 1335 | setRenderOpts(ctx, opts); 1336 | for (i = 0; i < lines.length; ++i) { 1337 | line = lines[i]; 1338 | if (stroke) { 1339 | if (opts.strokeColor) { 1340 | ctx.strokeStyle = opts.strokeColor; 1341 | } 1342 | if (!isNullOrUndef(opts.strokeWidth)) { 1343 | ctx.lineWidth = opts.strokeWidth; 1344 | } 1345 | ctx.strokeText(line, x, y, opts.maxWidth); 1346 | } 1347 | ctx.fillText(line, x, y, opts.maxWidth); 1348 | decorateText(ctx, x, y, line, opts); 1349 | y += font.lineHeight; 1350 | } 1351 | ctx.restore(); 1352 | } 1353 | function setRenderOpts(ctx, opts) { 1354 | if (opts.translation) { 1355 | ctx.translate(opts.translation[0], opts.translation[1]); 1356 | } 1357 | if (!isNullOrUndef(opts.rotation)) { 1358 | ctx.rotate(opts.rotation); 1359 | } 1360 | if (opts.color) { 1361 | ctx.fillStyle = opts.color; 1362 | } 1363 | if (opts.textAlign) { 1364 | ctx.textAlign = opts.textAlign; 1365 | } 1366 | if (opts.textBaseline) { 1367 | ctx.textBaseline = opts.textBaseline; 1368 | } 1369 | } 1370 | function decorateText(ctx, x, y, line, opts) { 1371 | if (opts.strikethrough || opts.underline) { 1372 | const metrics = ctx.measureText(line); 1373 | const left = x - metrics.actualBoundingBoxLeft; 1374 | const right = x + metrics.actualBoundingBoxRight; 1375 | const top = y - metrics.actualBoundingBoxAscent; 1376 | const bottom = y + metrics.actualBoundingBoxDescent; 1377 | const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom; 1378 | ctx.strokeStyle = ctx.fillStyle; 1379 | ctx.beginPath(); 1380 | ctx.lineWidth = opts.decorationWidth || 2; 1381 | ctx.moveTo(left, yDecoration); 1382 | ctx.lineTo(right, yDecoration); 1383 | ctx.stroke(); 1384 | } 1385 | } 1386 | function addRoundedRectPath(ctx, rect) { 1387 | const {x, y, w, h, radius} = rect; 1388 | ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, -HALF_PI, PI, true); 1389 | ctx.lineTo(x, y + h - radius.bottomLeft); 1390 | ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true); 1391 | ctx.lineTo(x + w - radius.bottomRight, y + h); 1392 | ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true); 1393 | ctx.lineTo(x + w, y + radius.topRight); 1394 | ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true); 1395 | ctx.lineTo(x + radius.topLeft, y); 1396 | } 1397 | 1398 | const LINE_HEIGHT = new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); 1399 | const FONT_STYLE = new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/); 1400 | function toLineHeight(value, size) { 1401 | const matches = ('' + value).match(LINE_HEIGHT); 1402 | if (!matches || matches[1] === 'normal') { 1403 | return size * 1.2; 1404 | } 1405 | value = +matches[2]; 1406 | switch (matches[3]) { 1407 | case 'px': 1408 | return value; 1409 | case '%': 1410 | value /= 100; 1411 | break; 1412 | } 1413 | return size * value; 1414 | } 1415 | const numberOrZero = v => +v || 0; 1416 | function _readValueToProps(value, props) { 1417 | const ret = {}; 1418 | const objProps = isObject(props); 1419 | const keys = objProps ? Object.keys(props) : props; 1420 | const read = isObject(value) 1421 | ? objProps 1422 | ? prop => valueOrDefault(value[prop], value[props[prop]]) 1423 | : prop => value[prop] 1424 | : () => value; 1425 | for (const prop of keys) { 1426 | ret[prop] = numberOrZero(read(prop)); 1427 | } 1428 | return ret; 1429 | } 1430 | function toTRBL(value) { 1431 | return _readValueToProps(value, {top: 'y', right: 'x', bottom: 'y', left: 'x'}); 1432 | } 1433 | function toTRBLCorners(value) { 1434 | return _readValueToProps(value, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight']); 1435 | } 1436 | function toPadding(value) { 1437 | const obj = toTRBL(value); 1438 | obj.width = obj.left + obj.right; 1439 | obj.height = obj.top + obj.bottom; 1440 | return obj; 1441 | } 1442 | function toFont(options, fallback) { 1443 | options = options || {}; 1444 | fallback = fallback || defaults.font; 1445 | let size = valueOrDefault(options.size, fallback.size); 1446 | if (typeof size === 'string') { 1447 | size = parseInt(size, 10); 1448 | } 1449 | let style = valueOrDefault(options.style, fallback.style); 1450 | if (style && !('' + style).match(FONT_STYLE)) { 1451 | console.warn('Invalid font style specified: "' + style + '"'); 1452 | style = ''; 1453 | } 1454 | const font = { 1455 | family: valueOrDefault(options.family, fallback.family), 1456 | lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size), 1457 | size, 1458 | style, 1459 | weight: valueOrDefault(options.weight, fallback.weight), 1460 | string: '' 1461 | }; 1462 | font.string = toFontString(font); 1463 | return font; 1464 | } 1465 | function resolve(inputs, context, index, info) { 1466 | let cacheable = true; 1467 | let i, ilen, value; 1468 | for (i = 0, ilen = inputs.length; i < ilen; ++i) { 1469 | value = inputs[i]; 1470 | if (value === undefined) { 1471 | continue; 1472 | } 1473 | if (context !== undefined && typeof value === 'function') { 1474 | value = value(context); 1475 | cacheable = false; 1476 | } 1477 | if (index !== undefined && isArray(value)) { 1478 | value = value[index % value.length]; 1479 | cacheable = false; 1480 | } 1481 | if (value !== undefined) { 1482 | if (info && !cacheable) { 1483 | info.cacheable = false; 1484 | } 1485 | return value; 1486 | } 1487 | } 1488 | } 1489 | function _addGrace(minmax, grace, beginAtZero) { 1490 | const {min, max} = minmax; 1491 | const change = toDimension(grace, (max - min) / 2); 1492 | const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add; 1493 | return { 1494 | min: keepZero(min, -Math.abs(change)), 1495 | max: keepZero(max, change) 1496 | }; 1497 | } 1498 | function createContext(parentContext, context) { 1499 | return Object.assign(Object.create(parentContext), context); 1500 | } 1501 | 1502 | function _lookup(table, value, cmp) { 1503 | cmp = cmp || ((index) => table[index] < value); 1504 | let hi = table.length - 1; 1505 | let lo = 0; 1506 | let mid; 1507 | while (hi - lo > 1) { 1508 | mid = (lo + hi) >> 1; 1509 | if (cmp(mid)) { 1510 | lo = mid; 1511 | } else { 1512 | hi = mid; 1513 | } 1514 | } 1515 | return {lo, hi}; 1516 | } 1517 | const _lookupByKey = (table, key, value) => 1518 | _lookup(table, value, index => table[index][key] < value); 1519 | const _rlookupByKey = (table, key, value) => 1520 | _lookup(table, value, index => table[index][key] >= value); 1521 | function _filterBetween(values, min, max) { 1522 | let start = 0; 1523 | let end = values.length; 1524 | while (start < end && values[start] < min) { 1525 | start++; 1526 | } 1527 | while (end > start && values[end - 1] > max) { 1528 | end--; 1529 | } 1530 | return start > 0 || end < values.length 1531 | ? values.slice(start, end) 1532 | : values; 1533 | } 1534 | const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; 1535 | function listenArrayEvents(array, listener) { 1536 | if (array._chartjs) { 1537 | array._chartjs.listeners.push(listener); 1538 | return; 1539 | } 1540 | Object.defineProperty(array, '_chartjs', { 1541 | configurable: true, 1542 | enumerable: false, 1543 | value: { 1544 | listeners: [listener] 1545 | } 1546 | }); 1547 | arrayEvents.forEach((key) => { 1548 | const method = '_onData' + _capitalize(key); 1549 | const base = array[key]; 1550 | Object.defineProperty(array, key, { 1551 | configurable: true, 1552 | enumerable: false, 1553 | value(...args) { 1554 | const res = base.apply(this, args); 1555 | array._chartjs.listeners.forEach((object) => { 1556 | if (typeof object[method] === 'function') { 1557 | object[method](...args); 1558 | } 1559 | }); 1560 | return res; 1561 | } 1562 | }); 1563 | }); 1564 | } 1565 | function unlistenArrayEvents(array, listener) { 1566 | const stub = array._chartjs; 1567 | if (!stub) { 1568 | return; 1569 | } 1570 | const listeners = stub.listeners; 1571 | const index = listeners.indexOf(listener); 1572 | if (index !== -1) { 1573 | listeners.splice(index, 1); 1574 | } 1575 | if (listeners.length > 0) { 1576 | return; 1577 | } 1578 | arrayEvents.forEach((key) => { 1579 | delete array[key]; 1580 | }); 1581 | delete array._chartjs; 1582 | } 1583 | function _arrayUnique(items) { 1584 | const set = new Set(); 1585 | let i, ilen; 1586 | for (i = 0, ilen = items.length; i < ilen; ++i) { 1587 | set.add(items[i]); 1588 | } 1589 | if (set.size === ilen) { 1590 | return items; 1591 | } 1592 | return Array.from(set); 1593 | } 1594 | 1595 | function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback, getTarget = () => scopes[0]) { 1596 | if (!defined(fallback)) { 1597 | fallback = _resolve('_fallback', scopes); 1598 | } 1599 | const cache = { 1600 | [Symbol.toStringTag]: 'Object', 1601 | _cacheable: true, 1602 | _scopes: scopes, 1603 | _rootScopes: rootScopes, 1604 | _fallback: fallback, 1605 | _getTarget: getTarget, 1606 | override: (scope) => _createResolver([scope, ...scopes], prefixes, rootScopes, fallback), 1607 | }; 1608 | return new Proxy(cache, { 1609 | deleteProperty(target, prop) { 1610 | delete target[prop]; 1611 | delete target._keys; 1612 | delete scopes[0][prop]; 1613 | return true; 1614 | }, 1615 | get(target, prop) { 1616 | return _cached(target, prop, 1617 | () => _resolveWithPrefixes(prop, prefixes, scopes, target)); 1618 | }, 1619 | getOwnPropertyDescriptor(target, prop) { 1620 | return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop); 1621 | }, 1622 | getPrototypeOf() { 1623 | return Reflect.getPrototypeOf(scopes[0]); 1624 | }, 1625 | has(target, prop) { 1626 | return getKeysFromAllScopes(target).includes(prop); 1627 | }, 1628 | ownKeys(target) { 1629 | return getKeysFromAllScopes(target); 1630 | }, 1631 | set(target, prop, value) { 1632 | const storage = target._storage || (target._storage = getTarget()); 1633 | target[prop] = storage[prop] = value; 1634 | delete target._keys; 1635 | return true; 1636 | } 1637 | }); 1638 | } 1639 | function _attachContext(proxy, context, subProxy, descriptorDefaults) { 1640 | const cache = { 1641 | _cacheable: false, 1642 | _proxy: proxy, 1643 | _context: context, 1644 | _subProxy: subProxy, 1645 | _stack: new Set(), 1646 | _descriptors: _descriptors(proxy, descriptorDefaults), 1647 | setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults), 1648 | override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults) 1649 | }; 1650 | return new Proxy(cache, { 1651 | deleteProperty(target, prop) { 1652 | delete target[prop]; 1653 | delete proxy[prop]; 1654 | return true; 1655 | }, 1656 | get(target, prop, receiver) { 1657 | return _cached(target, prop, 1658 | () => _resolveWithContext(target, prop, receiver)); 1659 | }, 1660 | getOwnPropertyDescriptor(target, prop) { 1661 | return target._descriptors.allKeys 1662 | ? Reflect.has(proxy, prop) ? {enumerable: true, configurable: true} : undefined 1663 | : Reflect.getOwnPropertyDescriptor(proxy, prop); 1664 | }, 1665 | getPrototypeOf() { 1666 | return Reflect.getPrototypeOf(proxy); 1667 | }, 1668 | has(target, prop) { 1669 | return Reflect.has(proxy, prop); 1670 | }, 1671 | ownKeys() { 1672 | return Reflect.ownKeys(proxy); 1673 | }, 1674 | set(target, prop, value) { 1675 | proxy[prop] = value; 1676 | delete target[prop]; 1677 | return true; 1678 | } 1679 | }); 1680 | } 1681 | function _descriptors(proxy, defaults = {scriptable: true, indexable: true}) { 1682 | const {_scriptable = defaults.scriptable, _indexable = defaults.indexable, _allKeys = defaults.allKeys} = proxy; 1683 | return { 1684 | allKeys: _allKeys, 1685 | scriptable: _scriptable, 1686 | indexable: _indexable, 1687 | isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable, 1688 | isIndexable: isFunction(_indexable) ? _indexable : () => _indexable 1689 | }; 1690 | } 1691 | const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name; 1692 | const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters' && 1693 | (Object.getPrototypeOf(value) === null || value.constructor === Object); 1694 | function _cached(target, prop, resolve) { 1695 | if (Object.prototype.hasOwnProperty.call(target, prop)) { 1696 | return target[prop]; 1697 | } 1698 | const value = resolve(); 1699 | target[prop] = value; 1700 | return value; 1701 | } 1702 | function _resolveWithContext(target, prop, receiver) { 1703 | const {_proxy, _context, _subProxy, _descriptors: descriptors} = target; 1704 | let value = _proxy[prop]; 1705 | if (isFunction(value) && descriptors.isScriptable(prop)) { 1706 | value = _resolveScriptable(prop, value, target, receiver); 1707 | } 1708 | if (isArray(value) && value.length) { 1709 | value = _resolveArray(prop, value, target, descriptors.isIndexable); 1710 | } 1711 | if (needsSubResolver(prop, value)) { 1712 | value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors); 1713 | } 1714 | return value; 1715 | } 1716 | function _resolveScriptable(prop, value, target, receiver) { 1717 | const {_proxy, _context, _subProxy, _stack} = target; 1718 | if (_stack.has(prop)) { 1719 | throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop); 1720 | } 1721 | _stack.add(prop); 1722 | value = value(_context, _subProxy || receiver); 1723 | _stack.delete(prop); 1724 | if (needsSubResolver(prop, value)) { 1725 | value = createSubResolver(_proxy._scopes, _proxy, prop, value); 1726 | } 1727 | return value; 1728 | } 1729 | function _resolveArray(prop, value, target, isIndexable) { 1730 | const {_proxy, _context, _subProxy, _descriptors: descriptors} = target; 1731 | if (defined(_context.index) && isIndexable(prop)) { 1732 | value = value[_context.index % value.length]; 1733 | } else if (isObject(value[0])) { 1734 | const arr = value; 1735 | const scopes = _proxy._scopes.filter(s => s !== arr); 1736 | value = []; 1737 | for (const item of arr) { 1738 | const resolver = createSubResolver(scopes, _proxy, prop, item); 1739 | value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors)); 1740 | } 1741 | } 1742 | return value; 1743 | } 1744 | function resolveFallback(fallback, prop, value) { 1745 | return isFunction(fallback) ? fallback(prop, value) : fallback; 1746 | } 1747 | const getScope = (key, parent) => key === true ? parent 1748 | : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined; 1749 | function addScopes(set, parentScopes, key, parentFallback, value) { 1750 | for (const parent of parentScopes) { 1751 | const scope = getScope(key, parent); 1752 | if (scope) { 1753 | set.add(scope); 1754 | const fallback = resolveFallback(scope._fallback, key, value); 1755 | if (defined(fallback) && fallback !== key && fallback !== parentFallback) { 1756 | return fallback; 1757 | } 1758 | } else if (scope === false && defined(parentFallback) && key !== parentFallback) { 1759 | return null; 1760 | } 1761 | } 1762 | return false; 1763 | } 1764 | function createSubResolver(parentScopes, resolver, prop, value) { 1765 | const rootScopes = resolver._rootScopes; 1766 | const fallback = resolveFallback(resolver._fallback, prop, value); 1767 | const allScopes = [...parentScopes, ...rootScopes]; 1768 | const set = new Set(); 1769 | set.add(value); 1770 | let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value); 1771 | if (key === null) { 1772 | return false; 1773 | } 1774 | if (defined(fallback) && fallback !== prop) { 1775 | key = addScopesFromKey(set, allScopes, fallback, key, value); 1776 | if (key === null) { 1777 | return false; 1778 | } 1779 | } 1780 | return _createResolver(Array.from(set), [''], rootScopes, fallback, 1781 | () => subGetTarget(resolver, prop, value)); 1782 | } 1783 | function addScopesFromKey(set, allScopes, key, fallback, item) { 1784 | while (key) { 1785 | key = addScopes(set, allScopes, key, fallback, item); 1786 | } 1787 | return key; 1788 | } 1789 | function subGetTarget(resolver, prop, value) { 1790 | const parent = resolver._getTarget(); 1791 | if (!(prop in parent)) { 1792 | parent[prop] = {}; 1793 | } 1794 | const target = parent[prop]; 1795 | if (isArray(target) && isObject(value)) { 1796 | return value; 1797 | } 1798 | return target; 1799 | } 1800 | function _resolveWithPrefixes(prop, prefixes, scopes, proxy) { 1801 | let value; 1802 | for (const prefix of prefixes) { 1803 | value = _resolve(readKey(prefix, prop), scopes); 1804 | if (defined(value)) { 1805 | return needsSubResolver(prop, value) 1806 | ? createSubResolver(scopes, proxy, prop, value) 1807 | : value; 1808 | } 1809 | } 1810 | } 1811 | function _resolve(key, scopes) { 1812 | for (const scope of scopes) { 1813 | if (!scope) { 1814 | continue; 1815 | } 1816 | const value = scope[key]; 1817 | if (defined(value)) { 1818 | return value; 1819 | } 1820 | } 1821 | } 1822 | function getKeysFromAllScopes(target) { 1823 | let keys = target._keys; 1824 | if (!keys) { 1825 | keys = target._keys = resolveKeysFromAllScopes(target._scopes); 1826 | } 1827 | return keys; 1828 | } 1829 | function resolveKeysFromAllScopes(scopes) { 1830 | const set = new Set(); 1831 | for (const scope of scopes) { 1832 | for (const key of Object.keys(scope).filter(k => !k.startsWith('_'))) { 1833 | set.add(key); 1834 | } 1835 | } 1836 | return Array.from(set); 1837 | } 1838 | 1839 | const EPSILON = Number.EPSILON || 1e-14; 1840 | const getPoint = (points, i) => i < points.length && !points[i].skip && points[i]; 1841 | const getValueAxis = (indexAxis) => indexAxis === 'x' ? 'y' : 'x'; 1842 | function splineCurve(firstPoint, middlePoint, afterPoint, t) { 1843 | const previous = firstPoint.skip ? middlePoint : firstPoint; 1844 | const current = middlePoint; 1845 | const next = afterPoint.skip ? middlePoint : afterPoint; 1846 | const d01 = distanceBetweenPoints(current, previous); 1847 | const d12 = distanceBetweenPoints(next, current); 1848 | let s01 = d01 / (d01 + d12); 1849 | let s12 = d12 / (d01 + d12); 1850 | s01 = isNaN(s01) ? 0 : s01; 1851 | s12 = isNaN(s12) ? 0 : s12; 1852 | const fa = t * s01; 1853 | const fb = t * s12; 1854 | return { 1855 | previous: { 1856 | x: current.x - fa * (next.x - previous.x), 1857 | y: current.y - fa * (next.y - previous.y) 1858 | }, 1859 | next: { 1860 | x: current.x + fb * (next.x - previous.x), 1861 | y: current.y + fb * (next.y - previous.y) 1862 | } 1863 | }; 1864 | } 1865 | function monotoneAdjust(points, deltaK, mK) { 1866 | const pointsLen = points.length; 1867 | let alphaK, betaK, tauK, squaredMagnitude, pointCurrent; 1868 | let pointAfter = getPoint(points, 0); 1869 | for (let i = 0; i < pointsLen - 1; ++i) { 1870 | pointCurrent = pointAfter; 1871 | pointAfter = getPoint(points, i + 1); 1872 | if (!pointCurrent || !pointAfter) { 1873 | continue; 1874 | } 1875 | if (almostEquals(deltaK[i], 0, EPSILON)) { 1876 | mK[i] = mK[i + 1] = 0; 1877 | continue; 1878 | } 1879 | alphaK = mK[i] / deltaK[i]; 1880 | betaK = mK[i + 1] / deltaK[i]; 1881 | squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2); 1882 | if (squaredMagnitude <= 9) { 1883 | continue; 1884 | } 1885 | tauK = 3 / Math.sqrt(squaredMagnitude); 1886 | mK[i] = alphaK * tauK * deltaK[i]; 1887 | mK[i + 1] = betaK * tauK * deltaK[i]; 1888 | } 1889 | } 1890 | function monotoneCompute(points, mK, indexAxis = 'x') { 1891 | const valueAxis = getValueAxis(indexAxis); 1892 | const pointsLen = points.length; 1893 | let delta, pointBefore, pointCurrent; 1894 | let pointAfter = getPoint(points, 0); 1895 | for (let i = 0; i < pointsLen; ++i) { 1896 | pointBefore = pointCurrent; 1897 | pointCurrent = pointAfter; 1898 | pointAfter = getPoint(points, i + 1); 1899 | if (!pointCurrent) { 1900 | continue; 1901 | } 1902 | const iPixel = pointCurrent[indexAxis]; 1903 | const vPixel = pointCurrent[valueAxis]; 1904 | if (pointBefore) { 1905 | delta = (iPixel - pointBefore[indexAxis]) / 3; 1906 | pointCurrent[`cp1${indexAxis}`] = iPixel - delta; 1907 | pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i]; 1908 | } 1909 | if (pointAfter) { 1910 | delta = (pointAfter[indexAxis] - iPixel) / 3; 1911 | pointCurrent[`cp2${indexAxis}`] = iPixel + delta; 1912 | pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i]; 1913 | } 1914 | } 1915 | } 1916 | function splineCurveMonotone(points, indexAxis = 'x') { 1917 | const valueAxis = getValueAxis(indexAxis); 1918 | const pointsLen = points.length; 1919 | const deltaK = Array(pointsLen).fill(0); 1920 | const mK = Array(pointsLen); 1921 | let i, pointBefore, pointCurrent; 1922 | let pointAfter = getPoint(points, 0); 1923 | for (i = 0; i < pointsLen; ++i) { 1924 | pointBefore = pointCurrent; 1925 | pointCurrent = pointAfter; 1926 | pointAfter = getPoint(points, i + 1); 1927 | if (!pointCurrent) { 1928 | continue; 1929 | } 1930 | if (pointAfter) { 1931 | const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis]; 1932 | deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0; 1933 | } 1934 | mK[i] = !pointBefore ? deltaK[i] 1935 | : !pointAfter ? deltaK[i - 1] 1936 | : (sign(deltaK[i - 1]) !== sign(deltaK[i])) ? 0 1937 | : (deltaK[i - 1] + deltaK[i]) / 2; 1938 | } 1939 | monotoneAdjust(points, deltaK, mK); 1940 | monotoneCompute(points, mK, indexAxis); 1941 | } 1942 | function capControlPoint(pt, min, max) { 1943 | return Math.max(Math.min(pt, max), min); 1944 | } 1945 | function capBezierPoints(points, area) { 1946 | let i, ilen, point, inArea, inAreaPrev; 1947 | let inAreaNext = _isPointInArea(points[0], area); 1948 | for (i = 0, ilen = points.length; i < ilen; ++i) { 1949 | inAreaPrev = inArea; 1950 | inArea = inAreaNext; 1951 | inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area); 1952 | if (!inArea) { 1953 | continue; 1954 | } 1955 | point = points[i]; 1956 | if (inAreaPrev) { 1957 | point.cp1x = capControlPoint(point.cp1x, area.left, area.right); 1958 | point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom); 1959 | } 1960 | if (inAreaNext) { 1961 | point.cp2x = capControlPoint(point.cp2x, area.left, area.right); 1962 | point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom); 1963 | } 1964 | } 1965 | } 1966 | function _updateBezierControlPoints(points, options, area, loop, indexAxis) { 1967 | let i, ilen, point, controlPoints; 1968 | if (options.spanGaps) { 1969 | points = points.filter((pt) => !pt.skip); 1970 | } 1971 | if (options.cubicInterpolationMode === 'monotone') { 1972 | splineCurveMonotone(points, indexAxis); 1973 | } else { 1974 | let prev = loop ? points[points.length - 1] : points[0]; 1975 | for (i = 0, ilen = points.length; i < ilen; ++i) { 1976 | point = points[i]; 1977 | controlPoints = splineCurve( 1978 | prev, 1979 | point, 1980 | points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen], 1981 | options.tension 1982 | ); 1983 | point.cp1x = controlPoints.previous.x; 1984 | point.cp1y = controlPoints.previous.y; 1985 | point.cp2x = controlPoints.next.x; 1986 | point.cp2y = controlPoints.next.y; 1987 | prev = point; 1988 | } 1989 | } 1990 | if (options.capBezierPoints) { 1991 | capBezierPoints(points, area); 1992 | } 1993 | } 1994 | 1995 | function _isDomSupported() { 1996 | return typeof window !== 'undefined' && typeof document !== 'undefined'; 1997 | } 1998 | function _getParentNode(domNode) { 1999 | let parent = domNode.parentNode; 2000 | if (parent && parent.toString() === '[object ShadowRoot]') { 2001 | parent = parent.host; 2002 | } 2003 | return parent; 2004 | } 2005 | function parseMaxStyle(styleValue, node, parentProperty) { 2006 | let valueInPixels; 2007 | if (typeof styleValue === 'string') { 2008 | valueInPixels = parseInt(styleValue, 10); 2009 | if (styleValue.indexOf('%') !== -1) { 2010 | valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; 2011 | } 2012 | } else { 2013 | valueInPixels = styleValue; 2014 | } 2015 | return valueInPixels; 2016 | } 2017 | const getComputedStyle = (element) => window.getComputedStyle(element, null); 2018 | function getStyle(el, property) { 2019 | return getComputedStyle(el).getPropertyValue(property); 2020 | } 2021 | const positions = ['top', 'right', 'bottom', 'left']; 2022 | function getPositionedStyle(styles, style, suffix) { 2023 | const result = {}; 2024 | suffix = suffix ? '-' + suffix : ''; 2025 | for (let i = 0; i < 4; i++) { 2026 | const pos = positions[i]; 2027 | result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0; 2028 | } 2029 | result.width = result.left + result.right; 2030 | result.height = result.top + result.bottom; 2031 | return result; 2032 | } 2033 | const useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot); 2034 | function getCanvasPosition(evt, canvas) { 2035 | const e = evt.native || evt; 2036 | const touches = e.touches; 2037 | const source = touches && touches.length ? touches[0] : e; 2038 | const {offsetX, offsetY} = source; 2039 | let box = false; 2040 | let x, y; 2041 | if (useOffsetPos(offsetX, offsetY, e.target)) { 2042 | x = offsetX; 2043 | y = offsetY; 2044 | } else { 2045 | const rect = canvas.getBoundingClientRect(); 2046 | x = source.clientX - rect.left; 2047 | y = source.clientY - rect.top; 2048 | box = true; 2049 | } 2050 | return {x, y, box}; 2051 | } 2052 | function getRelativePosition(evt, chart) { 2053 | const {canvas, currentDevicePixelRatio} = chart; 2054 | const style = getComputedStyle(canvas); 2055 | const borderBox = style.boxSizing === 'border-box'; 2056 | const paddings = getPositionedStyle(style, 'padding'); 2057 | const borders = getPositionedStyle(style, 'border', 'width'); 2058 | const {x, y, box} = getCanvasPosition(evt, canvas); 2059 | const xOffset = paddings.left + (box && borders.left); 2060 | const yOffset = paddings.top + (box && borders.top); 2061 | let {width, height} = chart; 2062 | if (borderBox) { 2063 | width -= paddings.width + borders.width; 2064 | height -= paddings.height + borders.height; 2065 | } 2066 | return { 2067 | x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio), 2068 | y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio) 2069 | }; 2070 | } 2071 | function getContainerSize(canvas, width, height) { 2072 | let maxWidth, maxHeight; 2073 | if (width === undefined || height === undefined) { 2074 | const container = _getParentNode(canvas); 2075 | if (!container) { 2076 | width = canvas.clientWidth; 2077 | height = canvas.clientHeight; 2078 | } else { 2079 | const rect = container.getBoundingClientRect(); 2080 | const containerStyle = getComputedStyle(container); 2081 | const containerBorder = getPositionedStyle(containerStyle, 'border', 'width'); 2082 | const containerPadding = getPositionedStyle(containerStyle, 'padding'); 2083 | width = rect.width - containerPadding.width - containerBorder.width; 2084 | height = rect.height - containerPadding.height - containerBorder.height; 2085 | maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth'); 2086 | maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight'); 2087 | } 2088 | } 2089 | return { 2090 | width, 2091 | height, 2092 | maxWidth: maxWidth || INFINITY, 2093 | maxHeight: maxHeight || INFINITY 2094 | }; 2095 | } 2096 | const round1 = v => Math.round(v * 10) / 10; 2097 | function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) { 2098 | const style = getComputedStyle(canvas); 2099 | const margins = getPositionedStyle(style, 'margin'); 2100 | const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY; 2101 | const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY; 2102 | const containerSize = getContainerSize(canvas, bbWidth, bbHeight); 2103 | let {width, height} = containerSize; 2104 | if (style.boxSizing === 'content-box') { 2105 | const borders = getPositionedStyle(style, 'border', 'width'); 2106 | const paddings = getPositionedStyle(style, 'padding'); 2107 | width -= paddings.width + borders.width; 2108 | height -= paddings.height + borders.height; 2109 | } 2110 | width = Math.max(0, width - margins.width); 2111 | height = Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height - margins.height); 2112 | width = round1(Math.min(width, maxWidth, containerSize.maxWidth)); 2113 | height = round1(Math.min(height, maxHeight, containerSize.maxHeight)); 2114 | if (width && !height) { 2115 | height = round1(width / 2); 2116 | } 2117 | return { 2118 | width, 2119 | height 2120 | }; 2121 | } 2122 | function retinaScale(chart, forceRatio, forceStyle) { 2123 | const pixelRatio = forceRatio || 1; 2124 | const deviceHeight = Math.floor(chart.height * pixelRatio); 2125 | const deviceWidth = Math.floor(chart.width * pixelRatio); 2126 | chart.height = deviceHeight / pixelRatio; 2127 | chart.width = deviceWidth / pixelRatio; 2128 | const canvas = chart.canvas; 2129 | if (canvas.style && (forceStyle || (!canvas.style.height && !canvas.style.width))) { 2130 | canvas.style.height = `${chart.height}px`; 2131 | canvas.style.width = `${chart.width}px`; 2132 | } 2133 | if (chart.currentDevicePixelRatio !== pixelRatio 2134 | || canvas.height !== deviceHeight 2135 | || canvas.width !== deviceWidth) { 2136 | chart.currentDevicePixelRatio = pixelRatio; 2137 | canvas.height = deviceHeight; 2138 | canvas.width = deviceWidth; 2139 | chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); 2140 | return true; 2141 | } 2142 | return false; 2143 | } 2144 | const supportsEventListenerOptions = (function() { 2145 | let passiveSupported = false; 2146 | try { 2147 | const options = { 2148 | get passive() { 2149 | passiveSupported = true; 2150 | return false; 2151 | } 2152 | }; 2153 | window.addEventListener('test', null, options); 2154 | window.removeEventListener('test', null, options); 2155 | } catch (e) { 2156 | } 2157 | return passiveSupported; 2158 | }()); 2159 | function readUsedSize(element, property) { 2160 | const value = getStyle(element, property); 2161 | const matches = value && value.match(/^(\d+)(\.\d+)?px$/); 2162 | return matches ? +matches[1] : undefined; 2163 | } 2164 | 2165 | function _pointInLine(p1, p2, t, mode) { 2166 | return { 2167 | x: p1.x + t * (p2.x - p1.x), 2168 | y: p1.y + t * (p2.y - p1.y) 2169 | }; 2170 | } 2171 | function _steppedInterpolation(p1, p2, t, mode) { 2172 | return { 2173 | x: p1.x + t * (p2.x - p1.x), 2174 | y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y 2175 | : mode === 'after' ? t < 1 ? p1.y : p2.y 2176 | : t > 0 ? p2.y : p1.y 2177 | }; 2178 | } 2179 | function _bezierInterpolation(p1, p2, t, mode) { 2180 | const cp1 = {x: p1.cp2x, y: p1.cp2y}; 2181 | const cp2 = {x: p2.cp1x, y: p2.cp1y}; 2182 | const a = _pointInLine(p1, cp1, t); 2183 | const b = _pointInLine(cp1, cp2, t); 2184 | const c = _pointInLine(cp2, p2, t); 2185 | const d = _pointInLine(a, b, t); 2186 | const e = _pointInLine(b, c, t); 2187 | return _pointInLine(d, e, t); 2188 | } 2189 | 2190 | const intlCache = new Map(); 2191 | function getNumberFormat(locale, options) { 2192 | options = options || {}; 2193 | const cacheKey = locale + JSON.stringify(options); 2194 | let formatter = intlCache.get(cacheKey); 2195 | if (!formatter) { 2196 | formatter = new Intl.NumberFormat(locale, options); 2197 | intlCache.set(cacheKey, formatter); 2198 | } 2199 | return formatter; 2200 | } 2201 | function formatNumber(num, locale, options) { 2202 | return getNumberFormat(locale, options).format(num); 2203 | } 2204 | 2205 | const getRightToLeftAdapter = function(rectX, width) { 2206 | return { 2207 | x(x) { 2208 | return rectX + rectX + width - x; 2209 | }, 2210 | setWidth(w) { 2211 | width = w; 2212 | }, 2213 | textAlign(align) { 2214 | if (align === 'center') { 2215 | return align; 2216 | } 2217 | return align === 'right' ? 'left' : 'right'; 2218 | }, 2219 | xPlus(x, value) { 2220 | return x - value; 2221 | }, 2222 | leftForLtr(x, itemWidth) { 2223 | return x - itemWidth; 2224 | }, 2225 | }; 2226 | }; 2227 | const getLeftToRightAdapter = function() { 2228 | return { 2229 | x(x) { 2230 | return x; 2231 | }, 2232 | setWidth(w) { 2233 | }, 2234 | textAlign(align) { 2235 | return align; 2236 | }, 2237 | xPlus(x, value) { 2238 | return x + value; 2239 | }, 2240 | leftForLtr(x, _itemWidth) { 2241 | return x; 2242 | }, 2243 | }; 2244 | }; 2245 | function getRtlAdapter(rtl, rectX, width) { 2246 | return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter(); 2247 | } 2248 | function overrideTextDirection(ctx, direction) { 2249 | let style, original; 2250 | if (direction === 'ltr' || direction === 'rtl') { 2251 | style = ctx.canvas.style; 2252 | original = [ 2253 | style.getPropertyValue('direction'), 2254 | style.getPropertyPriority('direction'), 2255 | ]; 2256 | style.setProperty('direction', direction, 'important'); 2257 | ctx.prevTextDirection = original; 2258 | } 2259 | } 2260 | function restoreTextDirection(ctx, original) { 2261 | if (original !== undefined) { 2262 | delete ctx.prevTextDirection; 2263 | ctx.canvas.style.setProperty('direction', original[0], original[1]); 2264 | } 2265 | } 2266 | 2267 | function propertyFn(property) { 2268 | if (property === 'angle') { 2269 | return { 2270 | between: _angleBetween, 2271 | compare: _angleDiff, 2272 | normalize: _normalizeAngle, 2273 | }; 2274 | } 2275 | return { 2276 | between: _isBetween, 2277 | compare: (a, b) => a - b, 2278 | normalize: x => x 2279 | }; 2280 | } 2281 | function normalizeSegment({start, end, count, loop, style}) { 2282 | return { 2283 | start: start % count, 2284 | end: end % count, 2285 | loop: loop && (end - start + 1) % count === 0, 2286 | style 2287 | }; 2288 | } 2289 | function getSegment(segment, points, bounds) { 2290 | const {property, start: startBound, end: endBound} = bounds; 2291 | const {between, normalize} = propertyFn(property); 2292 | const count = points.length; 2293 | let {start, end, loop} = segment; 2294 | let i, ilen; 2295 | if (loop) { 2296 | start += count; 2297 | end += count; 2298 | for (i = 0, ilen = count; i < ilen; ++i) { 2299 | if (!between(normalize(points[start % count][property]), startBound, endBound)) { 2300 | break; 2301 | } 2302 | start--; 2303 | end--; 2304 | } 2305 | start %= count; 2306 | end %= count; 2307 | } 2308 | if (end < start) { 2309 | end += count; 2310 | } 2311 | return {start, end, loop, style: segment.style}; 2312 | } 2313 | function _boundSegment(segment, points, bounds) { 2314 | if (!bounds) { 2315 | return [segment]; 2316 | } 2317 | const {property, start: startBound, end: endBound} = bounds; 2318 | const count = points.length; 2319 | const {compare, between, normalize} = propertyFn(property); 2320 | const {start, end, loop, style} = getSegment(segment, points, bounds); 2321 | const result = []; 2322 | let inside = false; 2323 | let subStart = null; 2324 | let value, point, prevValue; 2325 | const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0; 2326 | const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value); 2327 | const shouldStart = () => inside || startIsBefore(); 2328 | const shouldStop = () => !inside || endIsBefore(); 2329 | for (let i = start, prev = start; i <= end; ++i) { 2330 | point = points[i % count]; 2331 | if (point.skip) { 2332 | continue; 2333 | } 2334 | value = normalize(point[property]); 2335 | if (value === prevValue) { 2336 | continue; 2337 | } 2338 | inside = between(value, startBound, endBound); 2339 | if (subStart === null && shouldStart()) { 2340 | subStart = compare(value, startBound) === 0 ? i : prev; 2341 | } 2342 | if (subStart !== null && shouldStop()) { 2343 | result.push(normalizeSegment({start: subStart, end: i, loop, count, style})); 2344 | subStart = null; 2345 | } 2346 | prev = i; 2347 | prevValue = value; 2348 | } 2349 | if (subStart !== null) { 2350 | result.push(normalizeSegment({start: subStart, end, loop, count, style})); 2351 | } 2352 | return result; 2353 | } 2354 | function _boundSegments(line, bounds) { 2355 | const result = []; 2356 | const segments = line.segments; 2357 | for (let i = 0; i < segments.length; i++) { 2358 | const sub = _boundSegment(segments[i], line.points, bounds); 2359 | if (sub.length) { 2360 | result.push(...sub); 2361 | } 2362 | } 2363 | return result; 2364 | } 2365 | function findStartAndEnd(points, count, loop, spanGaps) { 2366 | let start = 0; 2367 | let end = count - 1; 2368 | if (loop && !spanGaps) { 2369 | while (start < count && !points[start].skip) { 2370 | start++; 2371 | } 2372 | } 2373 | while (start < count && points[start].skip) { 2374 | start++; 2375 | } 2376 | start %= count; 2377 | if (loop) { 2378 | end += start; 2379 | } 2380 | while (end > start && points[end % count].skip) { 2381 | end--; 2382 | } 2383 | end %= count; 2384 | return {start, end}; 2385 | } 2386 | function solidSegments(points, start, max, loop) { 2387 | const count = points.length; 2388 | const result = []; 2389 | let last = start; 2390 | let prev = points[start]; 2391 | let end; 2392 | for (end = start + 1; end <= max; ++end) { 2393 | const cur = points[end % count]; 2394 | if (cur.skip || cur.stop) { 2395 | if (!prev.skip) { 2396 | loop = false; 2397 | result.push({start: start % count, end: (end - 1) % count, loop}); 2398 | start = last = cur.stop ? end : null; 2399 | } 2400 | } else { 2401 | last = end; 2402 | if (prev.skip) { 2403 | start = end; 2404 | } 2405 | } 2406 | prev = cur; 2407 | } 2408 | if (last !== null) { 2409 | result.push({start: start % count, end: last % count, loop}); 2410 | } 2411 | return result; 2412 | } 2413 | function _computeSegments(line, segmentOptions) { 2414 | const points = line.points; 2415 | const spanGaps = line.options.spanGaps; 2416 | const count = points.length; 2417 | if (!count) { 2418 | return []; 2419 | } 2420 | const loop = !!line._loop; 2421 | const {start, end} = findStartAndEnd(points, count, loop, spanGaps); 2422 | if (spanGaps === true) { 2423 | return splitByStyles(line, [{start, end, loop}], points, segmentOptions); 2424 | } 2425 | const max = end < start ? end + count : end; 2426 | const completeLoop = !!line._fullLoop && start === 0 && end === count - 1; 2427 | return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions); 2428 | } 2429 | function splitByStyles(line, segments, points, segmentOptions) { 2430 | if (!segmentOptions || !segmentOptions.setContext || !points) { 2431 | return segments; 2432 | } 2433 | return doSplitByStyles(line, segments, points, segmentOptions); 2434 | } 2435 | function doSplitByStyles(line, segments, points, segmentOptions) { 2436 | const chartContext = line._chart.getContext(); 2437 | const baseStyle = readStyle(line.options); 2438 | const {_datasetIndex: datasetIndex, options: {spanGaps}} = line; 2439 | const count = points.length; 2440 | const result = []; 2441 | let prevStyle = baseStyle; 2442 | let start = segments[0].start; 2443 | let i = start; 2444 | function addStyle(s, e, l, st) { 2445 | const dir = spanGaps ? -1 : 1; 2446 | if (s === e) { 2447 | return; 2448 | } 2449 | s += count; 2450 | while (points[s % count].skip) { 2451 | s -= dir; 2452 | } 2453 | while (points[e % count].skip) { 2454 | e += dir; 2455 | } 2456 | if (s % count !== e % count) { 2457 | result.push({start: s % count, end: e % count, loop: l, style: st}); 2458 | prevStyle = st; 2459 | start = e % count; 2460 | } 2461 | } 2462 | for (const segment of segments) { 2463 | start = spanGaps ? start : segment.start; 2464 | let prev = points[start % count]; 2465 | let style; 2466 | for (i = start + 1; i <= segment.end; i++) { 2467 | const pt = points[i % count]; 2468 | style = readStyle(segmentOptions.setContext(createContext(chartContext, { 2469 | type: 'segment', 2470 | p0: prev, 2471 | p1: pt, 2472 | p0DataIndex: (i - 1) % count, 2473 | p1DataIndex: i % count, 2474 | datasetIndex 2475 | }))); 2476 | if (styleChanged(style, prevStyle)) { 2477 | addStyle(start, i - 1, segment.loop, prevStyle); 2478 | } 2479 | prev = pt; 2480 | prevStyle = style; 2481 | } 2482 | if (start < i - 1) { 2483 | addStyle(start, i - 1, segment.loop, prevStyle); 2484 | } 2485 | } 2486 | return result; 2487 | } 2488 | function readStyle(options) { 2489 | return { 2490 | backgroundColor: options.backgroundColor, 2491 | borderCapStyle: options.borderCapStyle, 2492 | borderDash: options.borderDash, 2493 | borderDashOffset: options.borderDashOffset, 2494 | borderJoinStyle: options.borderJoinStyle, 2495 | borderWidth: options.borderWidth, 2496 | borderColor: options.borderColor 2497 | }; 2498 | } 2499 | function styleChanged(style, prevStyle) { 2500 | return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle); 2501 | } 2502 | 2503 | export { _toLeftRightCenter as $, _rlookupByKey as A, getAngleFromPoint as B, toPadding as C, each as D, getMaximumSize as E, _getParentNode as F, readUsedSize as G, HALF_PI as H, throttled as I, supportsEventListenerOptions as J, _isDomSupported as K, log10 as L, _factorize as M, finiteOrDefault as N, callback as O, PI as P, _addGrace as Q, toDegrees as R, _measureText as S, TAU as T, _int16Range as U, _alignPixel as V, clipArea as W, renderText as X, unclipArea as Y, toFont as Z, _arrayUnique as _, resolve as a, _angleDiff as a$, _alignStartEnd as a0, overrides as a1, merge as a2, _capitalize as a3, descriptors as a4, isFunction as a5, _attachContext as a6, _createResolver as a7, _descriptors as a8, mergeIf as a9, restoreTextDirection as aA, noop as aB, distanceBetweenPoints as aC, _setMinAndMaxByKey as aD, niceNum as aE, almostWhole as aF, almostEquals as aG, _decimalPlaces as aH, _longestText as aI, _filterBetween as aJ, _lookup as aK, getHoverColor as aL, clone$1 as aM, _merger as aN, _mergerIf as aO, _deprecated as aP, toFontString as aQ, splineCurve as aR, splineCurveMonotone as aS, getStyle as aT, fontString as aU, toLineHeight as aV, PITAU as aW, INFINITY as aX, RAD_PER_DEG as aY, QUARTER_PI as aZ, TWO_THIRDS_PI as a_, uid as aa, debounce as ab, retinaScale as ac, clearCanvas as ad, setsEqual as ae, _elementsEqual as af, _isClickEvent as ag, _isBetween as ah, _readValueToProps as ai, _updateBezierControlPoints as aj, _computeSegments as ak, _boundSegments as al, _steppedInterpolation as am, _bezierInterpolation as an, _pointInLine as ao, _steppedLineTo as ap, _bezierCurveTo as aq, drawPoint as ar, addRoundedRectPath as as, toTRBL as at, toTRBLCorners as au, _boundSegment as av, _normalizeAngle as aw, getRtlAdapter as ax, overrideTextDirection as ay, _textX as az, isArray as b, color as c, defaults as d, effects as e, resolveObjectKey as f, isNumberFinite as g, createContext as h, isObject as i, defined as j, isNullOrUndef as k, listenArrayEvents as l, toPercentage as m, toDimension as n, formatNumber as o, _angleBetween as p, isNumber as q, requestAnimFrame as r, sign as s, toRadians as t, unlistenArrayEvents as u, valueOrDefault as v, _limitValue as w, _lookupByKey as x, getRelativePosition as y, _isPointInArea as z }; 2504 | -------------------------------------------------------------------------------- /src/views/js/chart.js/dist/helpers.esm.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Chart.js v3.7.1 3 | * https://www.chartjs.org 4 | * (c) 2022 Chart.js Contributors 5 | * Released under the MIT License 6 | */ 7 | export { H as HALF_PI, aX as INFINITY, P as PI, aW as PITAU, aZ as QUARTER_PI, aY as RAD_PER_DEG, T as TAU, a_ as TWO_THIRDS_PI, Q as _addGrace, V as _alignPixel, a0 as _alignStartEnd, p as _angleBetween, a$ as _angleDiff, _ as _arrayUnique, a6 as _attachContext, aq as _bezierCurveTo, an as _bezierInterpolation, av as _boundSegment, al as _boundSegments, a3 as _capitalize, ak as _computeSegments, a7 as _createResolver, aH as _decimalPlaces, aP as _deprecated, a8 as _descriptors, af as _elementsEqual, M as _factorize, aJ as _filterBetween, F as _getParentNode, U as _int16Range, ah as _isBetween, ag as _isClickEvent, K as _isDomSupported, z as _isPointInArea, w as _limitValue, aI as _longestText, aK as _lookup, x as _lookupByKey, S as _measureText, aN as _merger, aO as _mergerIf, aw as _normalizeAngle, ao as _pointInLine, ai as _readValueToProps, A as _rlookupByKey, aD as _setMinAndMaxByKey, am as _steppedInterpolation, ap as _steppedLineTo, az as _textX, $ as _toLeftRightCenter, aj as _updateBezierControlPoints, as as addRoundedRectPath, aG as almostEquals, aF as almostWhole, O as callback, ad as clearCanvas, W as clipArea, aM as clone, c as color, h as createContext, ab as debounce, j as defined, aC as distanceBetweenPoints, ar as drawPoint, D as each, e as easingEffects, N as finiteOrDefault, aU as fontString, o as formatNumber, B as getAngleFromPoint, aL as getHoverColor, E as getMaximumSize, y as getRelativePosition, ax as getRtlAdapter, aT as getStyle, b as isArray, g as isFinite, a5 as isFunction, k as isNullOrUndef, q as isNumber, i as isObject, l as listenArrayEvents, L as log10, a2 as merge, a9 as mergeIf, aE as niceNum, aB as noop, ay as overrideTextDirection, G as readUsedSize, X as renderText, r as requestAnimFrame, a as resolve, f as resolveObjectKey, aA as restoreTextDirection, ac as retinaScale, ae as setsEqual, s as sign, aR as splineCurve, aS as splineCurveMonotone, J as supportsEventListenerOptions, I as throttled, R as toDegrees, n as toDimension, Z as toFont, aQ as toFontString, aV as toLineHeight, C as toPadding, m as toPercentage, t as toRadians, at as toTRBL, au as toTRBLCorners, aa as uid, Y as unclipArea, u as unlistenArrayEvents, v as valueOrDefault } from './chunks/helpers.segment.js'; 8 | -------------------------------------------------------------------------------- /src/views/js/chart.js/helpers/helpers.esm.d.ts: -------------------------------------------------------------------------------- 1 | export * from '../types/helpers'; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/helpers/helpers.esm.js: -------------------------------------------------------------------------------- 1 | export * from '../dist/helpers.esm'; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/helpers/helpers.js: -------------------------------------------------------------------------------- 1 | module.exports = require('..').helpers; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/helpers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js-helpers", 3 | "private": true, 4 | "description": "helper package", 5 | "main": "helpers.js", 6 | "module": "helpers.esm.js", 7 | "types": "helpers.esm.d.ts" 8 | } -------------------------------------------------------------------------------- /src/views/js/chart.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js", 3 | "homepage": "https://www.chartjs.org", 4 | "description": "Simple HTML5 charts using the canvas element.", 5 | "version": "3.7.1", 6 | "license": "MIT", 7 | "jsdelivr": "dist/chart.min.js", 8 | "unpkg": "dist/chart.min.js", 9 | "main": "dist/chart.js", 10 | "module": "dist/chart.esm.js", 11 | "types": "types/index.esm.d.ts", 12 | "keywords": [ 13 | "canvas", 14 | "charts", 15 | "data", 16 | "graphs", 17 | "html5", 18 | "responsive" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/chartjs/Chart.js.git" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/chartjs/Chart.js/issues" 26 | }, 27 | "files": [ 28 | "auto/**/*.js", 29 | "auto/**/*.d.ts", 30 | "dist/*.js", 31 | "dist/chunks/*.js", 32 | "types/*.d.ts", 33 | "types/helpers/*.d.ts", 34 | "helpers/**/*.js", 35 | "helpers/**/*.d.ts" 36 | ], 37 | "scripts": { 38 | "autobuild": "rollup -c -w", 39 | "build": "rollup -c", 40 | "dev": "karma start --auto-watch --no-single-run --browsers chrome --grep", 41 | "dev:ff": "karma start --auto-watch --no-single-run --browsers firefox --grep", 42 | "docs": "npm run build && vuepress build docs --no-cache", 43 | "docs:dev": "npm run build && vuepress dev docs --no-cache", 44 | "lint-js": "eslint \"src/**/*.js\" \"test/**/*.js\" \"docs/**/*.js\"", 45 | "lint-md": "eslint \"**/*.md\"", 46 | "lint-tsc": "tsc", 47 | "lint-types": "eslint \"types/**/*.ts\" && node -r esm types/tests/autogen.js && tsc -p types/tests/", 48 | "lint": "concurrently \"npm:lint-*\"", 49 | "test": "npm run lint && cross-env NODE_ENV=test karma start --auto-watch --single-run --coverage --grep" 50 | }, 51 | "devDependencies": { 52 | "@kurkle/color": "^0.1.9", 53 | "@rollup/plugin-commonjs": "^21.0.1", 54 | "@rollup/plugin-inject": "^4.0.2", 55 | "@rollup/plugin-json": "^4.1.0", 56 | "@rollup/plugin-node-resolve": "^13.0.0", 57 | "@simonbrunel/vuepress-plugin-versions": "^0.2.0", 58 | "@types/offscreencanvas": "^2019.6.4", 59 | "@typescript-eslint/eslint-plugin": "^5.8.0", 60 | "@typescript-eslint/parser": "^5.8.0", 61 | "@vuepress/plugin-google-analytics": "^1.8.3", 62 | "@vuepress/plugin-html-redirect": "^0.1.2", 63 | "chartjs-adapter-luxon": "^1.0.0", 64 | "chartjs-adapter-moment": "^1.0.0", 65 | "chartjs-test-utils": "^0.3.1", 66 | "concurrently": "^6.0.1", 67 | "coveralls": "^3.1.0", 68 | "cross-env": "^7.0.3", 69 | "eslint": "^8.5.0", 70 | "eslint-config-chartjs": "^0.3.0", 71 | "eslint-plugin-es": "^4.1.0", 72 | "eslint-plugin-html": "^6.1.2", 73 | "eslint-plugin-markdown": "^2.2.1", 74 | "esm": "^3.2.25", 75 | "glob": "^7.1.6", 76 | "jasmine": "^3.7.0", 77 | "jasmine-core": "^3.7.1", 78 | "karma": "^6.3.2", 79 | "karma-chrome-launcher": "^3.1.0", 80 | "karma-coverage": "^2.0.3", 81 | "karma-edge-launcher": "^0.4.2", 82 | "karma-firefox-launcher": "^2.1.0", 83 | "karma-jasmine": "^4.0.1", 84 | "karma-jasmine-html-reporter": "^1.5.4", 85 | "karma-rollup-preprocessor": "^7.0.7", 86 | "karma-safari-private-launcher": "^1.0.0", 87 | "karma-spec-reporter": "0.0.32", 88 | "luxon": "^2.2.0", 89 | "markdown-it-include": "^2.0.0", 90 | "moment": "^2.29.1", 91 | "moment-timezone": "^0.5.34", 92 | "pixelmatch": "^5.2.1", 93 | "rollup": "^2.44.0", 94 | "rollup-plugin-analyzer": "^4.0.0", 95 | "rollup-plugin-cleanup": "^3.2.1", 96 | "rollup-plugin-istanbul": "^3.0.0", 97 | "rollup-plugin-terser": "^7.0.2", 98 | "typedoc": "^0.22.10", 99 | "typedoc-plugin-markdown": "^3.6.1", 100 | "typescript": "^4.3.5", 101 | "vue-tabs-component": "^1.5.0", 102 | "vuepress": "^1.8.2", 103 | "vuepress-plugin-code-copy": "^1.0.6", 104 | "vuepress-plugin-flexsearch": "^0.3.0", 105 | "vuepress-plugin-redirect": "^1.2.5", 106 | "vuepress-plugin-tabs": "^0.3.0", 107 | "vuepress-plugin-typedoc": "^0.10.0", 108 | "vuepress-theme-chartjs": "^0.2.0", 109 | "yargs": "^17.0.1" 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/adapters.d.ts: -------------------------------------------------------------------------------- 1 | export type TimeUnit = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'; 2 | 3 | export interface DateAdapter { 4 | // Override one or multiple of the methods to adjust to the logic of the current date library. 5 | override(members: Partial): void; 6 | readonly options: unknown; 7 | 8 | /** 9 | * Returns a map of time formats for the supported formatting units defined 10 | * in Unit as well as 'datetime' representing a detailed date/time string. 11 | * @returns {{string: string}} 12 | */ 13 | formats(): { [key: string]: string }; 14 | /** 15 | * Parses the given `value` and return the associated timestamp. 16 | * @param {unknown} value - the value to parse (usually comes from the data) 17 | * @param {string} [format] - the expected data format 18 | */ 19 | parse(value: unknown, format?: TimeUnit): number | null; 20 | /** 21 | * Returns the formatted date in the specified `format` for a given `timestamp`. 22 | * @param {number} timestamp - the timestamp to format 23 | * @param {string} format - the date/time token 24 | * @return {string} 25 | */ 26 | format(timestamp: number, format: TimeUnit): string; 27 | /** 28 | * Adds the specified `amount` of `unit` to the given `timestamp`. 29 | * @param {number} timestamp - the input timestamp 30 | * @param {number} amount - the amount to add 31 | * @param {Unit} unit - the unit as string 32 | * @return {number} 33 | */ 34 | add(timestamp: number, amount: number, unit: TimeUnit): number; 35 | /** 36 | * Returns the number of `unit` between the given timestamps. 37 | * @param {number} a - the input timestamp (reference) 38 | * @param {number} b - the timestamp to subtract 39 | * @param {Unit} unit - the unit as string 40 | * @return {number} 41 | */ 42 | diff(a: number, b: number, unit: TimeUnit): number; 43 | /** 44 | * Returns start of `unit` for the given `timestamp`. 45 | * @param {number} timestamp - the input timestamp 46 | * @param {Unit|'isoWeek'} unit - the unit as string 47 | * @param {number} [weekday] - the ISO day of the week with 1 being Monday 48 | * and 7 being Sunday (only needed if param *unit* is `isoWeek`). 49 | * @return {number} 50 | */ 51 | startOf(timestamp: number, unit: TimeUnit | 'isoWeek', weekday?: number): number; 52 | /** 53 | * Returns end of `unit` for the given `timestamp`. 54 | * @param {number} timestamp - the input timestamp 55 | * @param {Unit|'isoWeek'} unit - the unit as string 56 | * @return {number} 57 | */ 58 | endOf(timestamp: number, unit: TimeUnit | 'isoWeek'): number; 59 | } 60 | 61 | export const _adapters: { 62 | _date: DateAdapter; 63 | }; 64 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/animation.d.ts: -------------------------------------------------------------------------------- 1 | import { Chart } from './index.esm'; 2 | import { AnyObject } from './basic'; 3 | 4 | export class Animation { 5 | constructor(cfg: AnyObject, target: AnyObject, prop: string, to?: unknown); 6 | active(): boolean; 7 | update(cfg: AnyObject, to: unknown, date: number): void; 8 | cancel(): void; 9 | tick(date: number): void; 10 | } 11 | 12 | export interface AnimationEvent { 13 | chart: Chart; 14 | numSteps: number; 15 | initial: boolean; 16 | currentStep: number; 17 | } 18 | 19 | export class Animator { 20 | listen(chart: Chart, event: 'complete' | 'progress', cb: (event: AnimationEvent) => void): void; 21 | add(chart: Chart, items: readonly Animation[]): void; 22 | has(chart: Chart): boolean; 23 | start(chart: Chart): void; 24 | running(chart: Chart): boolean; 25 | stop(chart: Chart): void; 26 | remove(chart: Chart): boolean; 27 | } 28 | 29 | export class Animations { 30 | constructor(chart: Chart, animations: AnyObject); 31 | configure(animations: AnyObject): void; 32 | update(target: AnyObject, values: AnyObject): undefined | boolean; 33 | } 34 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/basic.d.ts: -------------------------------------------------------------------------------- 1 | 2 | export type AnyObject = Record; 3 | export type EmptyObject = Record; 4 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/color.d.ts: -------------------------------------------------------------------------------- 1 | export type Color = string | CanvasGradient | CanvasPattern; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/element.d.ts: -------------------------------------------------------------------------------- 1 | import { AnyObject } from './basic'; 2 | import { Point } from './geometric'; 3 | 4 | export interface Element { 5 | readonly x: number; 6 | readonly y: number; 7 | readonly active: boolean; 8 | readonly options: O; 9 | 10 | tooltipPosition(useFinalPosition?: boolean): Point; 11 | hasValue(): boolean; 12 | getProps

(props: P, final?: boolean): Pick; 13 | } 14 | export const Element: { 15 | prototype: Element; 16 | new (): Element; 17 | }; 18 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/geometric.d.ts: -------------------------------------------------------------------------------- 1 | export interface ChartArea { 2 | top: number; 3 | left: number; 4 | right: number; 5 | bottom: number; 6 | width: number; 7 | height: number; 8 | } 9 | 10 | export interface Point { 11 | x: number; 12 | y: number; 13 | } 14 | 15 | export type TRBL = { 16 | top: number; 17 | right: number; 18 | bottom: number; 19 | left: number; 20 | } 21 | 22 | export type TRBLCorners = { 23 | topLeft: number; 24 | topRight: number; 25 | bottomLeft: number; 26 | bottomRight: number; 27 | }; 28 | 29 | export type CornerRadius = number | Partial; 30 | 31 | export type RoundedRect = { 32 | x: number; 33 | y: number; 34 | w: number; 35 | h: number; 36 | radius?: CornerRadius 37 | } 38 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.canvas.d.ts: -------------------------------------------------------------------------------- 1 | import { PointStyle } from '../index.esm'; 2 | import { Color } from '../color'; 3 | import { ChartArea, RoundedRect } from '../geometric'; 4 | import { CanvasFontSpec } from './helpers.options'; 5 | 6 | export function clearCanvas(canvas: HTMLCanvasElement, ctx?: CanvasRenderingContext2D): void; 7 | 8 | export function clipArea(ctx: CanvasRenderingContext2D, area: ChartArea): void; 9 | 10 | export function unclipArea(ctx: CanvasRenderingContext2D): void; 11 | 12 | export interface DrawPointOptions { 13 | pointStyle: PointStyle; 14 | rotation?: number; 15 | radius: number; 16 | borderWidth: number; 17 | } 18 | 19 | export function drawPoint(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number): void; 20 | 21 | /** 22 | * Converts the given font object into a CSS font string. 23 | * @param font a font object 24 | * @return The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font 25 | */ 26 | export function toFontString(font: { size: number; family: string; style?: string; weight?: string }): string | null; 27 | 28 | export interface RenderTextOpts { 29 | /** 30 | * The fill color of the text. If unset, the existing 31 | * fillStyle property of the canvas is unchanged. 32 | */ 33 | color?: Color; 34 | 35 | /** 36 | * The width of the strikethrough / underline 37 | * @default 2 38 | */ 39 | decorationWidth?: number; 40 | 41 | /** 42 | * The max width of the text in pixels 43 | */ 44 | maxWidth?: number; 45 | 46 | /** 47 | * A rotation to be applied to the canvas 48 | * This is applied after the translation is applied 49 | */ 50 | rotation?: number; 51 | 52 | /** 53 | * Apply a strikethrough effect to the text 54 | */ 55 | strikethrough?: boolean; 56 | 57 | /** 58 | * The color of the text stroke. If unset, the existing 59 | * strokeStyle property of the context is unchanged 60 | */ 61 | strokeColor?: Color; 62 | 63 | /** 64 | * The text stroke width. If unset, the existing 65 | * lineWidth property of the context is unchanged 66 | */ 67 | strokeWidth?: number; 68 | 69 | /** 70 | * The text alignment to use. If unset, the existing 71 | * textAlign property of the context is unchanged 72 | */ 73 | textAlign: CanvasTextAlign; 74 | 75 | /** 76 | * The text baseline to use. If unset, the existing 77 | * textBaseline property of the context is unchanged 78 | */ 79 | textBaseline: CanvasTextBaseline; 80 | 81 | /** 82 | * If specified, a translation to apply to the context 83 | */ 84 | translation?: [number, number]; 85 | 86 | /** 87 | * Underline the text 88 | */ 89 | underline?: boolean; 90 | } 91 | 92 | export function renderText( 93 | ctx: CanvasRenderingContext2D, 94 | text: string | string[], 95 | x: number, 96 | y: number, 97 | font: CanvasFontSpec, 98 | opts?: RenderTextOpts 99 | ): void; 100 | 101 | export function addRoundedRectPath(ctx: CanvasRenderingContext2D, rect: RoundedRect): void; 102 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.collection.d.ts: -------------------------------------------------------------------------------- 1 | export interface ArrayListener { 2 | _onDataPush?(...item: T[]): void; 3 | _onDataPop?(): void; 4 | _onDataShift?(): void; 5 | _onDataSplice?(index: number, deleteCount: number, ...items: T[]): void; 6 | _onDataUnshift?(...item: T[]): void; 7 | } 8 | 9 | /** 10 | * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', 11 | * 'unshift') and notify the listener AFTER the array has been altered. Listeners are 12 | * called on the '_onData*' callbacks (e.g. _onDataPush, etc.) with same arguments. 13 | */ 14 | export function listenArrayEvents(array: T[], listener: ArrayListener): void; 15 | 16 | /** 17 | * Removes the given array event listener and cleanup extra attached properties (such as 18 | * the _chartjs stub and overridden methods) if array doesn't have any more listeners. 19 | */ 20 | export function unlistenArrayEvents(array: T[], listener: ArrayListener): void; 21 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.color.d.ts: -------------------------------------------------------------------------------- 1 | export function color(value: CanvasGradient): CanvasGradient; 2 | export function color(value: CanvasPattern): CanvasPattern; 3 | export function color( 4 | value: 5 | | string 6 | | { r: number; g: number; b: number; a: number } 7 | | [number, number, number] 8 | | [number, number, number, number] 9 | ): ColorModel; 10 | 11 | export interface ColorModel { 12 | rgbString(): string; 13 | hexString(): string; 14 | hslString(): string; 15 | rgb: { r: number; g: number; b: number; a: number }; 16 | valid: boolean; 17 | mix(color: ColorModel, weight: number): this; 18 | clone(): ColorModel; 19 | alpha(a: number): ColorModel; 20 | clearer(ration: number): ColorModel; 21 | greyscale(): ColorModel; 22 | opaquer(ratio: number): ColorModel; 23 | negate(): ColorModel; 24 | lighten(ratio: number): ColorModel; 25 | darken(ratio: number): ColorModel; 26 | saturate(ratio: number): ColorModel; 27 | desaturate(ratio: number): ColorModel; 28 | rotate(deg: number): this; 29 | } 30 | 31 | export function getHoverColor(value: CanvasGradient): CanvasGradient; 32 | export function getHoverColor(value: CanvasPattern): CanvasPattern; 33 | export function getHoverColor(value: string): string; 34 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.core.d.ts: -------------------------------------------------------------------------------- 1 | import { AnyObject } from '../basic'; 2 | 3 | /** 4 | * An empty function that can be used, for example, for optional callback. 5 | */ 6 | export function noop(): void; 7 | 8 | /** 9 | * Returns a unique id, sequentially generated from a global variable. 10 | * @returns {number} 11 | * @function 12 | */ 13 | export function uid(): number; 14 | /** 15 | * Returns true if `value` is neither null nor undefined, else returns false. 16 | * @param {*} value - The value to test. 17 | * @returns {boolean} 18 | * @since 2.7.0 19 | */ 20 | export function isNullOrUndef(value: unknown): value is null | undefined; 21 | /** 22 | * Returns true if `value` is an array (including typed arrays), else returns false. 23 | * @param {*} value - The value to test. 24 | * @returns {boolean} 25 | * @function 26 | */ 27 | export function isArray(value: unknown): value is ArrayLike; 28 | /** 29 | * Returns true if `value` is an object (excluding null), else returns false. 30 | * @param {*} value - The value to test. 31 | * @returns {boolean} 32 | * @since 2.7.0 33 | */ 34 | export function isObject(value: unknown): value is AnyObject; 35 | /** 36 | * Returns true if `value` is a finite number, else returns false 37 | * @param {*} value - The value to test. 38 | * @returns {boolean} 39 | */ 40 | export function isFinite(value: unknown): value is number; 41 | 42 | /** 43 | * Returns `value` if finite, else returns `defaultValue`. 44 | * @param {*} value - The value to return if defined. 45 | * @param {*} defaultValue - The value to return if `value` is not finite. 46 | * @returns {*} 47 | */ 48 | export function finiteOrDefault(value: unknown, defaultValue: number): number; 49 | 50 | /** 51 | * Returns `value` if defined, else returns `defaultValue`. 52 | * @param {*} value - The value to return if defined. 53 | * @param {*} defaultValue - The value to return if `value` is undefined. 54 | * @returns {*} 55 | */ 56 | export function valueOrDefault(value: T | undefined, defaultValue: T): T; 57 | 58 | export function toPercentage(value: number | string, dimesion: number): number; 59 | export function toDimension(value: number | string, dimension: number): number; 60 | 61 | /** 62 | * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the 63 | * value returned by `fn`. If `fn` is not a function, this method returns undefined. 64 | * @param fn - The function to call. 65 | * @param args - The arguments with which `fn` should be called. 66 | * @param [thisArg] - The value of `this` provided for the call to `fn`. 67 | * @returns {*} 68 | */ 69 | export function callback R, TA, R>( 70 | fn: T | undefined, 71 | args: unknown[], 72 | thisArg?: TA 73 | ): R | undefined; 74 | 75 | /** 76 | * Note(SB) for performance sake, this method should only be used when loopable type 77 | * is unknown or in none intensive code (not called often and small loopable). Else 78 | * it's preferable to use a regular for() loop and save extra function calls. 79 | * @param loopable - The object or array to be iterated. 80 | * @param fn - The function to call for each item. 81 | * @param [thisArg] - The value of `this` provided for the call to `fn`. 82 | * @param [reverse] - If true, iterates backward on the loopable. 83 | */ 84 | export function each( 85 | loopable: T[], 86 | fn: (this: TA, v: T, i: number) => void, 87 | thisArg?: TA, 88 | reverse?: boolean 89 | ): void; 90 | /** 91 | * Note(SB) for performance sake, this method should only be used when loopable type 92 | * is unknown or in none intensive code (not called often and small loopable). Else 93 | * it's preferable to use a regular for() loop and save extra function calls. 94 | * @param loopable - The object or array to be iterated. 95 | * @param fn - The function to call for each item. 96 | * @param [thisArg] - The value of `this` provided for the call to `fn`. 97 | * @param [reverse] - If true, iterates backward on the loopable. 98 | */ 99 | export function each( 100 | loopable: { [key: string]: T }, 101 | fn: (this: TA, v: T, k: string) => void, 102 | thisArg?: TA, 103 | reverse?: boolean 104 | ): void; 105 | 106 | /** 107 | * Returns a deep copy of `source` without keeping references on objects and arrays. 108 | * @param source - The value to clone. 109 | */ 110 | export function clone(source: T): T; 111 | 112 | export interface MergeOptions { 113 | merger?: (key: string, target: AnyObject, source: AnyObject, options: AnyObject) => AnyObject; 114 | } 115 | /** 116 | * Recursively deep copies `source` properties into `target` with the given `options`. 117 | * IMPORTANT: `target` is not cloned and will be updated with `source` properties. 118 | * @param target - The target object in which all sources are merged into. 119 | * @param source - Object(s) to merge into `target`. 120 | * @param {object} [options] - Merging options: 121 | * @param {function} [options.merger] - The merge method (key, target, source, options) 122 | * @returns {object} The `target` object. 123 | */ 124 | export function merge(target: T, source: [], options?: MergeOptions): T; 125 | export function merge(target: T, source: S1, options?: MergeOptions): T & S1; 126 | export function merge(target: T, source: [S1], options?: MergeOptions): T & S1; 127 | export function merge(target: T, source: [S1, S2], options?: MergeOptions): T & S1 & S2; 128 | export function merge(target: T, source: [S1, S2, S3], options?: MergeOptions): T & S1 & S2 & S3; 129 | export function merge( 130 | target: T, 131 | source: [S1, S2, S3, S4], 132 | options?: MergeOptions 133 | ): T & S1 & S2 & S3 & S4; 134 | export function merge(target: T, source: AnyObject[], options?: MergeOptions): AnyObject; 135 | 136 | /** 137 | * Recursively deep copies `source` properties into `target` *only* if not defined in target. 138 | * IMPORTANT: `target` is not cloned and will be updated with `source` properties. 139 | * @param target - The target object in which all sources are merged into. 140 | * @param source - Object(s) to merge into `target`. 141 | * @returns The `target` object. 142 | */ 143 | export function mergeIf(target: T, source: []): T; 144 | export function mergeIf(target: T, source: S1): T & S1; 145 | export function mergeIf(target: T, source: [S1]): T & S1; 146 | export function mergeIf(target: T, source: [S1, S2]): T & S1 & S2; 147 | export function mergeIf(target: T, source: [S1, S2, S3]): T & S1 & S2 & S3; 148 | export function mergeIf(target: T, source: [S1, S2, S3, S4]): T & S1 & S2 & S3 & S4; 149 | export function mergeIf(target: T, source: AnyObject[]): AnyObject; 150 | 151 | export function resolveObjectKey(obj: AnyObject, key: string): AnyObject; 152 | 153 | export function defined(value: unknown): boolean; 154 | 155 | export function isFunction(value: unknown): boolean; 156 | 157 | export function setsEqual(a: Set, b: Set): boolean; 158 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.curve.d.ts: -------------------------------------------------------------------------------- 1 | export interface SplinePoint { 2 | x: number; 3 | y: number; 4 | } 5 | 6 | /** 7 | * Props to Rob Spencer at scaled innovation for his post on splining between points 8 | * http://scaledinnovation.com/analytics/splines/aboutSplines.html 9 | */ 10 | export function splineCurve( 11 | firstPoint: SplinePoint & { skip?: boolean }, 12 | middlePoint: SplinePoint, 13 | afterPoint: SplinePoint, 14 | t: number 15 | ): { 16 | previous: SplinePoint; 17 | next: SplinePoint; 18 | }; 19 | 20 | export interface MonotoneSplinePoint extends SplinePoint { 21 | skip: boolean; 22 | cp1x?: number; 23 | cp1y?: number; 24 | cp2x?: number; 25 | cp2y?: number; 26 | } 27 | 28 | /** 29 | * This function calculates Bézier control points in a similar way than |splineCurve|, 30 | * but preserves monotonicity of the provided data and ensures no local extremums are added 31 | * between the dataset discrete points due to the interpolation. 32 | * @see https://en.wikipedia.org/wiki/Monotone_cubic_interpolation 33 | */ 34 | export function splineCurveMonotone(points: readonly MonotoneSplinePoint[], indexAxis?: 'x' | 'y'): void; 35 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.dom.d.ts: -------------------------------------------------------------------------------- 1 | import { ChartEvent } from '../index.esm'; 2 | 3 | export function getMaximumSize(node: HTMLElement, width?: number, height?: number, aspectRatio?: number): { width: number, height: number }; 4 | export function getRelativePosition( 5 | evt: MouseEvent | ChartEvent, 6 | chart: { readonly canvas: HTMLCanvasElement } 7 | ): { x: number; y: number }; 8 | export function getStyle(el: HTMLElement, property: string): string; 9 | export function retinaScale( 10 | chart: { 11 | currentDevicePixelRatio: number; 12 | readonly canvas: HTMLCanvasElement; 13 | readonly width: number; 14 | readonly height: number; 15 | readonly ctx: CanvasRenderingContext2D; 16 | }, 17 | forceRatio: number, 18 | forceStyle?: boolean 19 | ): void; 20 | export function readUsedSize(element: HTMLElement, property: 'width' | 'height'): number | undefined; 21 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.easing.d.ts: -------------------------------------------------------------------------------- 1 | import { EasingFunction } from '../index.esm'; 2 | 3 | export type EasingFunctionSignature = (t: number) => number; 4 | 5 | export const easingEffects: Record; 6 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.extras.d.ts: -------------------------------------------------------------------------------- 1 | export function fontString(pixelSize: number, fontStyle: string, fontFamily: string): string; 2 | 3 | /** 4 | * Request animation polyfill 5 | */ 6 | export function requestAnimFrame(cb: () => void): void; 7 | 8 | /** 9 | * Throttles calling `fn` once per animation frame 10 | * Latest arguments are used on the actual call 11 | * @param {function} fn 12 | * @param {*} thisArg 13 | * @param {function} [updateFn] 14 | */ 15 | export function throttled(fn: (...args: unknown[]) => void, thisArg: unknown, updateFn?: (...args: unknown[]) => unknown[]): (...args: unknown[]) => void; 16 | 17 | /** 18 | * Debounces calling `fn` for `delay` ms 19 | * @param {function} fn - Function to call. No arguments are passed. 20 | * @param {number} delay - Delay in ms. 0 = immediate invocation. 21 | * @returns {function} 22 | */ 23 | export function debounce(fn: () => void, delay: number): () => number; 24 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.interpolation.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.intl.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Format a number using a localized number formatter. 3 | * @param num The number to format 4 | * @param locale The locale to pass to the Intl.NumberFormat constructor 5 | * @param options Number format options 6 | */ 7 | export function formatNumber(num: number, locale: string, options: Intl.NumberFormatOptions): string; 8 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.math.d.ts: -------------------------------------------------------------------------------- 1 | export function log10(x: number): number; 2 | export function isNumber(v: unknown): boolean; 3 | export function almostEquals(x: number, y: number, epsilon: number): boolean; 4 | export function almostWhole(x: number, epsilon: number): number; 5 | export function sign(x: number): number; 6 | export function niceNum(range: number): number; 7 | export function toRadians(degrees: number): number; 8 | export function toDegrees(radians: number): number; 9 | /** 10 | * Gets the angle from vertical upright to the point about a centre. 11 | */ 12 | export function getAngleFromPoint( 13 | centrePoint: { x: number; y: number }, 14 | anglePoint: { x: number; y: number } 15 | ): { angle: number; distance: number }; 16 | 17 | export function distanceBetweenPoints(pt1: { x: number; y: number }, pt2: { x: number; y: number }): number; 18 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.options.d.ts: -------------------------------------------------------------------------------- 1 | import { TRBL, TRBLCorners } from '../geometric'; 2 | import { FontSpec } from '../index.esm'; 3 | 4 | export interface CanvasFontSpec extends FontSpec { 5 | string: string; 6 | } 7 | /** 8 | * Parses font options and returns the font object. 9 | * @param {object} options - A object that contains font options to be parsed. 10 | * @return {object} The font object. 11 | */ 12 | export function toFont(options: Partial): CanvasFontSpec; 13 | 14 | /** 15 | * Converts the given line height `value` in pixels for a specific font `size`. 16 | * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). 17 | * @param {number} size - The font size (in pixels) used to resolve relative `value`. 18 | * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid). 19 | * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height 20 | * @since 2.7.0 21 | */ 22 | export function toLineHeight(value: string, size: number): number; 23 | 24 | export function toTRBL(value: number | Partial): TRBL; 25 | export function toTRBLCorners(value: number | Partial): TRBLCorners; 26 | 27 | /** 28 | * Converts the given value into a padding object with pre-computed width/height. 29 | * @param {number|object} value - If a number, set the value to all TRBL component; 30 | * else, if an object, use defined properties and sets undefined ones to 0. 31 | * @returns {object} The padding values (top, right, bottom, left, width, height) 32 | * @since 2.7.0 33 | */ 34 | export function toPadding( 35 | value?: number | { top?: number; left?: number; right?: number; bottom?: number; x?:number, y?: number } 36 | ): { top: number; left: number; right: number; bottom: number; width: number; height: number }; 37 | 38 | /** 39 | * Evaluates the given `inputs` sequentially and returns the first defined value. 40 | * @param inputs - An array of values, falling back to the last value. 41 | * @param [context] - If defined and the current value is a function, the value 42 | * is called with `context` as first argument and the result becomes the new input. 43 | * @param [index] - If defined and the current value is an array, the value 44 | * at `index` become the new input. 45 | * @param [info] - object to return information about resolution in 46 | * @param [info.cacheable] - Will be set to `false` if option is not cacheable. 47 | * @since 2.7.0 48 | */ 49 | export function resolve( 50 | inputs: undefined | T | ((c: C) => T) | readonly T[], 51 | context?: C, 52 | index?: number, 53 | info?: { cacheable?: boolean } 54 | ): T | undefined; 55 | 56 | 57 | /** 58 | * Create a context inheriting parentContext 59 | * @since 3.6.0 60 | */ 61 | export function createContext(parentContext: P, context: T): P extends null ? T : P & T; 62 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.rtl.d.ts: -------------------------------------------------------------------------------- 1 | export interface RTLAdapter { 2 | x(x: number): number; 3 | setWidth(w: number): void; 4 | textAlign(align: 'center' | 'left' | 'right'): 'center' | 'left' | 'right'; 5 | xPlus(x: number, value: number): number; 6 | leftForLtr(x: number, itemWidth: number): number; 7 | } 8 | export function getRtlAdapter(rtl: boolean, rectX: number, width: number): RTLAdapter; 9 | 10 | export function overrideTextDirection(ctx: CanvasRenderingContext2D, direction: 'ltr' | 'rtl'): void; 11 | 12 | export function restoreTextDirection(ctx: CanvasRenderingContext2D, original?: [string, string]): void; 13 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/helpers.segment.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/helpers/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './helpers.canvas'; 2 | export * from './helpers.collection'; 3 | export * from './helpers.color'; 4 | export * from './helpers.core'; 5 | export * from './helpers.curve'; 6 | export * from './helpers.dom'; 7 | export * from './helpers.easing'; 8 | export * from './helpers.extras'; 9 | export * from './helpers.interpolation'; 10 | export * from './helpers.intl'; 11 | export * from './helpers.math'; 12 | export * from './helpers.options'; 13 | export * from './helpers.canvas'; 14 | export * from './helpers.rtl'; 15 | export * from './helpers.segment'; 16 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/layout.d.ts: -------------------------------------------------------------------------------- 1 | import { ChartArea } from './geometric'; 2 | 3 | export type LayoutPosition = 'left' | 'top' | 'right' | 'bottom' | 'center' | 'chartArea' | {[scaleId: string]: number}; 4 | 5 | export interface LayoutItem { 6 | /** 7 | * The position of the item in the chart layout. Possible values are 8 | */ 9 | position: LayoutPosition; 10 | /** 11 | * The weight used to sort the item. Higher weights are further away from the chart area 12 | */ 13 | weight: number; 14 | /** 15 | * if true, and the item is horizontal, then push vertical boxes down 16 | */ 17 | fullSize: boolean; 18 | /** 19 | * Width of item. Must be valid after update() 20 | */ 21 | width: number; 22 | /** 23 | * Height of item. Must be valid after update() 24 | */ 25 | height: number; 26 | /** 27 | * Left edge of the item. Set by layout system and cannot be used in update 28 | */ 29 | left: number; 30 | /** 31 | * Top edge of the item. Set by layout system and cannot be used in update 32 | */ 33 | top: number; 34 | /** 35 | * Right edge of the item. Set by layout system and cannot be used in update 36 | */ 37 | right: number; 38 | /** 39 | * Bottom edge of the item. Set by layout system and cannot be used in update 40 | */ 41 | bottom: number; 42 | 43 | /** 44 | * Called before the layout process starts 45 | */ 46 | beforeLayout?(): void; 47 | /** 48 | * Draws the element 49 | */ 50 | draw(chartArea: ChartArea): void; 51 | /** 52 | * Returns an object with padding on the edges 53 | */ 54 | getPadding?(): ChartArea; 55 | /** 56 | * returns true if the layout item is horizontal (ie. top or bottom) 57 | */ 58 | isHorizontal(): boolean; 59 | /** 60 | * Takes two parameters: width and height. 61 | * @param width 62 | * @param height 63 | */ 64 | update(width: number, height: number, margins?: ChartArea): void; 65 | } 66 | -------------------------------------------------------------------------------- /src/views/js/chart.js/types/utils.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-types */ 2 | 3 | // DeepPartial implementation taken from the utility-types NPM package, which is 4 | // Copyright (c) 2016 Piotr Witek (http://piotrwitek.github.io) 5 | // and used under the terms of the MIT license 6 | export type DeepPartial = T extends Function 7 | ? T 8 | : T extends Array 9 | ? _DeepPartialArray 10 | : T extends object 11 | ? _DeepPartialObject 12 | : T | undefined; 13 | 14 | type _DeepPartialArray = Array> 15 | type _DeepPartialObject = { [P in keyof T]?: DeepPartial }; 16 | 17 | export type DistributiveArray = [T] extends [unknown] ? Array : never 18 | 19 | // https://stackoverflow.com/a/50375286 20 | export type UnionToIntersection = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never; 21 | 22 | --------------------------------------------------------------------------------