* [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)
# 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
-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);
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'));
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);
* 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,
}
function lintJsTask() {
- var files = [
+ const files = [
'samples/**/*.html',
'samples/**/*.js',
'src/**/*.js',
// 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]
.pipe(eslint.failAfterError());
}
+function typescriptTask() {
+ return tsProject.src()
+ .pipe(tsProject())
+ .js.pipe(gulp.dest('dist'));
+}
+
function lintHtmlTask() {
return gulp.src('samples/**/*.html')
.pipe(htmllint({
}
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));
});
"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",
}
}
},
- "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",
"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",
"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",
"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",
"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",
"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",
}
}
},
- "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",
}
}
},
+ "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",
}
}
},
+ "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",
"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",
}
}
},
+ "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",
"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",
"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",
"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",
"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",
"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",
"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",
}
}
},
- "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",
"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",
"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",
"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",
"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",
"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",
"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",
"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",
"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",
}
}
},
- "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",
"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": {
"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",
"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",
"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": {
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 = {
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
+
+ this.innerRadius = undefined;
+ this.outerRadius = undefined;
}
linkScales() {}
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
+
+ this._showLine = undefined;
}
update(mode) {
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
+
+ this.innerRadius = undefined;
+ this.outerRadius = undefined;
}
/**
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);
*/
RadarController.prototype._datasetElementOptions = [
'backgroundColor',
- 'borderWidth',
'borderColor',
'borderCapStyle',
'borderDash',
'borderDashOffset',
'borderJoinStyle',
+ 'borderWidth',
'fill'
];
'use strict';
-import helpers from '../helpers';
+import helpers from '../helpers/index';
import {effects} from '../helpers/helpers.easing';
import {resolve} from '../helpers/helpers.options';
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() {
'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;
this._request = null;
this._charts = new Map();
this._running = false;
+ this._lastDate = undefined;
}
/**
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) {
// 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 || [];
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;
* @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() {
*/
bindEvents() {
const me = this;
- const listeners = me._listeners = {};
+ const listeners = me._listeners;
let listener = function() {
me.eventHandler.apply(me, arguments);
};
'use strict';
-import helpers from '../helpers';
+import helpers from '../helpers/index';
import Animations from './core.animations';
const resolve = helpers.options.resolve;
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);
}
/**
+ * @return {number|boolean}
* @private
*/
_getMaxOverflow() {
}
}
+ /**
+ * @private
+ */
_addAutomaticHoverColors(index, options) {
const me = this;
const getHoverColor = helpers.getHoverColor;
* 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;
return options;
}
+ /**
+ * @private
+ */
_getContext(index, active) {
return {
chart: this.chart,
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 = {};
}
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 = {};
me.updateElements(elements, start, 'reset');
}
+ updateElements(element, start, mode) {} // eslint-disable-line no-unused-vars
+
/**
* @private
*/
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;
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() {
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
* @returns {object} the event position
*/
function getRelativePosition(e, chart) {
- if (e.native) {
+ if ('native' in e) {
return {
x: e.x,
y: e.y
/**
* @interface IInteractionOptions
+ * @typedef {object} IInteractionOptions
*/
/**
* If true, only consider items that intersect the point
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) {
/**
* @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
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,
fitBoxes(verticalBoxes, chartArea, params);
}
- handleMaxPadding(chartArea, params);
+ handleMaxPadding(chartArea);
// Finally place the boxes to correct coordinates
placeBoxes(boxes.leftAndTop, chartArea, params);
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', {});
/**
/**
* Plugin extension hooks.
* @interface IPlugin
+ * @typedef {object} IPlugin
* @since 2.1.0
*/
/**
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
me.beforeUpdate();
// Absorb the master measurements
- // TODO: make maxWidth, maxHeight private
me.maxWidth = maxWidth;
me.maxHeight = maxHeight;
me.margins = extend({
me.ticks = null;
me._labelSizes = null;
me._maxLabelLines = 0;
- me._longestTextCache = me._longestTextCache || {};
me._gridLineItems = null;
me._labelItems = null;
/**
* @return {object[]} the ticks
*/
- buildTicks() {}
+ buildTicks() {
+ return [];
+ }
afterBuildTicks() {
call(this.options.afterBuildTicks, [this]);
}
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);
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;
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) {
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', {
return useFastPath ? fastPathSegment : pathSegment;
}
+/**
+ * @private
+ */
function _getInterpolationMethod(options) {
if (options.steppedLine) {
return _steppedInterpolation;
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) {
/**
* 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;
}
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;
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) {
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;
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) {
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;
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);
* @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,
* @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;
return ChartElement;
}
+/**
+ * @private
+ */
export function _deprecated(scope, value, previous, current) {
if (value !== undefined) {
console.warn(scope + ': "' + previous +
}
}
+/**
+ * @private
+ */
export function _updateBezierControlPoints(points, options, area, loop) {
var i, ilen, point, controlPoints;
/**
* @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)
/**
* @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);
* @alias Chart.helpers.math
* @namespace
*/
+
/**
* Returns an array of factors sorted from 1 to sqrt(value)
* @private
return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
}
+/**
+ * @private
+ */
export function _setMinAndMaxByKey(array, target, property) {
var i, ilen, value;
}
};
-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]);
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 {
*/
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';
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]);
}
if (typeof window !== 'undefined') {
+ // @ts-ignore
window.Chart = Chart;
}
'use strict';
+/**
+ * @typedef { import("../core/core.controller").default } Chart
+ */
+
/**
* Abstract class that allows abstracting platform dependencies away from the chart.
*/
/**
* 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
* @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.
/**
* @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'
'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';
}
// 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.
resizer.appendChild(expand);
resizer.appendChild(shrink);
- resizer._reset = function() {
+ domPlatform._reset = function() {
expand.scrollLeft = maxSize;
expand.scrollTop = maxSize;
shrink.scrollLeft = maxSize;
};
const onScroll = function() {
- resizer._reset();
+ domPlatform._reset();
handler();
};
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;
}
// The container size might have changed, let's reset the resizer state.
- resizer._reset();
+ domPlatform._reset();
}
});
}
/**
* Injects CSS styles inline if the styles are not already present.
- * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the <style>.
+ * @param {Node} rootNode - the HTMLDocument|ShadowRoot node to contain the <style>.
* @param {string} css - the CSS to be injected.
*/
function injectCSS(rootNode, css) {
// into the same shadow DOM.
// https://github.com/chartjs/Chart.js/issues/5763
const root = canvas.getRootNode ? canvas.getRootNode() : document;
+ // @ts-ignore
const targetNode = root.host ? root : document.head;
injectCSS(targetNode, stylesheet);
}
releaseContext(context) {
const canvas = context.canvas;
if (!canvas[EXPANDO_KEY]) {
- return;
+ return false;
}
const initial = canvas[EXPANDO_KEY].initial;
canvas.width = canvas.width;
delete canvas[EXPANDO_KEY];
+ return true;
}
addEventListener(chart, type, listener) {
const canvas = chart.canvas;
if (type === 'resize') {
// Note: the resize event is not supported on all browsers.
- addResizeListener(canvas, listener, chart);
+ addResizeListener(canvas, listener, chart, this);
return;
}
import Line from '../elements/element.line';
import {_boundSegment, _boundSegments} from '../helpers/helpers.segment';
import {clipArea, unclipArea} from '../helpers/helpers.canvas';
-import {valueOrDefault, isFinite, isArray, extend} from '../helpers/helpers.core';
+import {isArray, isFinite, valueOrDefault} from '../helpers/helpers.core';
import {_normalizeAngle} from '../helpers/helpers.math';
defaults._set('plugins', {
// TODO: use elements.Arc instead
class simpleArc {
constructor(opts) {
- extend(this, opts);
+ this.x = opts.x;
+ this.y = opts.y;
+ this.radius = opts.radius;
}
pathSegment(ctx, bounds, opts) {
if (isArray(boundary)) {
_loop = true;
+ // @ts-ignore
points = boundary;
} else {
points = pointsFromSegments(boundary, line);
ctx.beginPath();
- let loop = !!line.pathSegment(ctx, src);
- if (loop) {
+ const lineLoop = !!line.pathSegment(ctx, src);
+ if (lineLoop) {
ctx.closePath();
} else {
interpolatedLineTo(ctx, target, end, property);
}
- loop &= target.pathSegment(ctx, tgt, {move: loop, reverse: true});
+ const targetLoop = !!target.pathSegment(ctx, tgt, {move: lineLoop, reverse: true});
+ const loop = lineLoop && targetLoop;
if (!loop) {
interpolatedLineTo(ctx, target, start, property);
}
fill: decodeFill(line, i, count),
chart: chart,
scale: meta.vScale,
- line
+ line,
+ target: undefined
};
}
import {_parseFont, toPadding} from '../helpers/helpers.options';
import {getRtlAdapter, overrideTextDirection, restoreTextDirection} from '../helpers/helpers.rtl';
+/**
+ * @typedef { import("../platform/platform.base").IEvent } IEvent
+ */
+
defaults._set('legend', {
display: true,
position: 'top',
constructor(config) {
super();
- const me = this;
- extend(me, config);
+ extend(this, config);
// Contains hit boxes for each dataset (in dataset order)
- me.legendHitBoxes = [];
+ this.legendHitBoxes = [];
/**
* @private
*/
- me._hoveredItem = null;
+ this._hoveredItem = null;
// Are we in doughnut mode which has a different data type
- me.doughnutMode = false;
+ this.doughnutMode = false;
+
+ this.chart = config.chart;
+ this.options = config.options;
+ this.ctx = config.ctx;
+ this.legendItems = undefined;
+ this.columnWidths = undefined;
+ this.columnHeights = undefined;
+ this.lineWidths = undefined;
+ this._minSize = undefined;
+ this.maxHeight = undefined;
+ this.maxWidth = undefined;
+ this.top = undefined;
+ this.bottom = undefined;
+ this.left = undefined;
+ this.right = undefined;
+ this.height = undefined;
+ this.width = undefined;
+ this.margins = undefined;
+ this.paddingTop = undefined;
+ this.paddingBottom = undefined;
+ this.paddingLeft = undefined;
+ this.paddingRight = undefined;
+ this.position = undefined;
+ this.weight = undefined;
+ this.fullWidth = undefined;
}
// These methods are ordered by lifecycle. Utilities then follow.
constructor(config) {
super();
- var me = this;
- helpers.extend(me, config);
-
- // Contains hit boxes for each dataset (in dataset order)
- me.legendHitBoxes = [];
+ helpers.extend(this, config);
+
+ this.chart = config.chart;
+ this.options = config.options;
+ this.ctx = config.ctx;
+ this.margins = undefined;
+ this._padding = undefined;
+ this.legendHitBoxes = []; // Contains hit boxes for each dataset (in dataset order)
+ this.top = undefined;
+ this.bottom = undefined;
+ this.left = undefined;
+ this.right = undefined;
+ this.width = undefined;
+ this.height = undefined;
+ this.maxWidth = undefined;
+ this.maxHeight = undefined;
+ this.position = undefined;
+ this.weight = undefined;
+ this.fullWidth = undefined;
}
// These methods are ordered by lifecycle. Utilities then follow.
import plugins from '../core/core.plugins';
import helpers from '../helpers/index';
+/**
+ * @typedef { import("../platform/platform.base").IEvent } IEvent
+ */
+
const valueOrDefault = helpers.valueOrDefault;
const getRtlHelper = helpers.rtl.getRtlAdapter;
/**
* Returns array of strings split by newline
- * @param {string|undefined} str - The value to split by newline.
+ * @param {*} str - The value to split by newline.
* @returns {string|string[]} value if newline present - Returned from String split() method
* @function
*/
class Tooltip extends Element {
constructor(config) {
- super(config);
-
- const me = this;
- me.opacity = 0;
- me._active = [];
- me.initialize();
+ super();
+
+ this.opacity = 0;
+ this._active = [];
+ this._chart = config._chart;
+ this._eventPosition = undefined;
+ this._size = undefined;
+ this._cachedAnimations = undefined;
+ this.$animations = undefined;
+ this.options = undefined;
+ this.dataPoints = undefined;
+ this.title = undefined;
+ this.beforeBody = undefined;
+ this.body = undefined;
+ this.afterBody = undefined;
+ this.footer = undefined;
+ this.xAlign = undefined;
+ this.yAlign = undefined;
+ this.x = undefined;
+ this.y = undefined;
+ this.height = undefined;
+ this.width = undefined;
+ this.caretX = undefined;
+ this.labelColors = undefined;
+ this.labelTextColors = undefined;
+
+ this.initialize();
}
initialize() {
};
class CategoryScale extends Scale {
+
+ constructor(cfg) {
+ super(cfg);
+
+ /** @type {number} */
+ this._numLabels = undefined;
+ /** @type {number} */
+ this._startValue = undefined;
+ /** @type {number} */
+ this._valueRange = undefined;
+ }
+
_parse(raw, index) {
const labels = this._getLabels();
if (labels[index] === raw) {
me.handleTickRangeOptions();
}
- // Returns the maximum number of ticks based on the scale dimension
+ /**
+ * Returns the maximum number of ticks based on the scale dimension
+ * @private
+ */
_computeTickLimit() {
var me = this;
var tickFont;
}
class LinearScaleBase extends Scale {
+
+ constructor(cfg) {
+ super(cfg);
+
+ /** @type {number} */
+ this.start = undefined;
+ /** @type {number} */
+ this.end = undefined;
+ /** @type {number} */
+ this._startValue = undefined;
+ /** @type {number} */
+ this._endValue = undefined;
+ /** @type {number} */
+ this._valueRange = undefined;
+ }
+
_parse(raw, index) { // eslint-disable-line no-unused-vars
if (isNullOrUndef(raw)) {
return NaN;
}
- if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(raw)) {
+ if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) {
return NaN;
}
};
class LogarithmicScale extends Scale {
+
+ constructor(cfg) {
+ super(cfg);
+
+ /** @type {number} */
+ this.start = undefined;
+ /** @type {number} */
+ this.end = undefined;
+ /** @type {number} */
+ this._startValue = undefined;
+ /** @type {number} */
+ this._valueRange = undefined;
+ }
+
_parse(raw, index) { // eslint-disable-line no-unused-vars
const value = LinearScaleBase.prototype._parse.apply(this, arguments);
if (value === 0) {
var ctx = scale.ctx;
var circular = gridLineOpts.circular;
var valueCount = scale.chart.data.labels.length;
- var lineColor = valueAtIndexOrDefault(gridLineOpts.color, index - 1);
- var lineWidth = valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
+ var lineColor = valueAtIndexOrDefault(gridLineOpts.color, index - 1, undefined);
+ var lineWidth = valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1, undefined);
var pointPosition;
if ((!circular && !valueCount) || !lineColor || !lineWidth) {
}
class RadialLinearScale extends LinearScaleBase {
+
+ constructor(cfg) {
+ super(cfg);
+
+ /** @type {number} */
+ this.xCenter = undefined;
+ /** @type {number} */
+ this.yCenter = undefined;
+ /** @type {number} */
+ this.drawingArea = undefined;
+ /** @type {string[]} */
+ this.pointLabels = undefined;
+ }
+
setDimensions() {
var me = this;
};
class TimeScale extends Scale {
+
+ constructor(props) {
+ super(props);
+
+ const options = this.options;
+ const time = options.time || (options.time = {});
+ const adapter = this._adapter = new adapters._date(options.adapters.date);
+
+
+ this._cache = {};
+
+ /** @type {string | undefined} */
+ this._unit = undefined;
+ /** @type {string | undefined} */
+ this._majorUnit = undefined;
+ /** @type {object | undefined} */
+ this._offsets = undefined;
+ /** @type {object[] | undefined} */
+ this._table = undefined;
+
+ // Backward compatibility: before introducing adapter, `displayFormats` was
+ // supposed to contain *all* unit/string pairs but this can't be resolved
+ // when loading the scale (adapters are loaded afterward), so let's populate
+ // missing formats on update
+ mergeIf(time.displayFormats, adapter.formats());
+ }
+
_parse(raw, index) { // eslint-disable-line no-unused-vars
if (raw === undefined) {
return NaN;
this._cache = {};
}
- constructor(props) {
- super(props);
-
- const me = this;
- const options = me.options;
- const time = options.time || (options.time = {});
- const adapter = me._adapter = new adapters._date(options.adapters.date);
-
-
- me._cache = {};
-
- // Backward compatibility: before introducing adapter, `displayFormats` was
- // supposed to contain *all* unit/string pairs but this can't be resolved
- // when loading the scale (adapters are loaded afterward), so let's populate
- // missing formats on update
-
- mergeIf(time.displayFormats, adapter.formats());
- }
-
determineDataLimits() {
const me = this;
const options = me.options;
--- /dev/null
+{
+ "compilerOptions": {
+ "target": "ES6",
+ "moduleResolution": "Node",
+ "allowSyntheticDefaultImports": true,
+ "allowJs": true,
+ "checkJs": true,
+ "noEmit": true
+ },
+ "typedocOptions": {
+ "name": "Chart.js",
+ "excludeExternals": true,
+ "includeVersion": true,
+ "inputFiles": ["./src"],
+ "out": "./dist/docs/typedoc"
+ },
+ "include": [
+ "./src/**/*.js"
+ ]
+}