Fix errors reported by TypeScript compiler (#7030)

This commit is contained in:
Ben McCann 2020-02-07 15:03:33 -08:00 committed by GitHub
parent df407d23f0
commit 795c86e95b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 873 additions and 481 deletions

View File

@ -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)

View File

@ -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

View File

@ -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');
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");
var argv = yargs
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));
});

496
package-lock.json generated
View File

@ -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",

View File

@ -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": {

View File

@ -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 = {

View File

@ -100,6 +100,9 @@ class DoughnutController extends DatasetController {
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
this.innerRadius = undefined;
this.outerRadius = undefined;
}
linkScales() {}

View File

@ -30,6 +30,8 @@ class LineController extends DatasetController {
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
this._showLine = undefined;
}
update(mode) {

View File

@ -94,6 +94,9 @@ class PolarAreaController extends DatasetController {
constructor(chart, datasetIndex) {
super(chart, datasetIndex);
this.innerRadius = undefined;
this.outerRadius = undefined;
}
/**

View File

@ -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'
];

View File

@ -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() {

View File

@ -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;
}
/**

View File

@ -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);
};

View File

@ -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);
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(chart, datasetIndex) {
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;

View File

@ -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() {

View File

@ -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

View File

@ -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);

View File

@ -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
*/
/**

View File

@ -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]);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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 +

View File

@ -152,6 +152,9 @@ function capBezierPoints(points, area) {
}
}
/**
* @private
*/
export function _updateBezierControlPoints(points, options, area, loop) {
var i, ilen, point, controlPoints;

View File

@ -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);

View File

@ -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;

View File

@ -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]);

View File

@ -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 {

View File

@ -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;
}

View File

@ -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'

View File

@ -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 <style>.
* @param {Node} rootNode - the HTMLDocument|ShadowRoot node to contain the <style>.
* @param {string} css - the CSS to be injected.
*/
function injectCSS(rootNode, css) {
@ -346,6 +348,7 @@ export default class DomPlatform extends BasePlatform {
// 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);
}
@ -378,7 +381,7 @@ export default class DomPlatform extends BasePlatform {
releaseContext(context) {
const canvas = context.canvas;
if (!canvas[EXPANDO_KEY]) {
return;
return false;
}
const initial = canvas[EXPANDO_KEY].initial;
@ -404,13 +407,14 @@ export default class DomPlatform extends BasePlatform {
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;
}

View File

@ -10,7 +10,7 @@ import defaults from '../core/core.defaults';
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', {
@ -91,7 +91,9 @@ function computeLinearBoundary(source) {
// 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) {
@ -192,6 +194,7 @@ function getTarget(source) {
if (isArray(boundary)) {
_loop = true;
// @ts-ignore
points = boundary;
} else {
points = pointsFromSegments(boundary, line);
@ -354,14 +357,15 @@ function _fill(ctx, cfg) {
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);
}
@ -411,7 +415,8 @@ export default {
fill: decodeFill(line, i, count),
chart: chart,
scale: meta.vScale,
line
line,
target: undefined
};
}

View File

@ -8,6 +8,10 @@ import {callback as call, extend, mergeIf, valueOrDefault} from '../helpers/help
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',
@ -101,19 +105,43 @@ class Legend extends Element {
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.

View File

@ -23,11 +23,25 @@ class Title extends Element {
constructor(config) {
super();
var me = this;
helpers.extend(me, config);
helpers.extend(this, config);
// Contains hit boxes for each dataset (in dataset order)
me.legendHitBoxes = [];
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.

View File

@ -6,6 +6,10 @@ import Element from '../core/core.element';
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;
@ -199,7 +203,7 @@ function pushOrConcat(base, toPush) {
/**
* 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
*/
@ -449,12 +453,33 @@ function getBeforeAfterBodyLines(callback) {
class Tooltip extends Element {
constructor(config) {
super(config);
super();
const me = this;
me.opacity = 0;
me._active = [];
me.initialize();
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() {

View File

@ -6,6 +6,18 @@ const defaultConfig = {
};
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) {

View File

@ -31,7 +31,10 @@ class LinearScale extends LinearScaleBase {
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;

View File

@ -106,11 +106,27 @@ function generateTicks(generationOptions, dataRange) {
}
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;
}

View File

@ -60,6 +60,20 @@ const defaultConfig = {
};
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) {

View File

@ -253,8 +253,8 @@ function drawRadiusLine(scale, gridLineOpts, radius, index) {
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) {
@ -293,6 +293,20 @@ function numberOrZero(param) {
}
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;

View File

@ -515,6 +515,33 @@ const defaultConfig = {
};
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;
@ -536,25 +563,6 @@ class TimeScale extends Scale {
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;

20
tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"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"
]
}