From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 7 Feb 2020 23:03:33 +0000 (-0800) Subject: Fix errors reported by TypeScript compiler (#7030) X-Git-Tag: v3.0.0-alpha~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=795c86e95b73c95a599cfd5ca16401dc3c6e6699;p=thirdparty%2FChart.js.git Fix errors reported by TypeScript compiler (#7030) --- diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index fe64cc3c1..5a9608901 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -48,7 +48,7 @@ * [Styling](axes/styling.md) * [Developers](developers/README.md) * [Chart.js API](developers/api.md) - * [JSDoc](jsdoc/index.html) + * [TypeDoc](typedoc/index.html) * [Updating Charts](developers/updates.md) * [Plugins](developers/plugins.md) * [New Charts](developers/charts.md) diff --git a/docs/getting-started/v3-migration.md b/docs/getting-started/v3-migration.md index 07b544fc8..d00df7675 100644 --- a/docs/getting-started/v3-migration.md +++ b/docs/getting-started/v3-migration.md @@ -1,6 +1,13 @@ # Chart.js 3.x Migration Guide -Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released in April 2016. In the years since then, as Chart.js has grown in popularity and feature set, we've learned some lessons about how to better create a charting library. In order to improve performance, offer new features, and improve maintainability, it was necessary to break backwards compatibility, but we aimed to do so only when necessary. +Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released in April 2016. In the years since then, as Chart.js has grown in popularity and feature set, we've learned some lessons about how to better create a charting library. In order to improve performance, offer new features, and improve maintainability, it was necessary to break backwards compatibility, but we aimed to do so only when worth the benefit. Some major highlights of v3 include: + +* Large [performance](../general/performance.md) improvements including the ability to skip data parsing and render charts in parallel via webworkers +* Additional configurability and scriptable options with better defaults +* Completely rewritten animation system +* Rewritten filler plugin with numerous bug fixes +* API Documentation generated and verified by TypeScript +* Tons of bug fixes ## End user migration diff --git a/gulpfile.js b/gulpfile.js index b5e68217e..0c2cfb045 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,26 +1,29 @@ -var gulp = require('gulp'); -var eslint = require('gulp-eslint'); -var file = require('gulp-file'); -var jsdoc = require('gulp-jsdoc3'); -var replace = require('gulp-replace'); -var size = require('gulp-size'); -var streamify = require('gulp-streamify'); -var terser = require('gulp-terser'); -var zip = require('gulp-zip'); -var exec = require('child_process').exec; -var karma = require('karma'); -var merge = require('merge-stream'); -var yargs = require('yargs'); -var path = require('path'); -var htmllint = require('gulp-htmllint'); -var pkg = require('./package.json'); - -var argv = yargs +const gulp = require('gulp'); +const eslint = require('gulp-eslint'); +const file = require('gulp-file'); +const replace = require('gulp-replace'); +const size = require('gulp-size'); +const streamify = require('gulp-streamify'); +const terser = require('gulp-terser'); +const zip = require('gulp-zip'); +const exec = require('child_process').exec; +const karma = require('karma'); +const merge = require('merge-stream'); +const yargs = require('yargs'); +const path = require('path'); +const htmllint = require('gulp-htmllint'); +const typescript = require('gulp-typescript'); +const typedoc = require("gulp-typedoc"); + +const pkg = require('./package.json'); +const tsProject = typescript.createProject('./tsconfig.json'); + +const argv = yargs .option('verbose', {default: false}) .argv; -var srcDir = './src/'; -var outDir = './dist/'; +const srcDir = './src/'; +const outDir = './dist/'; gulp.task('bower', bowerTask); gulp.task('build', buildTask); @@ -28,9 +31,10 @@ gulp.task('package', packageTask); gulp.task('lint-html', lintHtmlTask); gulp.task('lint-js', lintJsTask); gulp.task('lint', gulp.parallel('lint-html', 'lint-js')); +gulp.task('tsc', typescriptTask); gulp.task('docs', docsTask); gulp.task('unittest', unittestTask); -gulp.task('test', gulp.parallel('lint', 'unittest')); +gulp.task('test', gulp.parallel('lint', 'tsc', 'unittest')); gulp.task('library-size', librarySizeTask); gulp.task('module-sizes', moduleSizesTask); gulp.task('size', gulp.parallel('library-size', 'module-sizes')); @@ -38,10 +42,10 @@ gulp.task('default', gulp.parallel('build')); function run(bin, args, done) { return new Promise(function(resolve, reject) { - var exe = '"' + process.execPath + '"'; - var src = require.resolve(bin); - var cmd = [exe, src].concat(args || []).join(' '); - var ps = exec(cmd); + const exe = '"' + process.execPath + '"'; + const src = require.resolve(bin); + const cmd = [exe, src].concat(args || []).join(' '); + const ps = exec(cmd); ps.stdout.pipe(process.stdout); ps.stderr.pipe(process.stderr); @@ -60,7 +64,7 @@ function run(bin, args, done) { * Specs: https://github.com/bower/spec/blob/master/json.md */ function bowerTask() { - var json = JSON.stringify({ + const json = JSON.stringify({ name: pkg.name, description: pkg.description, homepage: pkg.homepage, @@ -101,7 +105,7 @@ function packageTask() { } function lintJsTask() { - var files = [ + const files = [ 'samples/**/*.html', 'samples/**/*.js', 'src/**/*.js', @@ -111,7 +115,7 @@ function lintJsTask() { // NOTE(SB) codeclimate has 'complexity' and 'max-statements' eslint rules way too strict // compare to what the current codebase can support, and since it's not straightforward // to fix, let's turn them as warnings and rewrite code later progressively. - var options = { + const options = { rules: { 'complexity': [1, 10], 'max-statements': [1, 30] @@ -124,6 +128,12 @@ function lintJsTask() { .pipe(eslint.failAfterError()); } +function typescriptTask() { + return tsProject.src() + .pipe(tsProject()) + .js.pipe(gulp.dest('dist')); +} + function lintHtmlTask() { return gulp.src('samples/**/*.html') .pipe(htmllint({ @@ -132,20 +142,19 @@ function lintHtmlTask() { } function docsTask(done) { - var bin = require.resolve('gitbook-cli/bin/gitbook.js'); - var cmd = argv.watch ? 'serve' : 'build'; + const bin = require.resolve('gitbook-cli/bin/gitbook.js'); + const cmd = argv.watch ? 'serve' : 'build'; return run(bin, ['install', './']) .then(() => run(bin, [cmd, './', './dist/docs'])) .then(() => { - var config = { - opts: { - destination: './dist/docs/jsdoc' - }, - recurse: true + const config = { + moduleResolution: "Node", + target: "ES6", + out: "./dist/docs/typedoc" }; gulp.src(['./src/**/*.js'], {read: false}) - .pipe(jsdoc(config, done)); + .pipe(typedoc(config, done)); }).catch((err) => { done(new Error(err.stdout || err)); }); diff --git a/package-lock.json b/package-lock.json index 117cd1268..c49fdc617 100644 --- a/package-lock.json +++ b/package-lock.json @@ -785,6 +785,12 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, "@types/node": { "version": "12.12.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.3.tgz", @@ -1067,12 +1073,6 @@ } } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -1829,6 +1829,15 @@ "now-and-later": "^2.0.0" } }, + "backbone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", + "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", + "dev": true, + "requires": { + "underscore": ">=1.8.3" + } + }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -1923,12 +1932,6 @@ "tweetnacl": "^0.14.3" } }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, "better-assert": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", @@ -2179,15 +2182,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3402,6 +3396,21 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "eventemitter3": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", @@ -3851,6 +3860,12 @@ "map-cache": "^0.2.2" } }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, "fs-extra": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", @@ -4853,34 +4868,6 @@ } } }, - "gulp-jsdoc3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-jsdoc3/-/gulp-jsdoc3-2.0.0.tgz", - "integrity": "sha512-R0US0cHc5v/u8/g9oQ4/4hXEl/QqFcU3/sladKWlTpDUJPDIkeLNHZpq9PFqnuNvC2yZ/Pegs2KpgUmFghZUIg==", - "dev": true, - "requires": { - "ansi-colors": "^1.1.0", - "beeper": "^1.1.1", - "bluebird": "^3.1.1", - "debug": "^3.1.0", - "fancy-log": "^1.3.2", - "ink-docstrap": "^1.1.4", - "jsdoc": "^3.4.1", - "map-stream": "0.0.7", - "tmp": "0.0.33" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, "gulp-replace": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", @@ -5017,6 +5004,70 @@ } } }, + "gulp-typedoc": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/gulp-typedoc/-/gulp-typedoc-2.2.4.tgz", + "integrity": "sha512-E+UjjfJLjUupOSdMrEjv+WD/baKlwEWB2SBbKv8i9IfcCKgsakj6qSh85IYE69N5o3cCGjIKhd2H6KwX/ul5iA==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1", + "event-stream": "^4.0.1", + "fancy-log": "^1.3.3", + "plugin-error": "^1.0.1", + "semver": "^7.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "semver": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz", + "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==", + "dev": true + } + } + }, + "gulp-typescript": { + "version": "6.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz", + "integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1", + "plugin-error": "^1.0.1", + "source-map": "^0.7.3", + "through2": "^3.0.1", + "vinyl": "^2.2.0", + "vinyl-fs": "^3.0.3" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "dev": true, + "requires": { + "readable-stream": "2 || 3" + } + } + } + }, "gulp-zip": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.0.1.tgz", @@ -5180,6 +5231,12 @@ } } }, + "highlight.js": { + "version": "9.18.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", + "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", + "dev": true + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -5332,16 +5389,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "ink-docstrap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.2.tgz", - "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", - "dev": true, - "requires": { - "moment": "^2.14.1", - "sanitize-html": "^1.13.0" - } - }, "inquirer": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", @@ -5869,6 +5916,12 @@ } } }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==", + "dev": true + }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", @@ -5891,51 +5944,12 @@ "esprima": "^4.0.0" } }, - "js2xmlparser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", - "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.0" - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, - "jsdoc": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", - "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", - "dev": true, - "requires": { - "@babel/parser": "^7.4.4", - "bluebird": "^3.5.4", - "catharsis": "^0.8.11", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.0", - "klaw": "^3.0.0", - "markdown-it": "^8.4.2", - "markdown-it-anchor": "^5.0.2", - "marked": "^0.7.0", - "mkdirp": "^0.5.1", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.0.1", - "taffydb": "2.6.2", - "underscore": "~1.9.1" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6323,15 +6337,6 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, "last-run": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", @@ -6427,15 +6432,6 @@ "resolve": "^1.1.7" } }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -6473,36 +6469,6 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, - "lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -6551,6 +6517,12 @@ "yallist": "^2.1.2" } }, + "lunr": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.8.tgz", + "integrity": "sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==", + "dev": true + }, "magic-string": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz", @@ -6614,31 +6586,6 @@ "object-visit": "^1.0.0" } }, - "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", - "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==", - "dev": true - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, "matchdep": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", @@ -6674,12 +6621,6 @@ } } }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -11951,6 +11892,15 @@ "pinkie-promise": "^2.0.0" } }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "requires": { + "through": "~2.3" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -12053,34 +12003,6 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -12526,15 +12448,6 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "resolve": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", @@ -12747,24 +12660,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sanitize-html": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.1.tgz", - "integrity": "sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "htmlparser2": "^3.10.0", - "lodash.clonedeep": "^4.5.0", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.mergewith": "^4.6.1", - "postcss": "^7.0.5", - "srcset": "^1.0.0", - "xtend": "^4.0.1" - } - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -12836,6 +12731,17 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -13192,6 +13098,15 @@ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -13207,16 +13122,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "srcset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", - "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", - "dev": true, - "requires": { - "array-uniq": "^1.0.2", - "number-is-nan": "^1.0.0" - } - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -13267,6 +13172,16 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "stream-counter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-1.0.0.tgz", @@ -13478,12 +13393,6 @@ } } }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "terser": { "version": "4.3.9", "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", @@ -13755,10 +13664,87 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "typedoc": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.16.9.tgz", + "integrity": "sha512-UvOGoy76yqwCXwxPgatwgXWfsQ3FczyZ6ZNLjhCPK+TsDir6LiU3YB6N9XZmPv36E+7LA860mnc8a0v6YADKFw==", + "dev": true, + "requires": { + "@types/minimatch": "3.0.3", + "fs-extra": "^8.1.0", + "handlebars": "^4.7.2", + "highlight.js": "^9.17.1", + "lodash": "^4.17.15", + "marked": "^0.8.0", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shelljs": "^0.8.3", + "typedoc-default-themes": "^0.7.2", + "typescript": "3.7.x" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "handlebars": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.3.tgz", + "integrity": "sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "marked": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.0.tgz", + "integrity": "sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "typedoc-default-themes": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.7.2.tgz", + "integrity": "sha512-fiFKlFO6VTqjcno8w6WpTsbCgXmfPHVjnLfYkmByZE7moaz+E2DSpAT+oHtDHv7E0BM5kAhPrHJELP2J2Y2T9A==", + "dev": true, + "requires": { + "backbone": "^1.4.0", + "jquery": "^3.4.1", + "lunr": "^2.3.8", + "underscore": "^1.9.1" + } + }, + "typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", "dev": true }, "uglify-js": { @@ -14211,12 +14197,6 @@ "ultron": "~1.1.0" } }, - "xmlcreate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", - "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", - "dev": true - }, "xmlhttprequest-ssl": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", diff --git a/package.json b/package.json index 2e03fc657..3a145ecfa 100644 --- a/package.json +++ b/package.json @@ -43,11 +43,12 @@ "gulp-eslint": "^6.0.0", "gulp-file": "^0.4.0", "gulp-htmllint": "^0.0.16", - "gulp-jsdoc3": "^2.0.0", "gulp-replace": "^1.0.0", "gulp-size": "^3.0.0", "gulp-streamify": "^1.0.2", "gulp-terser": "^1.1.6", + "gulp-typedoc": "^2.2.4", + "gulp-typescript": "^6.0.0-alpha.1", "gulp-zip": "^5.0.0", "jasmine": "^3.3.0", "jasmine-core": "^3.3.0", @@ -69,6 +70,8 @@ "rollup-plugin-istanbul": "^2.0.1", "rollup-plugin-node-resolve": "^5.0.0", "rollup-plugin-terser": "^5.1.3", + "typedoc": "^0.16.9", + "typescript": "^3.7.5", "yargs": "^14.0.0" }, "dependencies": { diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index 2a08f7e66..0a702e418 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -146,7 +146,7 @@ class BubbleController extends DatasetController { var chart = me.chart; var dataset = me.getDataset(); var parsed = me._getParsed(index); - var values = DatasetController.prototype._resolveDataElementOptions.apply(me, arguments); + var values = super._resolveDataElementOptions.apply(me, arguments); // Scriptable options var context = { diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 4ee40f147..a6277932c 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -100,6 +100,9 @@ class DoughnutController extends DatasetController { constructor(chart, datasetIndex) { super(chart, datasetIndex); + + this.innerRadius = undefined; + this.outerRadius = undefined; } linkScales() {} diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index c91602079..ff98b805c 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -30,6 +30,8 @@ class LineController extends DatasetController { constructor(chart, datasetIndex) { super(chart, datasetIndex); + + this._showLine = undefined; } update(mode) { diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 41818b9a6..998447856 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -94,6 +94,9 @@ class PolarAreaController extends DatasetController { constructor(chart, datasetIndex) { super(chart, datasetIndex); + + this.innerRadius = undefined; + this.outerRadius = undefined; } /** diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index 5eebe77bb..3b926feea 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -110,7 +110,7 @@ class RadarController extends DatasetController { const me = this; const config = me._config; const options = me.chart.options; - const values = DatasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); + const values = super._resolveDatasetElementOptions.apply(me, arguments); values.spanGaps = valueOrDefault(config.spanGaps, options.spanGaps); values.tension = valueOrDefault(config.lineTension, options.elements.line.tension); @@ -128,12 +128,12 @@ RadarController.prototype.dataElementType = Point; */ RadarController.prototype._datasetElementOptions = [ 'backgroundColor', - 'borderWidth', 'borderColor', 'borderCapStyle', 'borderDash', 'borderDashOffset', 'borderJoinStyle', + 'borderWidth', 'fill' ]; diff --git a/src/core/core.animation.js b/src/core/core.animation.js index 3b2e27bb7..a468a0abf 100644 --- a/src/core/core.animation.js +++ b/src/core/core.animation.js @@ -1,6 +1,6 @@ 'use strict'; -import helpers from '../helpers'; +import helpers from '../helpers/index'; import {effects} from '../helpers/helpers.easing'; import {resolve} from '../helpers/helpers.options'; @@ -23,22 +23,21 @@ const interpolators = { class Animation { constructor(cfg, target, prop, to) { - const me = this; const currentValue = target[prop]; to = resolve([cfg.to, to, currentValue, cfg.from]); let from = resolve([cfg.from, currentValue, to]); - me._active = true; - me._fn = cfg.fn || interpolators[cfg.type || typeof from]; - me._easing = effects[cfg.easing || 'linear']; - me._start = Math.floor(Date.now() + (cfg.delay || 0)); - me._duration = Math.floor(cfg.duration); - me._loop = !!cfg.loop; - me._target = target; - me._prop = prop; - me._from = from; - me._to = to; + this._active = true; + this._fn = cfg.fn || interpolators[cfg.type || typeof from]; + this._easing = effects[cfg.easing || 'linear']; + this._start = Math.floor(Date.now() + (cfg.delay || 0)); + this._duration = Math.floor(cfg.duration); + this._loop = !!cfg.loop; + this._target = target; + this._prop = prop; + this._from = from; + this._to = to; } active() { diff --git a/src/core/core.animator.js b/src/core/core.animator.js index b2fd4b41b..3fe775ed9 100644 --- a/src/core/core.animator.js +++ b/src/core/core.animator.js @@ -1,6 +1,10 @@ 'use strict'; -import helpers from '../helpers'; +import helpers from '../helpers/index'; + +/** + * @typedef { import("./core.controller").default } Chart + */ function drawFPS(chart, count, date, lastDate) { const fps = (1000 / (date - lastDate)) | 0; @@ -21,6 +25,7 @@ class Animator { this._request = null; this._charts = new Map(); this._running = false; + this._lastDate = undefined; } /** diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 6d50198e8..7e0f9be3b 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -10,6 +10,10 @@ import {BasicPlatform, DomPlatform} from '../platform/platforms'; import plugins from './core.plugins'; import scaleService from '../core/core.scaleService'; +/** + * @typedef { import("../platform/platform.base").IEvent } IEvent + */ + const valueOrDefault = helpers.valueOrDefault; function mergeScaleConfig(config, options) { @@ -76,7 +80,7 @@ function initConfig(config) { // Do NOT use mergeConfig for the data object because this method merges arrays // and so would change references to labels and datasets, preventing data updates. - const data = config.data = config.data || {}; + const data = config.data = config.data || {datasets: [], labels: []}; data.datasets = data.datasets || []; data.labels = data.labels || []; @@ -174,24 +178,36 @@ class Chart { config = initConfig(config); const initialCanvas = getCanvas(item); - me._initializePlatform(initialCanvas, config); + this.platform = me._initializePlatform(initialCanvas, config); const context = me.platform.acquireContext(initialCanvas, config); const canvas = context && context.canvas; const height = canvas && canvas.height; const width = canvas && canvas.width; - me.id = helpers.uid(); - me.ctx = context; - me.canvas = canvas; - me.config = config; - me.width = width; - me.height = height; - me.aspectRatio = height ? width / height : null; - me.options = config.options; - me._bufferedRender = false; - me._layers = []; - me._metasets = []; + this.id = helpers.uid(); + this.ctx = context; + this.canvas = canvas; + this.config = config; + this.width = width; + this.height = height; + this.aspectRatio = height ? width / height : null; + this.options = config.options; + this._bufferedRender = false; + this._layers = []; + this._metasets = []; + this.boxes = []; + this.currentDevicePixelRatio = undefined; + this.chartArea = undefined; + this.data = undefined; + this.active = undefined; + this.lastActive = undefined; + this._lastEvent = undefined; + this._listeners = {resize: undefined}; + this._sortedMetasets = []; + this._updating = false; + this.scales = {}; + this.scale = undefined; // Add the chart instance to the global namespace Chart.instances[me.id] = me; @@ -250,17 +266,14 @@ class Chart { * @private */ _initializePlatform(canvas, config) { - const me = this; - if (config.platform) { - me.platform = new config.platform(); + return new config.platform(); } else if (!isDomSupported()) { - me.platform = new BasicPlatform(); + return new BasicPlatform(); } else if (window.OffscreenCanvas && canvas instanceof window.OffscreenCanvas) { - me.platform = new BasicPlatform(); - } else { - me.platform = new DomPlatform(); + return new BasicPlatform(); } + return new DomPlatform(); } clear() { @@ -910,7 +923,7 @@ class Chart { */ bindEvents() { const me = this; - const listeners = me._listeners = {}; + const listeners = me._listeners; let listener = function() { me.eventHandler.apply(me, arguments); }; diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 7ef108a58..dc6e3683c 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -1,6 +1,6 @@ 'use strict'; -import helpers from '../helpers'; +import helpers from '../helpers/index'; import Animations from './core.animations'; const resolve = helpers.options.resolve; @@ -217,21 +217,28 @@ function getFirstScaleId(chart, axis) { class DatasetController { - /** Base class for all dataset controllers (line, bar, etc) */ constructor(chart, datasetIndex) { - this.initialize(chart, datasetIndex); - } - - initialize(chart, datasetIndex) { + this.chart = chart; + this._ctx = chart.ctx; + this.index = datasetIndex; + this._cachedAnimations = {}; + this._cachedDataOpts = {}; + this._cachedMeta = this.getMeta(); + this._type = this._cachedMeta.type; + this._config = undefined; + this._parsing = false; + this._data = undefined; + this._dataCopy = undefined; + this._objectData = undefined; + this._labels = undefined; + this._scaleStacked = {}; + + this.initialize(); + } + + initialize() { const me = this; - let meta; - me.chart = chart; - me._ctx = chart.ctx; - me.index = datasetIndex; - me._cachedAnimations = {}; - me._cachedDataOpts = {}; - me._cachedMeta = meta = me.getMeta(); - me._type = meta.type; + const meta = me._cachedMeta; me._configure(); me.linkScales(); meta._stacked = isStacked(meta.vScale, meta); @@ -707,6 +714,7 @@ class DatasetController { } /** + * @return {number|boolean} * @private */ _getMaxOverflow() { @@ -763,6 +771,9 @@ class DatasetController { } } + /** + * @private + */ _addAutomaticHoverColors(index, options) { const me = this; const getHoverColor = helpers.getHoverColor; @@ -783,7 +794,7 @@ class DatasetController { * or the data if the index is specified * @param {number} index - data index * @param {boolean} [active] - true if hover - * @return {IStyleInterface} style object + * @return {object} style object */ getStyle(index, active) { const me = this; @@ -803,6 +814,9 @@ class DatasetController { return options; } + /** + * @private + */ _getContext(index, active) { return { chart: this.chart, @@ -821,6 +835,7 @@ class DatasetController { const me = this; const chart = me.chart; const datasetOpts = me._config; + // @ts-ignore const options = chart.options.elements[me.datasetElementType.prototype._type] || {}; const elementOptions = me._datasetElementOptions; const values = {}; @@ -854,6 +869,7 @@ class DatasetController { } const chart = me.chart; const datasetOpts = me._config; + // @ts-ignore const options = chart.options.elements[me.dataElementType.prototype._type] || {}; const elementOptions = me._dataElementOptions; const values = {}; @@ -1067,6 +1083,8 @@ class DatasetController { me.updateElements(elements, start, 'reset'); } + updateElements(element, start, mode) {} // eslint-disable-line no-unused-vars + /** * @private */ @@ -1119,47 +1137,45 @@ class DatasetController { DatasetController.extend = helpers.inherits; -DatasetController.extend({ - /** - * Element type used to generate a meta dataset (e.g. Chart.element.Line). - * @type {Chart.core.element} - */ - datasetElementType: null, +/** + * Element type used to generate a meta dataset (e.g. Chart.element.Line). + */ +DatasetController.prototype.datasetElementType = null; - /** - * Element type used to generate a meta data (e.g. Chart.element.Point). - * @type {Chart.core.element} - */ - dataElementType: null, +/** + * Element type used to generate a meta data (e.g. Chart.element.Point). + */ +DatasetController.prototype.dataElementType = null; - /** - * Dataset element option keys to be resolved in _resolveDatasetElementOptions. - * A derived controller may override this to resolve controller-specific options. - * The keys defined here are for backward compatibility for legend styles. - * @private - */ - _datasetElementOptions: [ - 'backgroundColor', - 'borderCapStyle', - 'borderColor', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'borderWidth' - ], +/** + * Dataset element option keys to be resolved in _resolveDatasetElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @type {string[]} + * @private + */ +DatasetController.prototype._datasetElementOptions = [ + 'backgroundColor', + 'borderCapStyle', + 'borderColor', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'borderWidth' +]; - /** - * Data element option keys to be resolved in _resolveDataElementOptions. - * A derived controller may override this to resolve controller-specific options. - * The keys defined here are for backward compatibility for legend styles. - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'pointStyle' - ] -}); +/** + * Data element option keys to be resolved in _resolveDataElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @type {string[]|object} + * @private + */ +DatasetController.prototype._dataElementOptions = [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'pointStyle' +]; export default DatasetController; diff --git a/src/core/core.element.js b/src/core/core.element.js index 6c9fc63ab..885c9ef0b 100644 --- a/src/core/core.element.js +++ b/src/core/core.element.js @@ -5,12 +5,17 @@ import {isNumber} from '../helpers/helpers.math'; class Element { - constructor(configuration) { - if (configuration) { - extend(this, configuration); - } + /** + * @param {object} [cfg] optional configuration + */ + constructor(cfg) { + this.x = undefined; + this.y = undefined; + this.hidden = undefined; - // this.hidden = false; we assume Element has an attribute called hidden, but do not initialize to save memory + if (cfg) { + extend(this, cfg); + } } tooltipPosition() { diff --git a/src/core/core.interaction.js b/src/core/core.interaction.js index 88c6cc3bd..12adbb62f 100644 --- a/src/core/core.interaction.js +++ b/src/core/core.interaction.js @@ -4,6 +4,14 @@ import helpers from '../helpers/index'; import {_isPointInArea} from '../helpers/helpers.canvas'; import {_lookupByKey, _rlookupByKey} from '../helpers/helpers.collection'; +/** + * @typedef { import("./core.controller").default } Chart + */ + +/** + * @typedef { import("../platform/platform.base").IEvent } IEvent + */ + /** * Helper function to get relative position for an event * @param {Event|IEvent} e - The event to get the position for @@ -11,7 +19,7 @@ import {_lookupByKey, _rlookupByKey} from '../helpers/helpers.collection'; * @returns {object} the event position */ function getRelativePosition(e, chart) { - if (e.native) { + if ('native' in e) { return { x: e.x, y: e.y @@ -175,6 +183,7 @@ function getNearestItems(chart, position, axis, intersect) { /** * @interface IInteractionOptions + * @typedef {object} IInteractionOptions */ /** * If true, only consider items that intersect the point diff --git a/src/core/core.layouts.js b/src/core/core.layouts.js index d56162bb2..97c7bec6c 100644 --- a/src/core/core.layouts.js +++ b/src/core/core.layouts.js @@ -4,6 +4,10 @@ import defaults from './core.defaults'; import {each, extend} from '../helpers/helpers.core'; import {toPadding} from '../helpers/helpers.options'; +/** + * @typedef { import("./core.controller").default } Chart + */ + const STATIC_POSITIONS = ['left', 'top', 'right', 'bottom']; function filterByPosition(array, position) { @@ -208,13 +212,15 @@ defaults._set('layout', { /** * @interface ILayoutItem + * @typedef {object} ILayoutItem * @prop {string} position - The position of the item in the chart layout. Possible values are * 'left', 'top', 'right', 'bottom', and 'chartArea' * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) * @prop {function} update - Takes two parameters: width and height. Returns size of item - * @prop {function} getPadding - Returns an object with padding on the edges + * @prop {function} draw - Draws the element + * @prop {function} [getPadding] - Returns an object with padding on the edges * @prop {number} width - Width of item. Must be valid after update() * @prop {number} height - Height of item. Must be valid after update() * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update @@ -244,6 +250,7 @@ export default { item.fullWidth = item.fullWidth || false; item.position = item.position || 'top'; item.weight = item.weight || 0; + // @ts-ignore item._layers = item._layers || function() { return [{ z: 0, @@ -363,7 +370,7 @@ export default { fitBoxes(verticalBoxes, chartArea, params); } - handleMaxPadding(chartArea, params); + handleMaxPadding(chartArea); // Finally place the boxes to correct coordinates placeBoxes(boxes.leftAndTop, chartArea, params); diff --git a/src/core/core.plugins.js b/src/core/core.plugins.js index 0ae1033b2..f5522fd15 100644 --- a/src/core/core.plugins.js +++ b/src/core/core.plugins.js @@ -3,6 +3,18 @@ import defaults from './core.defaults'; import {clone} from '../helpers/helpers.core'; +/** + * @typedef { import("./core.controller").default } Chart + */ + +/** + * @typedef { import("../platform/platform.base").IEvent } IEvent + */ + +/** + * @typedef { import("../plugins/plugin.tooltip").default } Tooltip + */ + defaults._set('plugins', {}); /** @@ -171,6 +183,7 @@ export default { /** * Plugin extension hooks. * @interface IPlugin + * @typedef {object} IPlugin * @since 2.1.0 */ /** diff --git a/src/core/core.scale.js b/src/core/core.scale.js index cc3d55002..40a084ced 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -224,6 +224,82 @@ function skip(ticks, newTicks, spacing, majorStart, majorEnd) { class Scale extends Element { + constructor(cfg) { + super(); + + /** @type {string} */ + this.id = cfg.id; + this.type = cfg.type; + /** @type {object} */ + this.options = cfg.options; + this.ctx = cfg.ctx; + this.chart = cfg.chart; + + // implements box + /** @type {number} */ + this.top = undefined; + /** @type {number} */ + this.bottom = undefined; + /** @type {number} */ + this.left = undefined; + /** @type {number} */ + this.right = undefined; + /** @type {number} */ + this.width = undefined; + /** @type {number} */ + this.height = undefined; + this.margins = { + left: 0, + right: 0, + top: 0, + bottom: 0 + }; + // TODO: make maxWidth, maxHeight private + /** @type {number} */ + this.maxWidth = undefined; + /** @type {number} */ + this.maxHeight = undefined; + /** @type {number} */ + this.paddingTop = undefined; + /** @type {number} */ + this.paddingBottom = undefined; + /** @type {number} */ + this.paddingLeft = undefined; + /** @type {number} */ + this.paddingRight = undefined; + + // scale-specific properties + /** @type {string} */ + this.axis = undefined; + /** @type {number} */ + this.labelRotation = undefined; + this.min = undefined; + this.max = undefined; + /** @type {object[]} */ + this.ticks = null; + /** @type {object[]} */ + this._gridLineItems = null; + /** @type {object[]} */ + this._labelItems = null; + /** @type {object} */ + this._labelSizes = null; + /** @type {number} */ + this._length = undefined; + /** @type {object} */ + this._longestTextCache = {}; + /** @type {number} */ + this._maxLabelLines = undefined; + /** @type {number} */ + this._startPixel = undefined; + /** @type {number} */ + this._endPixel = undefined; + this._reversePixels = undefined; + this._userMax = undefined; + this._userMin = undefined; + this._ticksLength = undefined; + this._borderValue = undefined; + } + /** * Parse a supported input value to internal representation. * @param {*} raw @@ -356,7 +432,6 @@ class Scale extends Element { me.beforeUpdate(); // Absorb the master measurements - // TODO: make maxWidth, maxHeight private me.maxWidth = maxWidth; me.maxHeight = maxHeight; me.margins = extend({ @@ -369,7 +444,6 @@ class Scale extends Element { me.ticks = null; me._labelSizes = null; me._maxLabelLines = 0; - me._longestTextCache = me._longestTextCache || {}; me._gridLineItems = null; me._labelItems = null; @@ -497,7 +571,9 @@ class Scale extends Element { /** * @return {object[]} the ticks */ - buildTicks() {} + buildTicks() { + return []; + } afterBuildTicks() { call(this.options.afterBuildTicks, [this]); } diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 1e4fa0711..85a669e23 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -54,7 +54,7 @@ export default { const logTick = log10(Math.abs(tickValue)); let numExponential = Math.floor(logTick) - Math.floor(logDelta); numExponential = Math.max(Math.min(numExponential, 20), 0); - return new Intl.NumberFormat(locale, {notation: 'scientific', minimumFractionDigits: numExponential, maximumFractionDigits: numExponential}).format(tickValue); + return tickValue.toExponential(numExponential); } let numDecimal = -1 * Math.floor(logDelta); diff --git a/src/elements/element.arc.js b/src/elements/element.arc.js index 8b154a376..39d0476cc 100644 --- a/src/elements/element.arc.js +++ b/src/elements/element.arc.js @@ -2,6 +2,7 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; +import {extend} from '../helpers/helpers.core'; import {getAngleFromPoint} from '../helpers/helpers.math'; const TAU = Math.PI * 2; @@ -92,8 +93,19 @@ function drawBorder(ctx, vm, arc) { class Arc extends Element { - constructor(props) { - super(props); + constructor(cfg) { + super(); + + this.options = undefined; + this.circumference = undefined; + this.startAngle = undefined; + this.endAngle = undefined; + this.innerRadius = undefined; + this.outerRadius = undefined; + + if (cfg) { + extend(this, cfg); + } } inRange(chartX, chartY) { diff --git a/src/elements/element.line.js b/src/elements/element.line.js index 3efe1d76a..589583af4 100644 --- a/src/elements/element.line.js +++ b/src/elements/element.line.js @@ -2,11 +2,16 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; +import {extend} from '../helpers/helpers.core'; import {_bezierInterpolation, _pointInLine, _steppedInterpolation} from '../helpers/helpers.interpolation'; import {_computeSegments, _boundSegments} from '../helpers/helpers.segment'; import {_steppedLineTo, _bezierCurveTo} from '../helpers/helpers.canvas'; import {_updateBezierControlPoints} from '../helpers/helpers.curve'; +/** + * @typedef { import("./element.point").default } Point + */ + const defaultColor = defaults.color; defaults._set('elements', { @@ -178,6 +183,9 @@ function _getSegmentMethod(line) { return useFastPath ? fastPathSegment : pathSegment; } +/** + * @private + */ function _getInterpolationMethod(options) { if (options.steppedLine) { return _steppedInterpolation; @@ -192,8 +200,19 @@ function _getInterpolationMethod(options) { class Line extends Element { - constructor(props) { - super(props); + constructor(cfg) { + super(); + + this.options = undefined; + this._loop = undefined; + this._fullLoop = undefined; + this._controlPointsUpdated = undefined; + this._points = undefined; + this._segments = undefined; + + if (cfg) { + extend(this, cfg); + } } updateControlPoints(chartArea) { @@ -299,19 +318,16 @@ class Line extends Element { /** * Append all segments of this line to current path. * @param {CanvasRenderingContext2D} ctx - * @param {object} params - * @param {object} params.move - move to starting point (vs line to it) - * @param {object} params.reverse - path the segment from end to start * @returns {undefined|boolean} - true if line is a full loop (path should be closed) */ - path(ctx, params) { + path(ctx) { const me = this; const segments = me.segments; const ilen = segments.length; const segmentMethod = _getSegmentMethod(me); let loop = me._loop; for (let i = 0; i < ilen; ++i) { - loop &= segmentMethod(ctx, me, segments[i], params); + loop &= segmentMethod(ctx, me, segments[i]); } return !!loop; } diff --git a/src/elements/element.point.js b/src/elements/element.point.js index 1f7541318..420e5f444 100644 --- a/src/elements/element.point.js +++ b/src/elements/element.point.js @@ -3,6 +3,7 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; import {_isPointInArea, drawPoint} from '../helpers/helpers.canvas'; +import {extend} from '../helpers/helpers.core'; const defaultColor = defaults.color; @@ -22,8 +23,16 @@ defaults._set('elements', { class Point extends Element { - constructor(props) { - super(props); + constructor(cfg) { + super(); + + this.options = undefined; + this.skip = undefined; + this.stop = undefined; + + if (cfg) { + extend(this, cfg); + } } inRange(mouseX, mouseY) { diff --git a/src/elements/element.rectangle.js b/src/elements/element.rectangle.js index b6aaeafe3..79c25ebca 100644 --- a/src/elements/element.rectangle.js +++ b/src/elements/element.rectangle.js @@ -2,7 +2,7 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; -import {isObject} from '../helpers/helpers.core'; +import {extend, isObject} from '../helpers/helpers.core'; const defaultColor = defaults.color; @@ -130,8 +130,18 @@ function inRange(bar, x, y) { class Rectangle extends Element { - constructor(props) { - super(props); + constructor(cfg) { + super(); + + this.options = undefined; + this.horizontal = undefined; + this.base = undefined; + this.width = undefined; + this.height = undefined; + + if (cfg) { + extend(this, cfg); + } } draw(ctx) { diff --git a/src/helpers/helpers.canvas.js b/src/helpers/helpers.canvas.js index 7ad5c4b55..36c73408d 100644 --- a/src/helpers/helpers.canvas.js +++ b/src/helpers/helpers.canvas.js @@ -2,6 +2,10 @@ import {isArray} from './helpers.core'; +/** + * @typedef { import("../core/core.controller").default } Chart + */ + const PI = Math.PI; const RAD_PER_DEG = PI / 180; const DOUBLE_PI = PI * 2; @@ -251,7 +255,7 @@ export function _steppedLineTo(ctx, previous, target, flip, mode) { const midpoint = (previous.x + target.x) / 2.0; ctx.lineTo(midpoint, previous.y); ctx.lineTo(midpoint, target.y); - } else if (mode === 'after' ^ flip) { + } else if (mode === 'after' !== !!flip) { ctx.lineTo(previous.x, target.y); } else { ctx.lineTo(target.x, previous.y); diff --git a/src/helpers/helpers.core.js b/src/helpers/helpers.core.js index 100d4edf4..0ddd8d761 100644 --- a/src/helpers/helpers.core.js +++ b/src/helpers/helpers.core.js @@ -63,7 +63,7 @@ export function isObject(value) { * @returns {boolean} */ const isNumberFinite = (value) => { - return (typeof value === 'number' || value instanceof Number) && isFinite(value); + return (typeof value === 'number' || value instanceof Number) && isFinite(+value); }; export { isNumberFinite as isFinite, @@ -171,6 +171,7 @@ export function arrayEquals(a0, a1) { * @param {Array} a0 - The array to compare * @param {Array} a1 - The array to compare * @returns {boolean} + * @private */ export function _elementsEqual(a0, a1) { let i, ilen, v0, v1; @@ -337,6 +338,9 @@ export function inherits(extensions) { return ChartElement; } +/** + * @private + */ export function _deprecated(scope, value, previous, current) { if (value !== undefined) { console.warn(scope + ': "' + previous + diff --git a/src/helpers/helpers.curve.js b/src/helpers/helpers.curve.js index 58e0952b9..afac52a0e 100644 --- a/src/helpers/helpers.curve.js +++ b/src/helpers/helpers.curve.js @@ -152,6 +152,9 @@ function capBezierPoints(points, area) { } } +/** + * @private + */ export function _updateBezierControlPoints(points, options, area, loop) { var i, ilen, point, controlPoints; diff --git a/src/helpers/helpers.interpolation.js b/src/helpers/helpers.interpolation.js index c8400b426..fe788161d 100644 --- a/src/helpers/helpers.interpolation.js +++ b/src/helpers/helpers.interpolation.js @@ -3,7 +3,7 @@ /** * @private */ -export function _pointInLine(p1, p2, t) { +export function _pointInLine(p1, p2, t, mode) { // eslint-disable-line no-unused-vars return { x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y) @@ -25,7 +25,7 @@ export function _steppedInterpolation(p1, p2, t, mode) { /** * @private */ -export function _bezierInterpolation(p1, p2, t) { +export function _bezierInterpolation(p1, p2, t, mode) { // eslint-disable-line no-unused-vars const cp1 = {x: p1.controlPointNextX, y: p1.controlPointNextY}; const cp2 = {x: p2.controlPointPreviousX, y: p2.controlPointPreviousY}; const a = _pointInLine(p1, cp1, t); diff --git a/src/helpers/helpers.math.js b/src/helpers/helpers.math.js index a08ed5ea5..c1c702c95 100644 --- a/src/helpers/helpers.math.js +++ b/src/helpers/helpers.math.js @@ -10,6 +10,7 @@ const PITAU = TAU + PI; * @alias Chart.helpers.math * @namespace */ + /** * Returns an array of factors sorted from 1 to sqrt(value) * @private @@ -58,6 +59,9 @@ export function almostWhole(x, epsilon) { return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x); } +/** + * @private + */ export function _setMinAndMaxByKey(array, target, property) { var i, ilen, value; diff --git a/src/helpers/helpers.rtl.js b/src/helpers/helpers.rtl.js index ebd5e7c0b..cf68886a9 100644 --- a/src/helpers/helpers.rtl.js +++ b/src/helpers/helpers.rtl.js @@ -60,8 +60,7 @@ const overrideTextDirection = function(ctx, direction) { } }; -const restoreTextDirection = function(ctx) { - var original = ctx.prevTextDirection; +const restoreTextDirection = function(ctx, original) { if (original !== undefined) { delete ctx.prevTextDirection; ctx.canvas.style.setProperty('direction', original[0], original[1]); diff --git a/src/helpers/helpers.segment.js b/src/helpers/helpers.segment.js index 012cb7481..76e519343 100644 --- a/src/helpers/helpers.segment.js +++ b/src/helpers/helpers.segment.js @@ -2,6 +2,14 @@ import {_angleBetween, _angleDiff, _normalizeAngle} from './helpers.math'; +/** + * @typedef { import("../elements/element.line").default } Line + */ + +/** + * @typedef { import("../elements/element.point").default } Point + */ + function propertyFn(property) { if (property === 'angle') { return { diff --git a/src/index.js b/src/index.js index b32770a09..1a1b17c00 100644 --- a/src/index.js +++ b/src/index.js @@ -3,16 +3,16 @@ */ import Chart from './core/core.controller'; -import helpers from './helpers'; +import helpers from './helpers/index'; import _adapters from './core/core.adapters'; import Animation from './core/core.animation'; import Animator from './core/core.animator'; import animationService from './core/core.animations'; -import controllers from './controllers'; +import controllers from './controllers/index'; import DatasetController from './core/core.datasetController'; import defaults from './core/core.defaults'; import Element from './core/core.element'; -import elements from './elements'; +import elements from './elements/index'; import Interaction from './core/core.interaction'; import layouts from './core/core.layouts'; import platforms from './platform/platforms'; @@ -42,17 +42,17 @@ Chart.scaleService = scaleService; Chart.Ticks = Ticks; // Register built-in scales -import scales from './scales'; +import scales from './scales/index'; Object.keys(scales).forEach(function(type) { const scale = scales[type]; Chart.scaleService.registerScaleType(type, scale, scale._defaults); }); // Load to register built-in adapters (as side effects) -import './adapters'; +import './adapters/index'; // Loading built-in plugins -import plugins from './plugins'; +import plugins from './plugins/index'; for (var k in plugins) { if (Object.prototype.hasOwnProperty.call(plugins, k)) { Chart.plugins.register(plugins[k]); @@ -60,6 +60,7 @@ for (var k in plugins) { } if (typeof window !== 'undefined') { + // @ts-ignore window.Chart = Chart; } diff --git a/src/platform/platform.base.js b/src/platform/platform.base.js index 3a62403ef..d00ad98df 100644 --- a/src/platform/platform.base.js +++ b/src/platform/platform.base.js @@ -1,5 +1,9 @@ 'use strict'; +/** + * @typedef { import("../core/core.controller").default } Chart + */ + /** * Abstract class that allows abstracting platform dependencies away from the chart. */ @@ -12,11 +16,13 @@ export default class BasePlatform { /** * Called at chart construction time, returns a context2d instance implementing * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}. - * @param {canvas} canvas - The canvas from which to acquire context (platform specific) + * @param {HTMLCanvasElement} canvas - The canvas from which to acquire context (platform specific) * @param {object} options - The chart options * @returns {CanvasRenderingContext2D} context2d instance */ - acquireContext(canvas, options) {} // eslint-disable-line no-unused-vars + acquireContext(canvas, options) { // eslint-disable-line no-unused-vars + return undefined; + } /** * Called at chart destruction time, releases any resources associated to the context @@ -24,7 +30,9 @@ export default class BasePlatform { * @param {CanvasRenderingContext2D} context - The context2d instance * @returns {boolean} true if the method succeeded, else false */ - releaseContext(context) {} // eslint-disable-line no-unused-vars + releaseContext(context) { // eslint-disable-line no-unused-vars + return false; + } /** * Registers the specified listener on the given chart. @@ -53,6 +61,7 @@ export default class BasePlatform { /** * @interface IEvent + * @typedef {object} IEvent * @prop {string} type - The event type name, possible values are: * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout', * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize' diff --git a/src/platform/platform.dom.js b/src/platform/platform.dom.js index 85d299b34..19c82dc21 100644 --- a/src/platform/platform.dom.js +++ b/src/platform/platform.dom.js @@ -4,11 +4,13 @@ 'use strict'; -import helpers from '../helpers'; -import stylesheet from './platform.dom.css'; +import helpers from '../helpers/index'; import BasePlatform from './platform.base'; import platform from './platform'; +// @ts-ignore +import stylesheet from './platform.dom.css'; + const EXPANDO_KEY = '$chartjs'; const CSS_PREFIX = 'chartjs-'; const CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor'; @@ -177,7 +179,7 @@ function createDiv(cls) { } // Implementation based on https://github.com/marcj/css-element-queries -function createResizer(handler) { +function createResizer(domPlatform, handler) { const maxSize = 1000000; // NOTE(SB) Don't use innerHTML because it could be considered unsafe. @@ -191,7 +193,7 @@ function createResizer(handler) { resizer.appendChild(expand); resizer.appendChild(shrink); - resizer._reset = function() { + domPlatform._reset = function() { expand.scrollLeft = maxSize; expand.scrollTop = maxSize; shrink.scrollLeft = maxSize; @@ -199,7 +201,7 @@ function createResizer(handler) { }; const onScroll = function() { - resizer._reset(); + domPlatform._reset(); handler(); }; @@ -247,11 +249,11 @@ function unwatchForRender(node) { node.classList.remove(CSS_RENDER_MONITOR); } -function addResizeListener(node, listener, chart) { +function addResizeListener(node, listener, chart, domPlatform) { const expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); // Let's keep track of this added resizer and thus avoid DOM query when removing it. - const resizer = expando.resizer = createResizer(throttled(function() { + const resizer = expando.resizer = createResizer(domPlatform, throttled(function() { if (expando.resizer) { const container = chart.options.maintainAspectRatio && node.parentNode; const w = container ? container.clientWidth : 0; @@ -279,7 +281,7 @@ function addResizeListener(node, listener, chart) { } // The container size might have changed, let's reset the resizer state. - resizer._reset(); + domPlatform._reset(); } }); } @@ -298,7 +300,7 @@ function removeResizeListener(node) { /** * Injects CSS styles inline if the styles are not already present. - * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the