diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1f02a0e753..b38ee05760 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -53,6 +53,12 @@ One of the following should be checked. ## Misc +### Security Checking + +- [ ] This PR uses security-sensitive Web APIs. + + + ### ZRender Changes - [ ] This PR depends on ZRender changes (ecomfe/zrender#xxx). @@ -61,10 +67,6 @@ One of the following should be checked. N.A. - - -## Others - ### Merging options - [ ] Please squash the commits into a single one when merging. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15bb470e26..71e6d84fbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - name: Collect changed files run: | mkdir ~/tmp/ - git diff ${{ github.event.pull_request.base.sha }} ${{ github.sha }} --diff-filter=ACM --name-only --relative '*src/**/*.ts' > ~/tmp/changed_files + git diff ${{ github.event.pull_request.base.sha }} ${{ github.sha }} --diff-filter=ACM --name-only --relative '*src/*.ts' '*src/**/*.ts' > ~/tmp/changed_files echo -e "Changed files: \n$(cat ~/tmp/changed_files)" - name: Lint diff --git a/.gitignore b/.gitignore index 43197b694e..acc8c8bcb7 100644 --- a/.gitignore +++ b/.gitignore @@ -171,6 +171,9 @@ node_modules test/data/map/tool test/data/map/raw + +/test/types/package-lock.json + theme/thumb pre-publish-tmp todo diff --git a/.husky/pre-commit b/.husky/pre-commit index ec9dcd8d84..e7e681f4b4 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -3,4 +3,3 @@ npm run lint npm run checktype -npm run checkheader diff --git a/build/pre-publish.js b/build/pre-publish.js index e73525901f..f7476b2afe 100644 --- a/build/pre-publish.js +++ b/build/pre-publish.js @@ -239,7 +239,7 @@ async function runTsCompile(localTs, compilerOptions, srcPathList) { } }); if (allDiagnostics.length > 0) { - throw new Error('TypeScript Compile Failed') + throw new Error('TypeScript Compile Failed'); } } module.exports.runTsCompile = runTsCompile; @@ -378,32 +378,43 @@ async function readFilePaths({patterns, cwd}) { async function bundleDTS() { const outDir = nodePath.resolve(__dirname, '../types/dist'); - const commonConfig = { - onwarn(warning, rollupWarn) { - // Not warn circular dependency - if (warning.code !== 'CIRCULAR_DEPENDENCY') { - rollupWarn(warning); - } - }, - plugins: [ - dts({ - respectExternal: true - }) -// { -// generateBundle(options, bundle) { -// for (let chunk of Object.values(bundle)) { -// chunk.code = ` -// type Omit = Pick>; -// ${chunk.code}` -// } -// } -// } - ] - }; + + function createCommonConfig(opt) { + return { + onwarn(warning, rollupWarn) { + // Not warn circular dependency + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + rollupWarn(warning); + } + }, + plugins: [ + dts({ + respectExternal: true, + // - `package.json` `{"type": "module"}` requires explicit file extensions in + // imports; otherwise `tsc` reports error TS(2834). + // - When importing a `.d.ts`, a proper solution can be + // `import {xxx} from "./yyy.js"` instead of `from "./yyy.d.ts"`; otherwise + // `tsc` reports error TS(2846). + // Use `explicitFileExtension: "js"` to use `.js` as the extension of a import paths. + explicitFileExtension: 'js', + umdExportName: opt.umdExportName, + }) + // { + // generateBundle(options, bundle) { + // for (let chunk of Object.values(bundle)) { + // chunk.code = ` + // type Omit = Pick>; + // ${chunk.code}` + // } + // } + // } + ] + }; + } // Bundle chunks. const parts = [ - 'core', 'charts', 'components', 'renderers', 'option', 'features' + 'all', 'core', 'charts', 'components', 'renderers', 'option', 'features' ]; const inputs = {}; parts.forEach(partName => { @@ -412,27 +423,39 @@ async function bundleDTS() { const bundle = await rollup.rollup({ input: inputs, - ...commonConfig + ...createCommonConfig({}) }); - let idx = 1; await bundle.write({ dir: outDir, minifyInternalExports: false, manualChunks: (id) => { - // Only create one chunk. + // Only create one chunk. All of the public entries should import from 'shared.d.ts'; + // otherwise TS error 2442 (Types have separate declarations of a private property) + // may occur. return 'shared'; }, chunkFileNames: 'shared.d.ts' }); - // Bundle all in one - const bundleAllInOne = await rollup.rollup({ + // Bundle a single, self-contained ESM `echarts/types/dist/echarts.d.ts` with no imports, + // for online type checkers (e.g., echarts-examples) usage. + const bundleStandaloneESM = await rollup.rollup({ input: nodePath.resolve(__dirname, `../types/src/export/all.d.ts`), - ...commonConfig + ...createCommonConfig({}) }); - await bundleAllInOne.write({ + await bundleStandaloneESM.write({ file: nodePath.resolve(outDir, 'echarts.d.ts') }); + + // Bundle a UMD `echarts/types/dist/echarts.d.cts`. + // See section "TypeScript entries" in `echarts/package.README.md` for more details. + const bundleStandaloneCJS = await rollup.rollup({ + input: nodePath.resolve(__dirname, `../types/src/export/all.d.ts`), + ...createCommonConfig({umdExportName: 'echarts'}) + }); + await bundleStandaloneCJS.write({ + file: nodePath.resolve(outDir, 'echarts.d.cts') + }); } function readTSConfig() { @@ -451,8 +474,9 @@ function generateEntries() { fs.writeFileSync(nodePath.join(__dirname, `../${entryPath}.js`), jsCode, 'utf-8'); } - // Make the d.ts in the same dir as .js, so that the can be found by tsc. - // package.json "types" in "exports" does not always seam to work. + // Create xxx.d.ts in the same dir with xxx.js, so that they can be found by `tsc`. + // This way is more reliable than using "types" field in `package.json` "exports" + // considering older versions of `tsc`. const dtsCode = fs.readFileSync(nodePath.join(__dirname, `/template/${entryPath}.d.ts`), 'utf-8'); fs.writeFileSync(nodePath.join(__dirname, `../${entryPath}.d.ts`), dtsCode, 'utf-8'); }); diff --git a/build/template/charts.d.ts b/build/template/charts.d.ts index 5c9edfcd9b..fc86b904c5 100644 --- a/build/template/charts.d.ts +++ b/build/template/charts.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/charts'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/charts.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/components.d.ts b/build/template/components.d.ts index 5bb38bef14..0dd838bcc9 100644 --- a/build/template/components.d.ts +++ b/build/template/components.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/components'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/components.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/core.d.ts b/build/template/core.d.ts index c3f461a0eb..3dd3bfe594 100644 --- a/build/template/core.d.ts +++ b/build/template/core.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/core'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/core.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/features.d.ts b/build/template/features.d.ts index 0e9a6fce1c..59b8545bba 100644 --- a/build/template/features.d.ts +++ b/build/template/features.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/features'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/features.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/option.d.ts b/build/template/option.d.ts index 7ebeaaefb4..08c237b50e 100644 --- a/build/template/option.d.ts +++ b/build/template/option.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/option'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/option.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/renderers.d.ts b/build/template/renderers.d.ts index 2fb46e91d3..5dc93f4d3b 100644 --- a/build/template/renderers.d.ts +++ b/build/template/renderers.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/dist/renderers'; \ No newline at end of file +// A pseudo `.js` to redirect to `.d.ts`. +export * from './types/dist/renderers.js'; +// See section "TypeScript entries" in `echarts/package.README.md` for more details. diff --git a/build/template/ssr/client/index.d.ts b/build/template/ssr/client/index.d.ts index 33876e9cf5..3bfcf41ef7 100644 --- a/build/template/ssr/client/index.d.ts +++ b/build/template/ssr/client/index.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export * from './types/index'; +// A pseudo `.js` to redirect to `.d.ts`. +// See `package.README.json` for more details. +export * from './types/index.js'; diff --git a/build/testDts.js b/build/testDts.js index 75dd4099be..112cd2b758 100644 --- a/build/testDts.js +++ b/build/testDts.js @@ -34,30 +34,113 @@ async function installTs() { } async function runTests() { - const compilerOptions = { - declaration: false, - importHelpers: false, - sourceMap: false, - pretty: false, - removeComments: false, - allowJs: false, - outDir: __dirname + '/../test/types/tmp', - typeRoots: [__dirname + '/../types/dist'], - rootDir: __dirname + '/../test/types', - - // Must pass in most strict cases - strict: true - }; - const testsList = await globby(__dirname + '/../test/types/*.ts'); + const casesESM = await globby(__dirname + '/../test/types/esm/*.ts'); + const casesCJS = await globby(__dirname + '/../test/types/cjs/*.ts'); + const casesNoModule = await globby(__dirname + '/../test/types/no-module/*.ts'); const tsVersions = getTypeScriptVersions(); + + function createCompilerOptions(overrideOptions) { + return { + declaration: false, + importHelpers: false, + sourceMap: false, + pretty: false, + removeComments: false, + allowJs: false, + rootDir: __dirname + '/../test/types', + outDir: __dirname + '/../test/types/tmp', + // Disable global types, necessary to avoid other + // irrelevant node_modules types interference. + typeRoots: [], + // Must pass in most strict cases + strict: true, + ...overrideOptions + }; + }; + + async function singleTest(ts, tsVersion, tsconfigModule, tsconfigModuleResolution, testList) { + if (!isSupportedTSConfigModuleField(ts, tsconfigModule)) { + console.log(`Skip: tsVersion: ${tsVersion} does not support {"module": "${tsconfigModule}"}.`); + return; + } + if (!isSupportedTSConfigModuleResolutionField(ts, tsVersion, tsconfigModuleResolution)) { + console.log(`Skip: tsVersion: ${tsVersion} does not support {"moduleResolution": "${tsconfigModuleResolution}"}.`); + return; + } + + console.log(`Testing: tsVersion: ${tsVersion}, tsconfig: {"module": "${tsconfigModule}", "moduleResolution": "${tsconfigModuleResolution}"}`); + await runTsCompile(ts, createCompilerOptions({ + // noEmit: true, + module: tsconfigModule, + moduleResolution: tsconfigModuleResolution, + }), testList); + } + for (const version of tsVersions) { - console.log(`Testing ts version ${version}`); const ts = require(typeScriptPath(version)); - await runTsCompile(ts, compilerOptions, testsList); - console.log(`Finished test of ts version ${version}`); + // console.log(ts.ModuleKind); + // console.log(ts.ModuleResolutionKind); + + // await singleTest(ts, version, undefined , undefined, casesESM); + // await singleTest(ts, version, 'None', 'classic', casesNoModule); + // await singleTest(ts, version, 'CommonJS', 'node', casesESM); + // await singleTest(ts, version, 'CommonJS', 'node', casesCJS); + // await singleTest(ts, version, 'ESNext', 'node', casesESM); + // await singleTest(ts, version, 'ESNext', 'Bundler', casesESM); + await singleTest(ts, version, 'NodeNext', 'NodeNext', casesESM); + // await singleTest(ts, version, 'NodeNext', 'NodeNext', casesCJS); + + console.log(`Finished test of tsVersion ${version}`); + } +} + +function isSupportedTSConfigModuleField(ts, moduleName) { + if (moduleName === undefined) { + return true; + } + const map = { + 'none': 'None', + 'commonjs': 'CommonJS', + 'amd': 'AMD', + 'umd': 'UMD', + 'system': 'System', + 'es6': 'ES2015', + 'es2015': 'ES2015', + 'es2020': 'ES2020', + 'es2022': 'ES2022', + 'esnext': 'ESNext', + 'node16': 'Node16', + 'nodenext': 'NodeNext', + }; + const enumKey = map[moduleName.toLowerCase()]; + return enumKey != null && ts.ModuleKind[enumKey] != null; +} + +function isSupportedTSConfigModuleResolutionField(ts, tsVersion, moduleResolutionName) { + if (moduleResolutionName === undefined) { + return true; } + const map = { + 'classic': 'Classic', + 'node': 'NodeJs', + // 'nodejs': 'NodeJs', // Older TS do not support value "nodejs". + 'node10': 'Node10', + 'node16': 'Node16', + 'nodenext': 'NodeNext', + 'bundler': 'Bundler', + }; + const enumKey = map[moduleResolutionName.toLowerCase()]; + + if (enumKey === 'NodeNext') { + // "NodeNext" is unstable before TSv4.7, and error will be thrown. + if (semver.lt(tsVersion + '.0', '4.7.0')) { + return false; + } + } + + return enumKey != null && ts.ModuleResolutionKind[enumKey] != null; } function getTypeScriptVersions() { diff --git a/index.d.ts b/index.d.ts index 811908a873..f855198b5b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,7 +17,18 @@ * under the License. */ +/** + * @deprecated + * Temporarily retain it in case users reference it like this: + * ```ts + * /// + * var myChart = echarts.init(...); + * ``` + * + * See section "TypeScript entries" in `echarts/package.README.md` for more details. + */ + import * as echarts from './types/dist/echarts'; // Export for UMD module. export as namespace echarts; -export = echarts; \ No newline at end of file +export = echarts; diff --git a/package-lock.json b/package-lock.json index 14d763dcd3..58a25dcfc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,9 @@ "@babel/code-frame": "7.10.4", "@babel/core": "7.3.4", "@babel/types": "7.10.5", - "@definitelytyped/typescript-versions": "^0.1.1", + "@definitelytyped/typescript-versions": "^0.1.9", "@definitelytyped/utils": "0.0.188", - "@lang/rollup-plugin-dts": "2.0.2", + "@lang/rollup-plugin-dts": "2.0.3", "@microsoft/api-extractor": "7.31.2", "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-node-resolve": "^11.0.0", @@ -712,12 +712,20 @@ "node": ">=18.18.0" } }, + "node_modules/@definitelytyped/header-parser/node_modules/@definitelytyped/typescript-versions": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.6.tgz", + "integrity": "sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@definitelytyped/header-parser/node_modules/@definitelytyped/utils": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.8.tgz", "integrity": "sha512-4JINx4Rttha29f50PBsJo48xZXx/He5yaIWJRwVarhYAN947+S84YciHl+AIhQNRPAFkg8+5qFngEGtKxQDWXA==", "dev": true, - "license": "MIT", "dependencies": { "@qiwi/npm-registry-client": "^8.9.1", "@types/node": "^18.19.7", @@ -733,21 +741,19 @@ } }, "node_modules/@definitelytyped/header-parser/node_modules/@types/node": { - "version": "18.19.67", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.67.tgz", - "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==", + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@definitelytyped/header-parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -757,7 +763,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -767,7 +772,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -796,7 +800,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -808,11 +811,10 @@ } }, "node_modules/@definitelytyped/typescript-versions": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.6.tgz", - "integrity": "sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.9.tgz", + "integrity": "sha512-Qjalw9eNlcTjXhzx0Q6kHKuRCOUt/M5RGGRGKsiYlm/nveGvPX9liZSQlGXZVwyQ5I9qvq/GdaWiPchQ+ZXOrQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18.18.0" } @@ -846,9 +848,9 @@ } }, "node_modules/@definitelytyped/utils/node_modules/@types/node": { - "version": "16.18.87", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.87.tgz", - "integrity": "sha512-+IzfhNirR/MDbXz6Om5eHV54D9mQlEMGag6AgEzlju0xH3M8baCXYwqQ6RKgGMpn9wSTx6Ltya/0y4Z8eSfdLw==", + "version": "16.18.126", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", + "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==", "dev": true }, "node_modules/@definitelytyped/utils/node_modules/brace-expansion": { @@ -1708,13 +1710,16 @@ } }, "node_modules/@lang/rollup-plugin-dts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lang/rollup-plugin-dts/-/rollup-plugin-dts-2.0.2.tgz", - "integrity": "sha512-2tVwALesC1o6MpnM9GYHrasV5d0sa5ICaJPhJQXvsnAr7N11W7f8vgSpS8/blOW26Mxdxv90kIUv92j3HP7Ziw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@lang/rollup-plugin-dts/-/rollup-plugin-dts-2.0.3.tgz", + "integrity": "sha512-bZUD1bFulpwT9Ms2fHptfCk8YhHXBSZuQP4zWzfCkjE5TtGX8mulVbb5VbdzBrekoPmEaQ5lmGJGmicG//xrxw==", "dev": true, "dependencies": { "magic-string": "^0.25.7" }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, "optionalDependencies": { "@babel/code-frame": "^7.10.4" }, @@ -3422,7 +3427,6 @@ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -4183,18 +4187,6 @@ "typescript": "*" } }, - "node_modules/dts-critic/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/dtslint": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-4.2.1.tgz", @@ -7928,9 +7920,9 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "dependencies": { "argparse": "^1.0.7", @@ -10844,6 +10836,15 @@ "dev": true, "license": "MIT" }, + "node_modules/tmp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", + "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -11170,8 +11171,7 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/union-value": { "version": "1.0.1", @@ -11397,9 +11397,9 @@ } }, "node_modules/validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", "dev": true, "engines": { "node": ">= 0.10" @@ -12293,6 +12293,12 @@ "semver": "^7.6.3" }, "dependencies": { + "@definitelytyped/typescript-versions": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.6.tgz", + "integrity": "sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==", + "dev": true + }, "@definitelytyped/utils": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.8.tgz", @@ -12310,18 +12316,18 @@ } }, "@types/node": { - "version": "18.19.67", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.67.tgz", - "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==", + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, "requires": { "undici-types": "~5.26.4" } }, "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -12360,9 +12366,9 @@ } }, "@definitelytyped/typescript-versions": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.6.tgz", - "integrity": "sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.9.tgz", + "integrity": "sha512-Qjalw9eNlcTjXhzx0Q6kHKuRCOUt/M5RGGRGKsiYlm/nveGvPX9liZSQlGXZVwyQ5I9qvq/GdaWiPchQ+ZXOrQ==", "dev": true }, "@definitelytyped/utils": { @@ -12388,9 +12394,9 @@ "dev": true }, "@types/node": { - "version": "16.18.87", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.87.tgz", - "integrity": "sha512-+IzfhNirR/MDbXz6Om5eHV54D9mQlEMGag6AgEzlju0xH3M8baCXYwqQ6RKgGMpn9wSTx6Ltya/0y4Z8eSfdLw==", + "version": "16.18.126", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", + "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==", "dev": true }, "brace-expansion": { @@ -13028,9 +13034,9 @@ } }, "@lang/rollup-plugin-dts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lang/rollup-plugin-dts/-/rollup-plugin-dts-2.0.2.tgz", - "integrity": "sha512-2tVwALesC1o6MpnM9GYHrasV5d0sa5ICaJPhJQXvsnAr7N11W7f8vgSpS8/blOW26Mxdxv90kIUv92j3HP7Ziw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@lang/rollup-plugin-dts/-/rollup-plugin-dts-2.0.3.tgz", + "integrity": "sha512-bZUD1bFulpwT9Ms2fHptfCk8YhHXBSZuQP4zWzfCkjE5TtGX8mulVbb5VbdzBrekoPmEaQ5lmGJGmicG//xrxw==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -14907,17 +14913,6 @@ "semver": "^6.2.0", "tmp": "^0.2.1", "yargs": "^15.3.1" - }, - "dependencies": { - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - } } }, "dtslint": { @@ -17663,9 +17658,9 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -19854,6 +19849,12 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, + "tmp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", + "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", + "dev": true + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -20259,9 +20260,9 @@ } }, "validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", "dev": true }, "verror": { diff --git a/package.README.md b/package.README.md index 0960ecbbd9..986c264ed9 100644 --- a/package.README.md +++ b/package.README.md @@ -34,7 +34,81 @@ Since `v5.5.0`, `"type": "module"` and `"exports: {...}"` are added to `package. About `"./types/dist/shared": "./types/dist/shared.d.ts",` in "exports", see https://github.com/apache/echarts/pull/19663 . -## Use physical entry file or alias in `"exports"` of `package.json` +## Use physical entry files or alias in `"exports"` of `package.json` -Although using `"exports"` of `package.json` we can make alias (or say, route) to physical file (for example: `{ "exports": { "./xxx": "./yyy/zzz.js" } }` enables `import 'echarts/xxx'` to route to `'echarts/yyy/zzz.js'`), at present we can not make sure all the versions of bundle tools and runtimes in use do it consistently. So we do not use the alias setting, but keep providing physical file for each public entry. For example, for an official public entry `'echarts/core'`, we provide a file `echarts/core.js` (and `echarts/core.d.ts`). +Although using `"exports"` of `package.json` we can make alias (or say, route) to physical files (for example: `{ "exports": { "./xxx": "./yyy/zzz.js" } }` enables `import 'echarts/xxx'` to route to `'echarts/yyy/zzz.js'`), at present we can not make sure all the versions of bundle tools and runtimes in use do it consistently. So we do not use the alias setting, but keep providing physical files for each public entry. For example, for an official public entry `'echarts/core'`, we provide a file `echarts/core.js` (and `echarts/core.d.ts`). + +## TypeScript entries + +### Why compiling to JS+DTS +For compatibility with older TS versions. +See `MIN_VERSION` in `echarts/build/testDts.js` for the minimal supported TS version. + +### Locate DTS ++ When importing `from "echarts"`: + + dts is configured in `package.json`: + ```json + { + "exports": { ".": { "types": /*...*/ } }, + "types": /*...*/ // fallback + } + ``` ++ When importing `from "echarts/core"` `from "echarts/features"` `from "echarts/components"` `from "echarts/charts"` `from "echarts/renderers"`: + + Use `echarts.core.d.ts` `echarts.features.d.ts` `echarts.components.d.ts` `echarts.charts.d.ts` `echarts.renderers.d.ts` respectively; no `package.json` configuration. + +### DTS entries + ++ ESM: + + dts: + + `echarts.core.d.ts` `echarts.features.d.ts` `echarts.components.d.ts` `echarts.charts.d.ts` `echarts.renderers.d.ts`. + + `echarts/type/dist/all.d.ts`. + + `echarts/ssr/client/index.d.ts`. + ++ CJS (and UMD): + + dts: + + `echarts/types/dist/echarts.d.cts`. + + Usage: + ```ts + // It enables usage in CJS+TS: + import echarts = require('echarts'); + var myChart = echarts.init(/*...*/); + const option: echarts.EChartsOption = {/*...*/}; // Get type in CJS. + myChart.setOption(option); + ``` + ```ts + // It enables usage via UMD global variables: + /// + var myChart = echarts.init(/*...*/); + ``` + ```ts + // However, "echarts/core", "echarts/features", "echarts/components", "echarts/charts", + // "echarts/renderers" have no types supported -- and are not necessary. + ``` + ++ Self-contained entry: + + dts: `echarts/types/dist/echarts.d.ts` + + This is a single, self-contained ESM with no imports, provided for online type checkers (e.g., echarts-examples, https://echarts.apache.org/examples/en/editor.html?c=line-simple) usage. + ++ Legacy entry: + + dts: `index.d.ts`: + + Historically, echarts has been providing a UMD bundle (`echarts/dist/echarts.js`) as one of the default entries, and `index.d.ts` has been corresponding to it. However, since ESM and UMD TS entries were refactored, `index.d.ts` was deprecated and temporarily retained in case users reference it like this: + ```ts + /// + var myChart = echarts.init(/*...*/); + ``` + +### Implementation memo + ++ Separated ESM and CJS(UMD) TS entries: + + Statements `export = echarts` and `export as namespace echarts` provide types for the UMD bundle. However, they effectively mismatches the ESM entry. `tsc` no longer tolerates this mismatch since TS `v5.6` and reports error `TS1203`. Therefore, ESM entries and UMD entries should be separately provided. + ++ Explicit file extensions: + + i.e., `export {some} from "echarts/types/dist/core.js"`, where a pseudo `.js` is used here to redirect to `.d.ts`. + + Explicit file extensions are required when `package.json` uses `"type": "module"` and `tsconfig.json` uses `"moduleResolution": "NodeNext"`; otherwise, if using `"from "echarts/types/dist/core"`, TS error `TS2834` occurs. + + If using `"from "echarts/types/dist/core.d.ts"`, TS error `TS2846` occurs. + ++ Avoid duplicated type declarations: + + `echarts/type/dist/all.d.ts` `echarts/type/dist/core.d.ts` `echarts/type/dist/option.d.ts` `echarts/type/dist/features.d.ts` `echarts/type/dist/components.d.ts` `echarts/type/dist/charts.d.ts` `echarts/type/dist/renderers.d.ts` import type declarations from a single source `echarts/types/dist/shared.d.ts`; otherwise TS error `TS2442` may occur. + ++ TSv4.7~TSv5.7 disallows `require` a ESM file from a CJS file when `moduleResolution: "NodeNext"` (introduced in TSv4.7); otherwise TS error `TS1471` may arise. `tsc` recognizes `.cts` as CJS rather than ESM even when `package.json` uses `"type": "module"`. diff --git a/package.json b/package.json index 1eb8814f61..fd57b487c3 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,9 @@ ], "main": "dist/echarts.js", "module": "index.js", + "unpkg": "dist/echarts.min.js", "jsdelivr": "dist/echarts.min.js", - "types": "index.d.ts", + "types": "types/dist/echarts.d.cts", "homepage": "https://echarts.apache.org", "bugs": { "url": "https://github.com/apache/echarts/issues", @@ -55,7 +56,8 @@ "test": "npx jest --config test/ut/jest.config.cjs", "test:single": "npx jest --config test/ut/jest.config.cjs --coverage=false -t", "test:single:debug": "npx --node-arg=--inspect-brk jest --runInBand --config test/ut/jest.config.cjs --coverage=false -t", - "test:dts": "node build/testDts.js", + "test:dts": "npm install --prefix ./test/types && node build/testDts.js", + "test:dts:fast": "node build/testDts.js", "mktest": "node test/build/mktest.js", "mktest:help": "node test/build/mktest.js -h", "checktype": "tsc --noEmit", @@ -72,9 +74,9 @@ "@babel/code-frame": "7.10.4", "@babel/core": "7.3.4", "@babel/types": "7.10.5", - "@definitelytyped/typescript-versions": "^0.1.1", + "@definitelytyped/typescript-versions": "^0.1.9", "@definitelytyped/utils": "0.0.188", - "@lang/rollup-plugin-dts": "2.0.2", + "@lang/rollup-plugin-dts": "2.0.3", "@microsoft/api-extractor": "7.31.2", "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-node-resolve": "^11.0.0", @@ -106,9 +108,14 @@ "type": "module", "exports": { ".": { - "types": "./index.d.ts", + "types": { + "import": "./types/dist/all.d.ts", + "require": "./types/dist/echarts.d.cts", + "default": "./types/dist/all.d.ts" + }, "import": "./index.js", - "require": "./dist/echarts.js" + "require": "./dist/echarts.js", + "default": "./index.js" }, "./core": "./core.js", "./core.js": "./core.js", @@ -130,6 +137,7 @@ "./index.js": "./index.js", "./theme/*": "./theme/*", "./i18n/*": "./i18n/*", + "./types/dist/all": "./types/dist/all.d.ts", "./types/dist/charts": "./types/dist/charts.d.ts", "./types/dist/components": "./types/dist/components.d.ts", "./types/dist/core": "./types/dist/core.d.ts", @@ -159,6 +167,7 @@ "./lib/chart/bar": "./lib/chart/bar.js", "./lib/chart/boxplot": "./lib/chart/boxplot.js", "./lib/chart/candlestick": "./lib/chart/candlestick.js", + "./lib/chart/chord": "./lib/chart/chord.js", "./lib/chart/custom": "./lib/chart/custom.js", "./lib/chart/effectScatter": "./lib/chart/effectScatter.js", "./lib/chart/funnel": "./lib/chart/funnel.js", diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts index eac83aab02..38fccd44e0 100644 --- a/src/chart/bar/BarView.ts +++ b/src/chart/bar/BarView.ts @@ -1041,8 +1041,8 @@ function updateStyle( ) ) : (isHorizontalOrRadial - ? ((layout as RectLayout).height >= 0 ? 'bottom' : 'top') - : ((layout as RectLayout).width >= 0 ? 'right' : 'left')); + ? getLabelPositionForHorizontal(layout as RectLayout, seriesModel.coordinateSystem) + : getLabelPositionForVertical(layout as RectLayout, seriesModel.coordinateSystem)); const labelStatesModels = getLabelStatesModels(itemModel); @@ -1288,4 +1288,22 @@ function createBackgroundEl( }); } +function getLabelPositionForHorizontal(layout: RectLayout, coordSys: CoordSysOfBar): 'top' | 'bottom' { + if (layout.height === 0) { + // For zero height, determine position based on axis inverse status + const valueAxis = (coordSys as Cartesian2D).getOtherAxis((coordSys as Cartesian2D).getBaseAxis()); + return valueAxis.inverse ? 'bottom' : 'top'; + } + return layout.height > 0 ? 'bottom' : 'top'; +} + +function getLabelPositionForVertical(layout: RectLayout, coordSys: CoordSysOfBar): 'left' | 'right' { + if (layout.width === 0) { + // For zero width, determine position based on axis inverse status + const valueAxis = (coordSys as Cartesian2D).getOtherAxis((coordSys as Cartesian2D).getBaseAxis()); + return valueAxis.inverse ? 'left' : 'right'; + } + return layout.width >= 0 ? 'right' : 'left'; +} + export default BarView; diff --git a/src/chart/boxplot/BoxplotView.ts b/src/chart/boxplot/BoxplotView.ts index f48cdf67b0..0d88309773 100644 --- a/src/chart/boxplot/BoxplotView.ts +++ b/src/chart/boxplot/BoxplotView.ts @@ -46,7 +46,7 @@ class BoxplotView extends ChartView { group.removeAll(); } - const constDim = seriesModel.get('layout') === 'horizontal' ? 1 : 0; + const constDim = seriesModel.getWhiskerBoxesLayout() === 'horizontal' ? 1 : 0; data.diff(oldData) .add(function (newIdx) { diff --git a/src/chart/boxplot/boxplotLayout.ts b/src/chart/boxplot/boxplotLayout.ts index cf6017b3cb..053462d2f2 100644 --- a/src/chart/boxplot/boxplotLayout.ts +++ b/src/chart/boxplot/boxplotLayout.ts @@ -144,7 +144,7 @@ function layoutSingleSeries(seriesModel: BoxplotSeriesModel, offset: number, box const coordSys = seriesModel.coordinateSystem; const data = seriesModel.getData(); const halfWidth = boxWidth / 2; - const cDimIdx = seriesModel.get('layout') === 'horizontal' ? 0 : 1; + const cDimIdx = seriesModel.getWhiskerBoxesLayout() === 'horizontal' ? 0 : 1; const vDimIdx = 1 - cDimIdx; const coordDims = ['x', 'y']; const cDim = data.mapDimension(coordDims[cDimIdx]); diff --git a/src/chart/candlestick/CandlestickSeries.ts b/src/chart/candlestick/CandlestickSeries.ts index f152fce2cf..55938e3b48 100644 --- a/src/chart/candlestick/CandlestickSeries.ts +++ b/src/chart/candlestick/CandlestickSeries.ts @@ -37,6 +37,7 @@ import SeriesData from '../../data/SeriesData'; import Cartesian2D from '../../coord/cartesian/Cartesian2D'; import { BrushCommonSelectorsForSeries } from '../../component/brush/selector'; import { mixin } from 'zrender/src/core/util'; +import type Axis2D from '../../coord/cartesian/Axis2D'; type CandlestickDataValue = OptionDataValue[]; @@ -158,6 +159,9 @@ class CandlestickSeriesModel extends SeriesModel { } } +interface CandlestickSeriesModel extends WhiskerBoxCommonMixin { + getBaseAxis(): Axis2D +} mixin(CandlestickSeriesModel, WhiskerBoxCommonMixin, true); export default CandlestickSeriesModel; diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts index 728291424c..706cae6fcc 100644 --- a/src/chart/candlestick/CandlestickView.ts +++ b/src/chart/candlestick/CandlestickView.ts @@ -106,6 +106,8 @@ class CandlestickView extends ChartView { group.removeAll(); } + const transPointDim = getTransPointDimension(seriesModel); + data.diff(oldData) .add(function (newIdx) { if (data.hasValue(newIdx)) { @@ -115,7 +117,7 @@ class CandlestickView extends ChartView { return; } - const el = createNormalBox(itemLayout, newIdx, true); + const el = createNormalBox(itemLayout, newIdx, transPointDim, true); graphic.initProps(el, {shape: {points: itemLayout.ends}}, seriesModel, newIdx); setBoxCommon(el, data, newIdx, isSimpleBox); @@ -141,7 +143,7 @@ class CandlestickView extends ChartView { } if (!el) { - el = createNormalBox(itemLayout, newIdx); + el = createNormalBox(itemLayout, newIdx, transPointDim); } else { graphic.updateProps(el, { @@ -188,10 +190,12 @@ class CandlestickView extends ChartView { const data = seriesModel.getData(); const isSimpleBox = data.getLayout('isSimpleBox'); + const transPointDim = getTransPointDimension(seriesModel); + let dataIndex; while ((dataIndex = params.next()) != null) { const itemLayout = data.getItemLayout(dataIndex) as CandlestickItemLayout; - const el = createNormalBox(itemLayout, dataIndex); + const el = createNormalBox(itemLayout, dataIndex, transPointDim); setBoxCommon(el, data, dataIndex, isSimpleBox); el.incremental = true; @@ -262,12 +266,17 @@ class NormalBoxPath extends Path { } -function createNormalBox(itemLayout: CandlestickItemLayout, dataIndex: number, isInit?: boolean) { +function createNormalBox( + itemLayout: CandlestickItemLayout, + dataIndex: number, + constDim: number, + isInit?: boolean +) { const ends = itemLayout.ends; return new NormalBoxPath({ shape: { points: isInit - ? transInit(ends, itemLayout) + ? transInit(ends, constDim, itemLayout) : ends }, z2: 100 @@ -310,14 +319,18 @@ function setBoxCommon(el: NormalBoxPath, data: SeriesData, dataIndex: number, is toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); } -function transInit(points: number[][], itemLayout: CandlestickItemLayout) { +function transInit(points: number[][], dim: number, itemLayout: CandlestickItemLayout) { return zrUtil.map(points, function (point) { point = point.slice(); - point[1] = itemLayout.initBaseline; + point[dim] = itemLayout.initBaseline; return point; }); } +function getTransPointDimension(seriesModel: CandlestickSeriesModel): number { + return seriesModel.getWhiskerBoxesLayout() === 'horizontal' ? 1 : 0; +} + class LargeBoxPathShape { diff --git a/src/chart/candlestick/candlestickLayout.ts b/src/chart/candlestick/candlestickLayout.ts index f655b381f0..6b6fa03a6e 100644 --- a/src/chart/candlestick/candlestickLayout.ts +++ b/src/chart/candlestick/candlestickLayout.ts @@ -51,8 +51,8 @@ const candlestickLayout: StageHandler = { const coordSys = seriesModel.coordinateSystem; const data = seriesModel.getData(); const candleWidth = calculateCandleWidth(seriesModel, data); - const cDimIdx = 0; - const vDimIdx = 1; + const cDimIdx = seriesModel.getWhiskerBoxesLayout() === 'horizontal' ? 0 : 1; + const vDimIdx = 1 - cDimIdx; const coordDims = ['x', 'y']; const cDimI = data.getDimensionIndex(data.mapDimension(coordDims[cDimIdx])); const vDimsI = map(data.mapDimensionsAll(coordDims[vDimIdx]), data.getDimensionIndex, data); diff --git a/src/chart/chord.ts b/src/chart/chord.ts new file mode 100644 index 0000000000..0f68ed5ed8 --- /dev/null +++ b/src/chart/chord.ts @@ -0,0 +1,24 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +import { use } from '../extension'; +import { install } from './chord/install'; + +use(install); + diff --git a/src/chart/chord/ChordSeries.ts b/src/chart/chord/ChordSeries.ts index 568f5b96d7..39464d113a 100644 --- a/src/chart/chord/ChordSeries.ts +++ b/src/chart/chord/ChordSeries.ts @@ -21,7 +21,8 @@ import { SeriesOption, SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, OptionDataValue, @@ -115,7 +116,8 @@ export interface ChordEdgeItemOption extends ChordEdgeStateOption, export interface ChordSeriesOption extends SeriesOption, ChordStatesMixin>, - SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin, + SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin, RoamOptionMixin, diff --git a/src/chart/custom/CustomSeries.ts b/src/chart/custom/CustomSeries.ts index 0b5bb5db34..13e526090f 100644 --- a/src/chart/custom/CustomSeries.ts +++ b/src/chart/custom/CustomSeries.ts @@ -37,7 +37,8 @@ import { ParsedValue, SeriesDataType, SeriesEncodeOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, SeriesOnPolarOptionMixin, @@ -363,7 +364,8 @@ export interface CustomSeriesOption extends SeriesOnPolarOptionMixin, SeriesOnSingleOptionMixin, SeriesOnGeoOptionMixin, - SeriesOnCalendarOptionMixin { + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin { type?: 'custom' diff --git a/src/chart/effectScatter/EffectScatterSeries.ts b/src/chart/effectScatter/EffectScatterSeries.ts index 72d40f6bca..ae652031be 100644 --- a/src/chart/effectScatter/EffectScatterSeries.ts +++ b/src/chart/effectScatter/EffectScatterSeries.ts @@ -23,7 +23,8 @@ import { SeriesOption, SeriesOnPolarOptionMixin, SeriesOnCartesianOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin, @@ -66,7 +67,8 @@ export interface EffectScatterDataItemOption extends SymbolOptionMixin, export interface EffectScatterSeriesOption extends SeriesOption, EffectScatterStatesOptionMixin>, EffectScatterStateOption, - SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin, + SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin, SeriesEncodeOptionMixin { diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts index e53eb9036c..c775b759a5 100644 --- a/src/chart/funnel/FunnelSeries.ts +++ b/src/chart/funnel/FunnelSeries.ts @@ -38,7 +38,9 @@ import { SeriesLabelOption, SeriesEncodeOptionMixin, DefaultStatesMixinEmphasis, - CallbackDataParams + CallbackDataParams, + ComponentOnMatrixOptionMixin, + ComponentOnCalendarOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -75,6 +77,7 @@ export interface FunnelDataItemOption export interface FunnelSeriesOption extends SeriesOption, FunnelStatesMixin>, FunnelStateOption, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, SeriesEncodeOptionMixin { type?: 'funnel' diff --git a/src/chart/gauge/GaugeSeries.ts b/src/chart/gauge/GaugeSeries.ts index 1d05e31e6e..ff19b5c1e4 100644 --- a/src/chart/gauge/GaugeSeries.ts +++ b/src/chart/gauge/GaugeSeries.ts @@ -30,7 +30,9 @@ import { StatesOptionMixin, SeriesEncodeOptionMixin, DefaultStatesMixinEmphasis, - CallbackDataParams + CallbackDataParams, + ComponentOnMatrixOptionMixin, + ComponentOnCalendarOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -123,6 +125,7 @@ export interface GaugeDataItemOption extends GaugeStateOption, } export interface GaugeSeriesOption extends SeriesOption, GaugeStateOption, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, CircleLayoutOptionMixin, SeriesEncodeOptionMixin { type?: 'gauge' diff --git a/src/chart/gauge/GaugeView.ts b/src/chart/gauge/GaugeView.ts index edf0edaf26..1df6458a14 100644 --- a/src/chart/gauge/GaugeView.ts +++ b/src/chart/gauge/GaugeView.ts @@ -529,6 +529,7 @@ class GaugeView extends ChartView { const focus = emphasisModel.get('focus'); const blurScope = emphasisModel.get('blurScope'); const emphasisDisabled = emphasisModel.get('disabled'); + const autoColor = getColor(linearMap(data.get(valueDim, idx) as number, valueExtent, [0, 1], true)); if (showPointer) { const pointer = data.getItemGraphicEl(idx) as ECSymbol; const symbolStyle = data.getItemVisual(idx, 'style'); @@ -550,9 +551,7 @@ class GaugeView extends ChartView { if (pointer.style.fill === 'auto') { - pointer.setStyle('fill', getColor( - linearMap(data.get(valueDim, idx) as number, valueExtent, [0, 1], true) - )); + pointer.setStyle('fill', autoColor); } (pointer as ECElement).z2EmphasisLift = 0; @@ -564,6 +563,9 @@ class GaugeView extends ChartView { const progress = progressList[idx]; progress.useStyle(data.getItemVisual(idx, 'style')); progress.setStyle(itemModel.getModel(['progress', 'itemStyle']).getItemStyle()); + if (progress.style.fill === 'auto') { + progress.setStyle('fill', autoColor); + } (progress as ECElement).z2EmphasisLift = 0; setStatesStylesFromModel(progress, itemModel); toggleHoverEmphasis(progress, focus, blurScope, emphasisDisabled); diff --git a/src/chart/graph/GraphSeries.ts b/src/chart/graph/GraphSeries.ts index 88aee86d30..1ef05eb49b 100644 --- a/src/chart/graph/GraphSeries.ts +++ b/src/chart/graph/GraphSeries.ts @@ -27,7 +27,8 @@ import { SeriesOption, SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, OptionDataValue, @@ -140,7 +141,8 @@ export interface GraphCategoryItemOption extends SymbolOptionMixin, export interface GraphSeriesOption extends SeriesOption, GraphNodeStatesMixin>, - SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin, + SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin, RoamOptionMixin, @@ -171,7 +173,7 @@ export interface GraphSeriesOption /** * Symbol size scale ratio in roam */ - nodeScaleRatio?: 0.6, + nodeScaleRatio?: number, draggable?: boolean diff --git a/src/chart/heatmap/HeatmapSeries.ts b/src/chart/heatmap/HeatmapSeries.ts index 84b0a756c5..8d7373e63a 100644 --- a/src/chart/heatmap/HeatmapSeries.ts +++ b/src/chart/heatmap/HeatmapSeries.ts @@ -29,7 +29,8 @@ import { OptionDataValue, StatesOptionMixin, SeriesEncodeOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, DefaultStatesMixinEmphasis, CallbackDataParams } from '../../util/types'; @@ -64,7 +65,8 @@ export interface HeatmapSeriesOption HeatmapStateOption, SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesEncodeOptionMixin { type?: 'heatmap' diff --git a/src/chart/helper/EffectLine.ts b/src/chart/helper/EffectLine.ts index f368d83ac0..195783ed7e 100644 --- a/src/chart/helper/EffectLine.ts +++ b/src/chart/helper/EffectLine.ts @@ -207,7 +207,7 @@ class EffectLine extends graphic.Group { const p1 = symbol.__p1; const p2 = symbol.__p2; const cp1 = symbol.__cp1; - const t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t; + const t = symbol.__t <= 1 ? symbol.__t : 2 - symbol.__t; const pos = [symbol.x, symbol.y]; const lastPos = pos.slice(); const quadraticAt = curveUtil.quadraticAt; @@ -216,9 +216,9 @@ class EffectLine extends graphic.Group { pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t); // Tangent - const tx = symbol.__t < 1 ? quadraticDerivativeAt(p1[0], cp1[0], p2[0], t) + const tx = symbol.__t <= 1 ? quadraticDerivativeAt(p1[0], cp1[0], p2[0], t) : quadraticDerivativeAt(p2[0], cp1[0], p1[0], 1 - t); - const ty = symbol.__t < 1 ? quadraticDerivativeAt(p1[1], cp1[1], p2[1], t) + const ty = symbol.__t <= 1 ? quadraticDerivativeAt(p1[1], cp1[1], p2[1], t) : quadraticDerivativeAt(p2[1], cp1[1], p1[1], 1 - t); diff --git a/src/chart/helper/EffectPolyline.ts b/src/chart/helper/EffectPolyline.ts index 389dbe4d83..282df0725f 100644 --- a/src/chart/helper/EffectPolyline.ts +++ b/src/chart/helper/EffectPolyline.ts @@ -67,7 +67,7 @@ class EffectPolyline extends EffectLine { // Override protected _updateSymbolPosition(symbol: ECSymbolOnEffectLine) { - const t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t; + const t = symbol.__t <= 1 ? symbol.__t : 2 - symbol.__t; const points = this._points; const offsets = this._offsets; const len = points.length; @@ -107,8 +107,8 @@ class EffectPolyline extends EffectLine { symbol.x = p0[0] * (1 - p) + p * p1[0]; symbol.y = p0[1] * (1 - p) + p * p1[1]; - const tx = symbol.__t < 1 ? p1[0] - p0[0] : p0[0] - p1[0]; - const ty = symbol.__t < 1 ? p1[1] - p0[1] : p0[1] - p1[1]; + const tx = symbol.__t <= 1 ? p1[0] - p0[0] : p0[0] - p1[0]; + const ty = symbol.__t <= 1 ? p1[1] - p0[1] : p0[1] - p1[1]; symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; this._lastFrame = frame; diff --git a/src/chart/helper/whiskerBoxCommon.ts b/src/chart/helper/whiskerBoxCommon.ts index efd425afa4..294fd0eae2 100644 --- a/src/chart/helper/whiskerBoxCommon.ts +++ b/src/chart/helper/whiskerBoxCommon.ts @@ -30,6 +30,9 @@ import type Axis2D from '../../coord/cartesian/Axis2D'; import { CoordDimensionDefinition } from '../../data/helper/createDimensions'; interface CommonOption extends SeriesOption, SeriesOnCartesianOptionMixin { + // - 'horizontal': Multiple whisker boxes (each drawn vertically) + // are arranged side by side horizontally. + // - 'vertical': The opposite. layout?: LayoutOrient // data?: (DataItemOption | number[])[] @@ -44,14 +47,15 @@ interface DataItemOption { interface WhiskerBoxCommonMixin extends SeriesModel{} class WhiskerBoxCommonMixin { - /** - * @private - * @type {string} - */ - _baseAxisDim: string; + private _baseAxisDim: string; defaultValueDimensions: CoordDimensionDefinition['dimsDef']; + /** + * Computed layout. + */ + private _layout: CommonOption['layout']; + /** * @private */ @@ -76,25 +80,33 @@ class WhiskerBoxCommonMixin { const yAxisType = yAxisModel.get('type'); let addOrdinal; - // FIXME - // Consider time axis. - + // Theoretically, if `encode` and/or `layout` are not specified, they can be derived from + // the specified one (also according to axis types). However, only the logic for deriving + // `encode` from `layout` is implemented; the reverse direction is not implemented yet, + // due to its complexity and low priority. + let layout = option.layout; + // 'category' axis has historically been enforcing `layout` regardless of its presence. + // This behavior is preserved until it causes problems. if (xAxisType === 'category') { - option.layout = 'horizontal'; + layout = 'horizontal'; ordinalMeta = xAxisModel.getOrdinalMeta(); addOrdinal = !this._hasEncodeRule('x'); } else if (yAxisType === 'category') { - option.layout = 'vertical'; + layout = 'vertical'; ordinalMeta = yAxisModel.getOrdinalMeta(); addOrdinal = !this._hasEncodeRule('y'); } - else { - option.layout = option.layout || 'horizontal'; + if (!layout) { + layout = yAxisType === 'time' ? 'vertical' : 'horizontal'; + // It is theoretically possible for an axis with type "time" to serve as the "value axis". + // `layout` can be explicitly specified for that case. } + // Do not assign the computed `layout` to `option.layout`, otherwise the idempotent may be broken. + this._layout = layout; const coordDims = ['x', 'y']; - const baseAxisDimIndex = option.layout === 'horizontal' ? 0 : 1; + const baseAxisDimIndex = layout === 'horizontal' ? 0 : 1; const baseAxisDim = this._baseAxisDim = coordDims[baseAxisDimIndex]; const otherAxisDim = coordDims[1 - baseAxisDimIndex]; const axisModels = [xAxisModel, yAxisModel]; @@ -166,7 +178,11 @@ class WhiskerBoxCommonMixin { ) as CartesianAxisModel).axis; } + getWhiskerBoxesLayout() { + return this._layout; + } + }; -export {WhiskerBoxCommonMixin}; +export { WhiskerBoxCommonMixin }; diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts index bf1a6cb82f..0cd0c9ef83 100644 --- a/src/chart/line/LineSeries.ts +++ b/src/chart/line/LineSeries.ts @@ -120,7 +120,18 @@ export interface LineSeriesOption extends SeriesOption { @@ -214,7 +225,12 @@ class LineSeriesModel extends SeriesModel { divideShape: 'clone' }, - triggerLineEvent: false + /** + * @deprecated + */ + triggerLineEvent: false, + + triggerEvent: false }; getLegendIcon(opt: LegendIconParams): ECSymbol | Group { diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts index deebe66e22..3682d96512 100644 --- a/src/chart/line/LineView.ts +++ b/src/chart/line/LineView.ts @@ -52,10 +52,10 @@ import { setStatesStylesFromModel, setStatesFlag, toggleHoverEmphasis, SPECIAL_S import Model from '../../model/Model'; import { setLabelStyle, getLabelStatesModels, labelInner } from '../../label/labelStyle'; import { getDefaultLabel, getDefaultInterpolatedLabel } from '../helper/labelHelper'; - import { getECData } from '../../util/innerStore'; import { createFloat32Array } from '../../util/vendor'; import { convertToColorString } from '../../util/format'; +import { warnDeprecated } from '../../util/styleCompat'; import { lerp } from 'zrender/src/tool/color'; import Element from 'zrender/src/Element'; @@ -132,7 +132,7 @@ function getStackedOnPoints( data: SeriesData, dataCoordInfo: ReturnType ) { - if (!dataCoordInfo.valueDim) { + if (dataCoordInfo.valueDim == null) { return []; } @@ -621,7 +621,7 @@ class LineView extends ChartView { _endLabel: graphic.Text; _polyline: ECPolyline; - _polygon: ECPolygon; + _polygon?: ECPolygon; _stackedOnPoints: ArrayLike; _points: ArrayLike; @@ -920,21 +920,31 @@ class LineView extends ChartView { this._step = step; this._valueOrigin = valueOrigin; - if (seriesModel.get('triggerLineEvent')) { - this.packEventData(seriesModel, polyline); - polygon && this.packEventData(seriesModel, polygon); + const triggerEvent = seriesModel.get('triggerEvent'); + const triggerLineEvent = seriesModel.get('triggerLineEvent'); + + if (__DEV__) { + triggerLineEvent && warnDeprecated('triggerLineEvent', 'Use the `triggerEvent` option instead.'); } + + const shouldTriggerLineEvent = triggerLineEvent === true || triggerEvent === true || triggerEvent === 'line'; + const shouldTriggerAreaEvent = triggerLineEvent === true || triggerEvent === true || triggerEvent === 'area'; + + this.packEventData(seriesModel, polyline, shouldTriggerLineEvent); + polygon && this.packEventData(seriesModel, polygon, shouldTriggerAreaEvent); } - private packEventData(seriesModel: LineSeriesModel, el: Element) { - getECData(el).eventData = { + private packEventData(seriesModel: LineSeriesModel, el: Element, enable: boolean) { + getECData(el).eventData = enable ? { componentType: 'series', componentSubType: 'line', componentIndex: seriesModel.componentIndex, seriesIndex: seriesModel.seriesIndex, seriesName: seriesModel.name, - seriesType: 'line' - }; + seriesType: 'line', + // for determining this event is triggered by area or line + selfType: el === this._polygon ? 'area' : 'line' + } : null; } highlight( diff --git a/src/chart/lines/LinesSeries.ts b/src/chart/lines/LinesSeries.ts index 2c1fc29c88..c83330edb1 100644 --- a/src/chart/lines/LinesSeries.ts +++ b/src/chart/lines/LinesSeries.ts @@ -28,7 +28,8 @@ import { SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, SeriesOnPolarOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesLargeOptionMixin, LineStyleOption, OptionDataValue, @@ -113,7 +114,7 @@ export interface LinesDataItemOption extends LinesStateOption, export interface LinesSeriesOption extends SeriesOption, LinesStateOption, SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, SeriesOnPolarOptionMixin, - SeriesOnCalendarOptionMixin, SeriesLargeOptionMixin { + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SeriesLargeOptionMixin { type?: 'lines' diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts index 294c1a57df..90a8299df1 100644 --- a/src/chart/map/MapSeries.ts +++ b/src/chart/map/MapSeries.ts @@ -34,7 +34,9 @@ import { StatesOptionMixin, SeriesLabelOption, StatesMixinBase, - CallbackDataParams + CallbackDataParams, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import { Dictionary } from 'zrender/src/core/types'; import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption } from '../../coord/geo/GeoModel'; @@ -70,6 +72,8 @@ export interface MapSeriesOption extends // created. Otherwise use the specified geo component, and // `map` and `mapType` are ignored. SeriesOnGeoOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, SeriesEncodeOptionMixin { type?: 'map' diff --git a/src/chart/parallel/ParallelSeries.ts b/src/chart/parallel/ParallelSeries.ts index 91546ae293..d2088d19d9 100644 --- a/src/chart/parallel/ParallelSeries.ts +++ b/src/chart/parallel/ParallelSeries.ts @@ -35,7 +35,9 @@ import { OptionEncode, DefaultStatesMixinEmphasis, ZRColor, - CallbackDataParams + CallbackDataParams, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -60,6 +62,8 @@ export interface ParallelSeriesDataItemOption extends ParallelStateOption, export interface ParallelSeriesOption extends SeriesOption, ParallelStatesMixin>, ParallelStateOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesEncodeOptionMixin { type?: 'parallel'; diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts index e86b645610..496d9a5e6a 100644 --- a/src/chart/pie/PieSeries.ts +++ b/src/chart/pie/PieSeries.ts @@ -36,7 +36,11 @@ import { OptionDataItemObject, StatesOptionMixin, SeriesLabelOption, - DefaultEmphasisFocus + DefaultEmphasisFocus, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, + SeriesOnGeoOptionMixin, + SeriesOnCartesianOptionMixin } from '../../util/types'; import type SeriesData from '../../data/SeriesData'; import { registerLayOutOnCoordSysUsage } from '../../core/CoordinateSystem'; @@ -64,7 +68,7 @@ export interface PieStateOption { labelLine?: PieLabelLineOption } interface PieLabelOption extends Omit { - rotate?: number | boolean | 'radial' | 'tangential' + rotate?: number | boolean | 'radial' | 'tangential' | 'tangential-noflip' alignTo?: 'none' | 'labelLine' | 'edge' edgeDistance?: string | number /** @@ -102,6 +106,10 @@ export interface PieSeriesOption extends Omit, ExtraStateOption>, 'labelLine'>, PieStateOption, CircleLayoutOptionMixin<{centerExtra: string | number}>, + SeriesOnGeoOptionMixin, + SeriesOnCartesianOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, SeriesEncodeOptionMixin { diff --git a/src/chart/pie/labelLayout.ts b/src/chart/pie/labelLayout.ts index b99d118577..e617e61895 100644 --- a/src/chart/pie/labelLayout.ts +++ b/src/chart/pie/labelLayout.ts @@ -484,7 +484,7 @@ export default function pieLabelLayout( const radialAngle = nx < 0 ? -midAngle + PI : -midAngle; labelRotate = radialAngle; } - else if (rotate === 'tangential' + else if (rotate === 'tangential' || rotate === 'tangential-noflip' && labelPosition !== 'outside' && labelPosition !== 'outer' ) { let rad = Math.atan2(nx, ny); @@ -492,7 +492,7 @@ export default function pieLabelLayout( rad = PI * 2 + rad; } const isDown = ny > 0; - if (isDown) { + if (isDown && rotate !== 'tangential-noflip') { rad = PI + rad; } labelRotate = rad - PI; diff --git a/src/chart/radar/RadarSeries.ts b/src/chart/radar/RadarSeries.ts index 1405ac074b..2d2a93d5db 100644 --- a/src/chart/radar/RadarSeries.ts +++ b/src/chart/radar/RadarSeries.ts @@ -33,7 +33,8 @@ import { OptionDataItemObject, SeriesEncodeOptionMixin, CallbackDataParams, - DefaultStatesMixinEmphasis + DefaultStatesMixinEmphasis, + SeriesOnRadarOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -61,14 +62,11 @@ export interface RadarSeriesDataItemOption extends SymbolOptionMixin, export interface RadarSeriesOption extends SeriesOption, - RadarSeriesStateOption, + RadarSeriesStateOption, SeriesOnRadarOptionMixin, SymbolOptionMixin, SeriesEncodeOptionMixin { type?: 'radar' coordinateSystem?: 'radar' - radarIndex?: number - radarId?: string - data?: (RadarSeriesDataItemOption | RadarSeriesDataValue)[] } diff --git a/src/chart/sankey/SankeySeries.ts b/src/chart/sankey/SankeySeries.ts index 9409f56df6..ebd85227ab 100644 --- a/src/chart/sankey/SankeySeries.ts +++ b/src/chart/sankey/SankeySeries.ts @@ -35,7 +35,9 @@ import { OptionDataValueNumeric, DefaultEmphasisFocus, CallbackDataParams, - RoamOptionMixin + RoamOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -99,6 +101,8 @@ export interface SankeySeriesOption extends SeriesOption, ExtraStateOption>, SankeyBothStateOption, BoxLayoutOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, RoamOptionMixin { type?: 'sankey' diff --git a/src/chart/scatter/ScatterSeries.ts b/src/chart/scatter/ScatterSeries.ts index 9dfe667735..053addcc9e 100644 --- a/src/chart/scatter/ScatterSeries.ts +++ b/src/chart/scatter/ScatterSeries.ts @@ -23,7 +23,8 @@ import { SeriesOption, SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, - SeriesOnCalendarOptionMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, OptionDataValue, @@ -63,7 +64,8 @@ export interface ScatterDataItemOption extends SymbolOptionMixin, export interface ScatterSeriesOption extends SeriesOption, ScatterStatesOptionMixin>, ScatterStateOption, - SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin, + SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SeriesLargeOptionMixin, SeriesStackOptionMixin, SymbolOptionMixin, SeriesEncodeOptionMixin { diff --git a/src/chart/sunburst/SunburstPiece.ts b/src/chart/sunburst/SunburstPiece.ts index 0925f16f94..edff517300 100644 --- a/src/chart/sunburst/SunburstPiece.ts +++ b/src/chart/sunburst/SunburstPiece.ts @@ -234,7 +234,7 @@ class SunburstPiece extends graphic.Sector { else { if (!textAlign || textAlign === 'center') { // Put label in the center if it's a circle - if (angle === 2 * Math.PI && layout.r0 === 0) { + if (layout.r0 === 0 && isRadianAroundZero(angle - 2 * Math.PI)) { r = 0; } else { diff --git a/src/chart/sunburst/SunburstSeries.ts b/src/chart/sunburst/SunburstSeries.ts index f4b8b94324..795b9c5a53 100644 --- a/src/chart/sunburst/SunburstSeries.ts +++ b/src/chart/sunburst/SunburstSeries.ts @@ -31,7 +31,9 @@ import { StatesOptionMixin, OptionDataItemObject, DefaultEmphasisFocus, - SunburstColorByMixin + SunburstColorByMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import SeriesData from '../../data/SeriesData'; @@ -122,6 +124,8 @@ export interface SunburstSeriesOption extends SeriesOption, SunburstStatesMixin>, SunburstStateOption, SunburstColorByMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, CircleLayoutOptionMixin { type?: 'sunburst' diff --git a/src/chart/tree/TreeSeries.ts b/src/chart/tree/TreeSeries.ts index c00ce26c9b..6c8826f74b 100644 --- a/src/chart/tree/TreeSeries.ts +++ b/src/chart/tree/TreeSeries.ts @@ -31,7 +31,9 @@ import { StatesOptionMixin, OptionDataItemObject, CallbackDataParams, - DefaultEmphasisFocus + DefaultEmphasisFocus, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import SeriesData from '../../data/SeriesData'; import View from '../../coord/View'; @@ -83,6 +85,7 @@ export interface TreeSeriesLeavesOption export interface TreeSeriesOption extends SeriesOption, TreeSeriesStateOption, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, SymbolOptionMixin, BoxLayoutOptionMixin, RoamOptionMixin { type?: 'tree' diff --git a/src/chart/treemap/TreemapSeries.ts b/src/chart/treemap/TreemapSeries.ts index 9776d40684..4618ec464a 100644 --- a/src/chart/treemap/TreemapSeries.ts +++ b/src/chart/treemap/TreemapSeries.ts @@ -37,7 +37,9 @@ import { SeriesLabelOption, DefaultEmphasisFocus, AriaOptionMixin, - BlurScope + BlurScope, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import GlobalModel from '../../model/Global'; import { LayoutRect } from '../../util/layout'; @@ -153,6 +155,8 @@ export interface TreemapSeriesNodeItemOption extends TreemapSeriesVisualOption, export interface TreemapSeriesOption extends SeriesOption, ExtraStateOption>, TreemapStateOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, RoamOptionMixin, TreemapSeriesVisualOption { diff --git a/src/component/dataZoom/DataZoomModel.ts b/src/component/dataZoom/DataZoomModel.ts index 0fd8d78015..279c06a13b 100644 --- a/src/component/dataZoom/DataZoomModel.ts +++ b/src/component/dataZoom/DataZoomModel.ts @@ -32,7 +32,7 @@ import { getAxisMainType, DATA_ZOOM_AXIS_DIMENSIONS, DataZoomAxisDimension } from './helper'; import SingleAxisModel from '../../coord/single/AxisModel'; -import { MULTIPLE_REFERRING, SINGLE_REFERRING } from '../../util/model'; +import { MULTIPLE_REFERRING, SINGLE_REFERRING, ModelFinderIndexQuery, ModelFinderIdQuery } from '../../util/model'; export interface DataZoomOption extends ComponentOption { @@ -47,22 +47,22 @@ export interface DataZoomOption extends ComponentOption { /** * Default the first horizontal category axis. */ - xAxisIndex?: number | number[] - xAxisId?: string | string[] + xAxisIndex?: ModelFinderIndexQuery + xAxisId?: ModelFinderIdQuery /** * Default the first vertical category axis. */ - yAxisIndex?: number | number[] - yAxisId?: string | string[] + yAxisIndex?: ModelFinderIndexQuery + yAxisId?: ModelFinderIdQuery - radiusAxisIndex?: number | number[] - radiusAxisId?: string | string[] - angleAxisIndex?: number | number[] - angleAxisId?: string | string[] + radiusAxisIndex?: ModelFinderIndexQuery + radiusAxisId?: ModelFinderIdQuery + angleAxisIndex?: ModelFinderIndexQuery + angleAxisId?: ModelFinderIdQuery - singleAxisIndex?: number | number[] - singleAxisId?: string | string[] + singleAxisIndex?: ModelFinderIndexQuery + singleAxisId?: ModelFinderIdQuery /** * Possible values: 'filter' or 'empty' or 'weakFilter'. diff --git a/src/component/dataZoom/SliderZoomModel.ts b/src/component/dataZoom/SliderZoomModel.ts index 75c9d51ea6..80d206842a 100644 --- a/src/component/dataZoom/SliderZoomModel.ts +++ b/src/component/dataZoom/SliderZoomModel.ts @@ -24,7 +24,9 @@ import { LineStyleOption, AreaStyleOption, ItemStyleOption, - LabelOption + LabelOption, + ComponentOnMatrixOptionMixin, + ComponentOnCalendarOptionMixin } from '../../util/types'; import { inheritDefaultOption } from '../../util/component'; import tokens from '../../visual/tokens'; @@ -33,7 +35,9 @@ interface SliderHandleLabelOption { show?: boolean } -export interface SliderDataZoomOption extends DataZoomOption, BoxLayoutOptionMixin { +export interface SliderDataZoomOption + extends DataZoomOption, BoxLayoutOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { show?: boolean /** @@ -124,7 +128,7 @@ export interface SliderDataZoomOption extends DataZoomOption, BoxLayoutOptionMix brushStyle?: ItemStyleOption emphasis?: { - handleLabel: SliderHandleLabelOption + handleLabel?: SliderHandleLabelOption handleStyle?: ItemStyleOption moveHandleStyle?: ItemStyleOption }, diff --git a/src/component/dataZoom/SliderZoomView.ts b/src/component/dataZoom/SliderZoomView.ts index b542817ed8..30422c9c52 100644 --- a/src/component/dataZoom/SliderZoomView.ts +++ b/src/component/dataZoom/SliderZoomView.ts @@ -294,8 +294,11 @@ class SliderZoomView extends DataZoomView { // Position barGroup const rect = thisGroup.getBoundingRect([sliderGroup]); - thisGroup.x = location.x - rect.x; - thisGroup.y = location.y - rect.y; + const rectX = isNaN(rect.x) ? 0 : rect.x; + const rectY = isNaN(rect.y) ? 0 : rect.y; + + thisGroup.x = location.x - rectX; + thisGroup.y = location.y - rectY; thisGroup.markRedraw(); } diff --git a/src/component/legend/LegendModel.ts b/src/component/legend/LegendModel.ts index 3a62a26b12..e03fe26f89 100644 --- a/src/component/legend/LegendModel.ts +++ b/src/component/legend/LegendModel.ts @@ -30,7 +30,9 @@ import { LayoutOrient, CommonTooltipOption, ItemStyleOption, - LineStyleOption + LineStyleOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import { Dictionary } from 'zrender/src/core/types'; import GlobalModel from '../../model/Global'; @@ -158,8 +160,8 @@ export interface LegendSymbolStyleOption { } export interface LegendOption extends ComponentOption, LegendStyleOption, - BoxLayoutOptionMixin, BorderOptionMixin -{ + BoxLayoutOptionMixin, BorderOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { mainType?: 'legend' diff --git a/src/component/matrix/MatrixView.ts b/src/component/matrix/MatrixView.ts index 4c236cc0fd..022ba938cd 100644 --- a/src/component/matrix/MatrixView.ts +++ b/src/component/matrix/MatrixView.ts @@ -31,7 +31,8 @@ import { LineShape } from 'zrender/src/graphic/shape/Line'; import { subPixelOptimize } from 'zrender/src/graphic/helper/subPixelOptimize'; import { Group, Text, Rect, Line, XY, setTooltipConfig, expandOrShrinkRect } from '../../util/graphic'; import { clearTmpModel, ListIterator } from '../../util/model'; -import { clone, retrieve2 } from 'zrender/src/core/util'; +import { clone, retrieve2, isFunction, isString } from 'zrender/src/core/util'; +import { formatTplSimple } from '../../util/format'; import { invert } from 'zrender/src/core/matrix'; import { MatrixBodyCorner, MatrixBodyOrCornerKind } from '../../coord/matrix/MatrixBodyCorner'; import { setLabelStyle } from '../../label/labelStyle'; @@ -289,12 +290,33 @@ function createMatrixCell( let cellText: Text | NullUndefined; if (textValue != null) { - const text = textValue + ''; + let text = textValue + ''; _tmpCellLabelModel.option = cellOption ? cellOption.label : null; _tmpCellLabelModel.parentModel = parentLabelModel; // This is to accept `option.textStyle` as the default. _tmpCellLabelModel.ecModel = ecModel; + const formatter = _tmpCellLabelModel.getShallow('formatter'); + if (formatter) { + const params = { + componentType: 'matrix' as const, + componentIndex: matrixModel.componentIndex, + name: text, + value: textValue as unknown, + coord: xyLocator.slice() as MatrixXYLocator[], + $vars: ['name', 'value', 'coord'] as const + }; + if (isString(formatter)) { + text = formatTplSimple(formatter, params); + } + else if (isFunction(formatter)) { + const formattedText = formatter(params); + if (formattedText != null) { + text = formattedText + ''; + } + } + } + setLabelStyle( cellRect, // Currently do not support other states (`emphasis`, `select`, `blur`) diff --git a/src/component/thumbnail/ThumbnailModel.ts b/src/component/thumbnail/ThumbnailModel.ts index 7f480dc5ac..1086bcf340 100644 --- a/src/component/thumbnail/ThumbnailModel.ts +++ b/src/component/thumbnail/ThumbnailModel.ts @@ -20,7 +20,8 @@ import ComponentModel from '../../model/Component'; import { error } from '../../util/log'; import { - BorderOptionMixin, BoxLayoutOptionMixin, ComponentOption, ItemStyleOption, NullUndefined, + BoxLayoutOptionMixin, ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, ComponentOption, ItemStyleOption, NullUndefined, } from '../../util/types'; import tokens from '../../visual/tokens'; import { @@ -37,7 +38,10 @@ import { ThumbnailBridgeImpl } from './ThumbnailBridgeImpl'; // TODO: currently only graph supports thumbnail. // May need some refactor if serving new components in future. -export interface ThumbnailOption extends ComponentOption, BoxLayoutOptionMixin, BorderOptionMixin { +export interface ThumbnailOption extends + ComponentOption, BoxLayoutOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { + mainType?: 'thumbnail' show?: boolean diff --git a/src/component/timeline/TimelineModel.ts b/src/component/timeline/TimelineModel.ts index 3027dcedc0..d366589d99 100644 --- a/src/component/timeline/TimelineModel.ts +++ b/src/component/timeline/TimelineModel.ts @@ -32,7 +32,9 @@ import { ColorString, CommonTooltipOption, CallbackDataParams, - ZREasing + ZREasing, + ComponentOnMatrixOptionMixin, + ComponentOnCalendarOptionMixin } from '../../util/types'; import Model from '../../model/Model'; import GlobalModel, { GlobalModelSetOptionOpts } from '../../model/Global'; @@ -102,7 +104,10 @@ export interface TimelineDataItemOption extends SymbolOptionMixin { tooltip?: boolean } -export interface TimelineOption extends ComponentOption, BoxLayoutOptionMixin, SymbolOptionMixin { +export interface TimelineOption extends ComponentOption, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, + BoxLayoutOptionMixin, SymbolOptionMixin { + mainType?: 'timeline' backgroundColor?: ZRColor diff --git a/src/component/title/install.ts b/src/component/title/install.ts index d127ad0464..7e96acf9c1 100644 --- a/src/component/title/install.ts +++ b/src/component/title/install.ts @@ -30,7 +30,9 @@ import { ZRTextVerticalAlign, ZRColor, BorderOptionMixin, - LabelOption + LabelOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import ComponentView from '../../view/Component'; import GlobalModel from '../../model/Global'; @@ -43,7 +45,9 @@ interface TitleTextStyleOption extends LabelOption { width?: number } -export interface TitleOption extends ComponentOption, BoxLayoutOptionMixin, BorderOptionMixin { +export interface TitleOption extends + ComponentOption, BoxLayoutOptionMixin, BorderOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { mainType?: 'title' diff --git a/src/component/toolbox/ToolboxModel.ts b/src/component/toolbox/ToolboxModel.ts index ba3786f01e..49debe77b5 100644 --- a/src/component/toolbox/ToolboxModel.ts +++ b/src/component/toolbox/ToolboxModel.ts @@ -29,7 +29,9 @@ import { ItemStyleOption, LabelOption, CommonTooltipOption, - Dictionary + Dictionary, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import tokens from '../../visual/tokens'; @@ -40,9 +42,13 @@ export interface ToolboxTooltipFormatterParams { title: string $vars: ['name', 'title'] } -export interface ToolboxOption extends ComponentOption, +export interface ToolboxOption extends + ComponentOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, BorderOptionMixin { + mainType?: 'toolbox' show?: boolean @@ -141,7 +147,7 @@ class ToolboxModel extends ComponentModel { }, emphasis: { iconStyle: { - borderColor: tokens.color.accent50 + borderColor: tokens.color.accent70 } }, // textStyle: {}, diff --git a/src/component/tooltip/TooltipView.ts b/src/component/tooltip/TooltipView.ts index 2d259799ac..11d965f8ec 100644 --- a/src/component/tooltip/TooltipView.ts +++ b/src/component/tooltip/TooltipView.ts @@ -243,6 +243,12 @@ class TooltipView extends ComponentView { const api = this._api; const triggerOn = tooltipModel.get('triggerOn'); + if (tooltipModel.get('trigger') !== 'axis') { + // _lastDataByCoordSys and _cbParamsList are used for axis tooltip only. + this._lastDataByCoordSys = null; + this._cbParamsList = null; + } + // Try to keep the tooltip show when refreshing if (this._lastX != null && this._lastY != null @@ -393,6 +399,7 @@ class TooltipView extends ComponentView { } this._lastX = this._lastY = this._lastDataByCoordSys = null; + this._cbParamsList = null; if (payload.from !== this.uid) { this._hide(makeDispatchAction(payload, api)); @@ -468,6 +475,7 @@ class TooltipView extends ComponentView { return; } this._lastDataByCoordSys = null; + this._cbParamsList = null; let seriesDispatcher: Element; let cmptDispatcher: Element; @@ -501,6 +509,7 @@ class TooltipView extends ComponentView { } else { this._lastDataByCoordSys = null; + this._cbParamsList = null; this._hide(dispatchAction); } } @@ -1027,6 +1036,7 @@ class TooltipView extends ComponentView { // FIXME // duplicated hideTip if manuallyHideTip is called from dispatchAction. this._lastDataByCoordSys = null; + this._cbParamsList = null; dispatchAction({ type: 'hideTip', from: this.uid @@ -1040,6 +1050,11 @@ class TooltipView extends ComponentView { clear(this, '_updatePosition'); this._tooltipContent.dispose(); globalListener.unregister('itemTooltip', api); + + this._tooltipContent = null; + this._tooltipModel = null; + this._lastDataByCoordSys = null; + this._cbParamsList = null; } } diff --git a/src/component/visualMap/VisualMapModel.ts b/src/component/visualMap/VisualMapModel.ts index 9139d54e8c..843387a465 100644 --- a/src/component/visualMap/VisualMapModel.ts +++ b/src/component/visualMap/VisualMapModel.ts @@ -33,7 +33,9 @@ import { OptionDataValue, BuiltinVisualProperty, DimensionIndex, - OptionId + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, + OptionId, } from '../../util/types'; import ComponentModel from '../../model/Component'; import Model from '../../model/Model'; @@ -56,6 +58,8 @@ type LabelFormatter = (min: OptionDataValue, max?: OptionDataValue) => string; type VisualState = VisualMapModel['stateList'][number]; export interface VisualMapOption extends ComponentOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, BorderOptionMixin { @@ -70,8 +74,8 @@ export interface VisualMapOption * 'all' or null/undefined: all series. * A number or an array of number: the specified series. */ - seriesIndex?: 'all' | number[] | number - seriesId?: OptionId | OptionId[] + seriesIndex?: modelUtil.ModelFinderIndexQuery + seriesId?: modelUtil.ModelFinderIdQuery /** * set min: 0, max: 200, only for campatible with ec2. @@ -89,6 +93,16 @@ export interface VisualMapOption */ dimension?: number + /** + * Series targets with specific dimensions + * When provided, seriesIndex, seriesId, and dimension are ignored + */ + seriesTargets?: { + seriesIndex?: number + seriesId?: OptionId + dimension: number + }[] + /** * Visual configuration for the data in selection */ @@ -243,6 +257,30 @@ class VisualMapModel extends Com * @return An array of series indices. */ protected getTargetSeriesIndices(): number[] { + const seriesTargets = this.option.seriesTargets; + if (seriesTargets) { + // When seriesTargets is provided, collect all target series indices + const indices: number[] = []; + each(seriesTargets, (target) => { + if (target.seriesIndex != null) { + indices.push(target.seriesIndex); + } + else if (target.seriesId != null) { + // Find series by ID + let seriesModel: SeriesModel; + this.ecModel.eachSeries(function (series) { + if (series.id === target.seriesId) { + seriesModel = series; + } + }); + if (seriesModel) { + indices.push(seriesModel.componentIndex); + } + } + }); + return indices; + } + const optionSeriesId = this.option.seriesId; let optionSeriesIndex = this.option.seriesIndex; if (optionSeriesIndex == null && optionSeriesId == null) { @@ -402,8 +440,23 @@ class VisualMapModel extends Com // } // } + getDimension(seriesIndex: number): number { + const seriesTargets = this.option.seriesTargets; + if (seriesTargets) { + const target = zrUtil.find(seriesTargets, target => + (target.seriesIndex != null && target.seriesIndex === seriesIndex) + || (target.seriesId != null && target.seriesId === this.ecModel.getSeriesByIndex(seriesIndex).id) + ); + if (target) { + return target.dimension; + } + } + return this.option.dimension; + } + getDataDimensionIndex(data: SeriesData): DimensionIndex { - const optDim = this.option.dimension; + const seriesIndex = (data.hostModel as any).seriesIndex; + const optDim = this.getDimension(seriesIndex); if (optDim != null) { return data.getDimensionIndex(optDim); diff --git a/src/component/visualMap/preprocessor.ts b/src/component/visualMap/preprocessor.ts index 08ba687c1d..6e86e06970 100644 --- a/src/component/visualMap/preprocessor.ts +++ b/src/component/visualMap/preprocessor.ts @@ -53,6 +53,21 @@ export default function visualMapPreprocessor(option) { } }); } + + // Validate seriesTargets + if (__DEV__) { + const seriesTargets = opt.seriesTargets; + if (seriesTargets && zrUtil.isArray(seriesTargets)) { + each(seriesTargets, function (target) { + if (!zrUtil.isObject(target) || target.dimension == null) { + console.warn('Each seriesTarget should have a dimension property'); + } + if (target.seriesIndex == null && target.seriesId == null) { + console.warn('Each seriesTarget should have either seriesIndex or seriesId'); + } + }); + } + } }); } diff --git a/src/coord/View.ts b/src/coord/View.ts index 14935ac3d5..44351c03af 100644 --- a/src/coord/View.ts +++ b/src/coord/View.ts @@ -159,7 +159,7 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy if (opt && opt.api && opt.ecModel && opt.ecModel.getShallow('legacyViewCoordSysCenterBase') && centerCoord) { centerCoord = [ parsePercent(centerCoord[0], opt.api.getWidth()), - parsePercent(centerCoord[1], opt.api.getWidth()) + parsePercent(centerCoord[1], opt.api.getHeight()) ]; } diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts index 3d22ee7ef0..4291a0729c 100644 --- a/src/coord/axisCommonTypes.ts +++ b/src/coord/axisCommonTypes.ts @@ -102,14 +102,14 @@ export interface AxisBaseOptionCommon extends ComponentOption, * + 'dataMin': use the min value in data. * + null/undefined: auto decide min value (consider pretty look and boundaryGap). */ - min?: ScaleDataValue | 'dataMin' | ((extent: {min: number, max: number}) => ScaleDataValue); + min?: ScaleDataValue | 'dataMin' | ((extent: {min: number, max: number}) => ScaleDataValue | NullUndefined); /** * Max value of the axis. can be: * + ScaleDataValue * + 'dataMax': use the max value in data. * + null/undefined: auto decide max value (consider pretty look and boundaryGap). */ - max?: ScaleDataValue | 'dataMax' | ((extent: {min: number, max: number}) => ScaleDataValue); + max?: ScaleDataValue | 'dataMax' | ((extent: {min: number, max: number}) => ScaleDataValue | NullUndefined); startValue?: number; jitter?: number; @@ -123,7 +123,7 @@ export interface AxisBaseOptionCommon extends ComponentOption, zigzagAmplitude?: number; zigzagMinSpan?: number; zigzagMaxSpan?: number; - zigzagZ: number; + zigzagZ?: number; expandOnClick?: boolean; }; breakLabelLayout?: { @@ -163,6 +163,20 @@ export interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon { * Will be ignored if interval is set. */ alignTicks?: boolean + + /** + * Data min value to be included in axis extent calculation. + * The final min value will be the minimum of this value and the data min. + * Only works for value axis. + */ + dataMin?: ScaleDataValue; + + /** + * Data max value to be included in axis extent calculation. + * The final max value will be the maximum of this value and the data max. + * Only works for value axis. + */ + dataMax?: ScaleDataValue; } export interface CategoryAxisBaseOption extends AxisBaseOptionCommon { diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts index 1ca67f5558..ab344dec68 100644 --- a/src/coord/axisTickLabelBuilder.ts +++ b/src/coord/axisTickLabelBuilder.ts @@ -130,10 +130,10 @@ export function createAxisLabels(axis: Axis, ctx: AxisLabelsComputingContext): { const tickNumbers = tickValuesToNumbers(axis, custom); const ticks = zrUtil.filter(tickNumbers, val => val >= extent[0] && val <= extent[1]); return { - labels: zrUtil.map(ticks, numval => { + labels: zrUtil.map(ticks, (numval, index) => { const tick = {value: numval}; return { - formattedLabel: labelFormatter(tick), + formattedLabel: labelFormatter(tick, index), rawLabel: axis.scale.getLabel(tick), tickValue: numval, time: undefined as ScaleTick['time'] | NullUndefined, diff --git a/src/coord/cartesian/GridModel.ts b/src/coord/cartesian/GridModel.ts index 5461319b6c..ba8341841b 100644 --- a/src/coord/cartesian/GridModel.ts +++ b/src/coord/cartesian/GridModel.ts @@ -19,7 +19,10 @@ import ComponentModel from '../../model/Component'; -import { ComponentOption, BoxLayoutOptionMixin, ZRColor, ShadowOptionMixin, NullUndefined } from '../../util/types'; +import { + ComponentOption, BoxLayoutOptionMixin, ZRColor, ShadowOptionMixin, NullUndefined, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin +} from '../../util/types'; import Grid from './Grid'; import { CoordinateSystemHostModel } from '../CoordinateSystem'; import type GlobalModel from '../../model/Global'; @@ -31,8 +34,9 @@ import tokens from '../../visual/tokens'; export const OUTER_BOUNDS_DEFAULT = {left: 0, right: 0, top: 0, bottom: 0}; export const OUTER_BOUNDS_CLAMP_DEFAULT = ['25%', '25%']; -export interface GridOption - extends ComponentOption, BoxLayoutOptionMixin, ShadowOptionMixin { +export interface GridOption extends ComponentOption, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, + BoxLayoutOptionMixin, ShadowOptionMixin { mainType?: 'grid'; diff --git a/src/coord/geo/GeoModel.ts b/src/coord/geo/GeoModel.ts index 72f0252bd6..a55fcc804d 100644 --- a/src/coord/geo/GeoModel.ts +++ b/src/coord/geo/GeoModel.ts @@ -37,7 +37,9 @@ import { Dictionary, CommonTooltipOption, StatesMixinBase, - PreserveAspectMixin + PreserveAspectMixin, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import { GeoProjection, NameMap } from './geoTypes'; import GlobalModel from '../../model/Global'; @@ -81,8 +83,10 @@ export interface GeoTooltipFormatterParams { } export interface GeoCommonOptionMixin extends RoamOptionMixin, PreserveAspectMixin { + // When series.map use an external geo component, all of the properties should not be set. + // Map name - map: string; + map?: string; // Aspect is width / height. Inited to be geoJson bbox aspect // This parameter is used for scale this aspect @@ -119,6 +123,8 @@ export interface GeoCommonOptionMixin extends RoamOptionMixin, PreserveAspectMix export interface GeoOption extends ComponentOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, BoxLayoutOptionMixin, // For lens animation on geo. AnimationOptionMixin, diff --git a/src/coord/matrix/MatrixDim.ts b/src/coord/matrix/MatrixDim.ts index 764d762c50..ed407bf0c0 100644 --- a/src/coord/matrix/MatrixDim.ts +++ b/src/coord/matrix/MatrixDim.ts @@ -149,6 +149,7 @@ export class MatrixDim { this._uniqueValueGen = createUniqueValueGenerator(dim); let dimModelData = dimModel.get('data', true); + const length = dimModel.get('length', true); if (dimModelData != null && !isArray(dimModelData)) { if (__DEV__) { error(`Illegal echarts option - matrix.${this.dim}.data must be an array if specified.`); @@ -158,6 +159,13 @@ export class MatrixDim { if (dimModelData) { this._initByDimModelData(dimModelData); } + else if (length != null) { + dimModelData = Array(length); + for (let i = 0; i < length; i++) { + dimModelData[i] = null; + } + this._initByDimModelData(dimModelData); + } else { this._initBySeriesData(); } diff --git a/src/coord/matrix/MatrixModel.ts b/src/coord/matrix/MatrixModel.ts index bcaae24bb0..b6b0e53291 100644 --- a/src/coord/matrix/MatrixModel.ts +++ b/src/coord/matrix/MatrixModel.ts @@ -158,6 +158,9 @@ interface MatrixDimensionOption extends MatrixCellStyleOption, MatrixDimensionLe type?: 'category'; // For internal usage; force be 'category'. show?: boolean; data?: MatrixDimensionCellLooseOption[]; + // A simple way to provide column/row count if no need to compose a `data`. + // Note: `length` is ignored if `data` is specified. + length?: number; // `levels[0]`: the topmost (for x dimension) or leftmost (for y dimension) level. // If not specified, use null/undefined, such as `levels: [null, null, {levelSize: 10}]` levels?: (MatrixDimensionLevelOption | NullUndefined)[]; @@ -169,7 +172,7 @@ export interface MatrixDimensionCellOption extends MatrixBaseCellOption { // Do not use type `OrdinalRawValue` here. Number input is forbiden due to the possible confusion. // e.g., if `matrix.x.data: [1, 2, 3]` is allowed, then querying `coord: [1, null]` will actually get // the second column, since number represents the index (i.e. `MatrixXYLocator` or `OrdinalNumber`). - value?: string; + value?: string | NullUndefined; // column width (for x dimension) or row height (for y dimension). // If not specified (null/undefined), auto calculate it. // Only available on leaves, to avoid unnecessary complex. @@ -192,6 +195,19 @@ export interface MatrixDimensionLevelOption { export interface MatrixDimensionModel extends Model { } +export interface MatrixLabelOption extends LabelOption { + formatter?: string | ((params: MatrixLabelFormatterParams) => string); +} + +export interface MatrixLabelFormatterParams { + componentType: 'matrix'; + componentIndex: number; + name: string; + value: unknown; + coord: MatrixXYLocator[]; + $vars: readonly ['name', 'value', 'coord']; +} + /** * Two levels of cascade inheritance: * - priority-high: style options defined in `matrix.x/y/coner/body.data[i]` (in cell) @@ -206,7 +222,7 @@ export interface MatrixCellStyleOption { // The text truncation rect is obtained by cell rect minus by padding. // - The inner series / other coord sys padding is not supported, to avoid necessary complexity. // Consider some series, such as heatmap, prefer no padding. - label?: LabelOption; + label?: MatrixLabelOption; itemStyle?: ItemStyleOption; cursor?: string; // By default, auto decide whether to be silent, considering tooltip. diff --git a/src/coord/parallel/Parallel.ts b/src/coord/parallel/Parallel.ts index 5108bbf914..6566cb1215 100644 --- a/src/coord/parallel/Parallel.ts +++ b/src/coord/parallel/Parallel.ts @@ -185,9 +185,14 @@ class Parallel implements CoordinateSystemMaster, CoordinateSystem { each(this.dimensions, function (dim) { const axis = this._axesMap.get(dim); axis.scale.unionExtentFromData(data, data.mapDimension(dim)); - axisHelper.niceScaleExtent(axis.scale, axis.model); }, this); }, this); + + // do after all series processed + each(this.dimensions, function (dim) { + const axis = this._axesMap.get(dim); + axisHelper.niceScaleExtent(axis.scale, axis.model); + }, this); } /** diff --git a/src/coord/parallel/ParallelModel.ts b/src/coord/parallel/ParallelModel.ts index edbe7c4846..4ca648bb39 100644 --- a/src/coord/parallel/ParallelModel.ts +++ b/src/coord/parallel/ParallelModel.ts @@ -21,7 +21,10 @@ import * as zrUtil from 'zrender/src/core/util'; import ComponentModel from '../../model/Component'; import Parallel from './Parallel'; -import { DimensionName, ComponentOption, BoxLayoutOptionMixin } from '../../util/types'; +import { + DimensionName, ComponentOption, BoxLayoutOptionMixin, ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin +} from '../../util/types'; import ParallelAxisModel, { ParallelAxisOption } from './AxisModel'; import GlobalModel from '../../model/Global'; import ParallelSeriesModel from '../../chart/parallel/ParallelSeries'; @@ -30,7 +33,12 @@ import SeriesModel from '../../model/Series'; export type ParallelLayoutDirection = 'horizontal' | 'vertical'; -export interface ParallelCoordinateSystemOption extends ComponentOption, BoxLayoutOptionMixin { +export interface ParallelCoordinateSystemOption extends + ComponentOption, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin, + BoxLayoutOptionMixin { + mainType?: 'parallel'; layout?: ParallelLayoutDirection; diff --git a/src/coord/polar/PolarModel.ts b/src/coord/polar/PolarModel.ts index 65dc0ebd44..60133aaa7c 100644 --- a/src/coord/polar/PolarModel.ts +++ b/src/coord/polar/PolarModel.ts @@ -17,12 +17,18 @@ * under the License. */ -import { ComponentOption, CircleLayoutOptionMixin } from '../../util/types'; +import { + ComponentOption, CircleLayoutOptionMixin, ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin +} from '../../util/types'; import ComponentModel from '../../model/Component'; import Polar from './Polar'; import { AngleAxisModel, RadiusAxisModel } from './AxisModel'; -export interface PolarOption extends ComponentOption, CircleLayoutOptionMixin { +export interface PolarOption extends + ComponentOption, CircleLayoutOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { + mainType?: 'polar'; } diff --git a/src/coord/radar/Radar.ts b/src/coord/radar/Radar.ts index 6ce88ec75f..c0fb4df295 100644 --- a/src/coord/radar/Radar.ts +++ b/src/coord/radar/Radar.ts @@ -126,6 +126,7 @@ class Radar implements CoordinateSystem, CoordinateSystemMaster { const refContainer = createBoxLayoutReference(radarModel, api).refContainer; const center = radarModel.get('center'); + const clockwise = radarModel.get('clockwise') || false; const viewSize = Math.min(refContainer.width, refContainer.height) / 2; this.cx = numberUtil.parsePercent(center[0], refContainer.width) + refContainer.x; this.cy = numberUtil.parsePercent(center[1], refContainer.height) + refContainer.y; @@ -140,9 +141,11 @@ class Radar implements CoordinateSystem, CoordinateSystemMaster { this.r0 = numberUtil.parsePercent(radius[0], viewSize); this.r = numberUtil.parsePercent(radius[1], viewSize); + const sign = clockwise ? -1 : 1; + each(this._indicatorAxes, function (indicatorAxis, idx) { indicatorAxis.setExtent(this.r0, this.r); - let angle = (this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length); + let angle = (this.startAngle + sign * idx * Math.PI * 2 / this._indicatorAxes.length); // Normalize to [-PI, PI] angle = Math.atan2(Math.sin(angle), Math.cos(angle)); indicatorAxis.angle = angle; diff --git a/src/coord/radar/RadarModel.ts b/src/coord/radar/RadarModel.ts index 4723a34541..60fe2060aa 100644 --- a/src/coord/radar/RadarModel.ts +++ b/src/coord/radar/RadarModel.ts @@ -26,7 +26,9 @@ import { ComponentOption, CircleLayoutOptionMixin, LabelOption, - ColorString + ColorString, + ComponentOnCalendarOptionMixin, + ComponentOnMatrixOptionMixin } from '../../util/types'; import { AxisBaseOption, CategoryAxisBaseOption, ValueAxisBaseOption } from '../axisCommonTypes'; import { AxisBaseModel } from '../AxisBaseModel'; @@ -55,11 +57,16 @@ export interface RadarIndicatorOption { axisType?: 'value' | 'log' } -export interface RadarOption extends ComponentOption, CircleLayoutOptionMixin { +export interface RadarOption extends + ComponentOption, CircleLayoutOptionMixin, + ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin { + mainType?: 'radar' startAngle?: number + clockwise?: boolean + shape?: 'polygon' | 'circle' // TODO. axisType seems to have issue. @@ -106,6 +113,7 @@ class RadarModel extends ComponentModel implements CoordinateSystem optionUpdated() { const boundaryGap = this.get('boundaryGap'); const splitNumber = this.get('splitNumber'); + const clockwise = this.get('clockwise'); const scale = this.get('scale'); const axisLine = this.get('axisLine'); const axisTick = this.get('axisTick'); @@ -135,6 +143,7 @@ class RadarModel extends ComponentModel implements CoordinateSystem const innerIndicatorOpt: InnerIndicatorAxisOption = zrUtil.merge(zrUtil.clone(indicatorOpt), { boundaryGap: boundaryGap, splitNumber: splitNumber, + clockwise: clockwise, scale: scale, axisLine: axisLine, axisTick: axisTick, @@ -187,6 +196,8 @@ class RadarModel extends ComponentModel implements CoordinateSystem startAngle: 90, + clockwise: false, + axisName: { show: true, color: tokens.color.axisLabel diff --git a/src/coord/scaleRawExtentInfo.ts b/src/coord/scaleRawExtentInfo.ts index 78c29cc0cf..389b98c3b1 100644 --- a/src/coord/scaleRawExtentInfo.ts +++ b/src/coord/scaleRawExtentInfo.ts @@ -21,7 +21,7 @@ import { assert, isArray, eqNaN, isFunction } from 'zrender/src/core/util'; import Scale from '../scale/Scale'; import { AxisBaseModel } from './AxisBaseModel'; import { parsePercent } from 'zrender/src/contain/text'; -import { AxisBaseOption, CategoryAxisBaseOption } from './axisCommonTypes'; +import { AxisBaseOption, CategoryAxisBaseOption, NumericAxisBaseOptionCommon } from './axisCommonTypes'; import { ScaleDataValue } from '../util/types'; @@ -69,6 +69,9 @@ export class ScaleRawExtentInfo { // Make that the `rawExtentInfo` can not be modified any more. readonly frozen: boolean; + // custom dataMin/dataMax + private _dataMinNum: number; + private _dataMaxNum: number; constructor( scale: Scale, @@ -98,6 +101,19 @@ export class ScaleRawExtentInfo { const isOrdinal = this._isOrdinal = scale.type === 'ordinal'; this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero(); + if (scale.type === 'interval' || scale.type === 'log' || scale.type === 'time') { + // Process custom dataMin/dataMax + const dataMinRaw = (model as AxisBaseModel).get('dataMin', true); + if (dataMinRaw != null) { + this._dataMinNum = parseAxisModelMinMax(scale, dataMinRaw); + } + + const dataMaxRaw = (model as AxisBaseModel).get('dataMax', true); + if (dataMaxRaw != null) { + this._dataMaxNum = parseAxisModelMinMax(scale, dataMaxRaw); + } + } + let axisMinValue = model.get('min', true); if (axisMinValue == null) { axisMinValue = model.get('startValue', true); @@ -173,8 +189,20 @@ export class ScaleRawExtentInfo { // (3) If no data, it should be ensured that `scale.setBlank` is set. const isOrdinal = this._isOrdinal; - const dataMin = this._dataMin; - const dataMax = this._dataMax; + let dataMin = this._dataMin; + let dataMax = this._dataMax; + + // Include custom dataMin/dataMax in calculation + // If dataMin is set and less than current data minimum, update the minimum value + if (this._dataMinNum != null && isFinite(dataMin) && this._dataMinNum < dataMin) { + dataMin = this._dataMinNum; + } + + // If dataMax is set and greater than current data maximum, update the maximum value + if (this._dataMaxNum != null && isFinite(dataMax) && this._dataMaxNum > dataMax) { + dataMax = this._dataMaxNum; + } + const axisDataLen = this._axisDataLen; const boundaryGapInner = this._boundaryGapInner; diff --git a/src/coord/single/AxisModel.ts b/src/coord/single/AxisModel.ts index 4301959c8f..a65e149c88 100644 --- a/src/coord/single/AxisModel.ts +++ b/src/coord/single/AxisModel.ts @@ -23,7 +23,9 @@ import {AxisModelCommonMixin} from '../axisModelCommonMixin'; import Single from './Single'; import SingleAxis from './SingleAxis'; import { AxisBaseOption } from '../axisCommonTypes'; -import { BoxLayoutOptionMixin, LayoutOrient } from '../../util/types'; +import { + BoxLayoutOptionMixin, ComponentOnCalendarOptionMixin, ComponentOnMatrixOptionMixin, LayoutOrient +} from '../../util/types'; import { AxisBaseModel } from '../AxisBaseModel'; import { mixin } from 'zrender/src/core/util'; @@ -33,7 +35,7 @@ export type SingleAxisOption = AxisBaseOption & BoxLayoutOptionMixin & { mainType?: 'singleAxis' position?: SingleAxisPosition orient?: LayoutOrient -}; +} & ComponentOnCalendarOptionMixin & ComponentOnMatrixOptionMixin; class SingleAxisModel extends ComponentModel implements AxisBaseModel { diff --git a/src/core/echarts.ts b/src/core/echarts.ts index b37012ae37..89f810088b 100644 --- a/src/core/echarts.ts +++ b/src/core/echarts.ts @@ -437,6 +437,9 @@ class ECharts extends Eventful { opts = opts || {}; + // mark the echarts instance as raw in Vue 3 to prevent the object being converted to be a proxy. + (this as any).__v_skip = true; + this._dom = dom; let defaultRenderer = 'canvas'; diff --git a/src/data/DataStore.ts b/src/data/DataStore.ts index 38227916ed..9bcc88e9a7 100644 --- a/src/data/DataStore.ts +++ b/src/data/DataStore.ts @@ -1088,8 +1088,8 @@ class DataStore { * Data iteration * @param ctx default this * @example - * list.each('x', function (x, idx) {}); - * list.each(['x', 'y'], function (x, y, idx) {}); + * list.each(0, function (x, idx) {}); + * list.each([0, 1], function (x, y, idx) {}); * list.each(function (idx) {}) */ each(dims: DimensionIndex[], cb: EachCb): void { diff --git a/src/data/SeriesData.ts b/src/data/SeriesData.ts index 9a824c05a4..472d3b3c7e 100644 --- a/src/data/SeriesData.ts +++ b/src/data/SeriesData.ts @@ -884,6 +884,8 @@ class SeriesData< * @example * list.each('x', function (x, idx) {}); * list.each(['x', 'y'], function (x, y, idx) {}); + * list.each(0, function (x, idx) {}); + * list.each([0, 1], function (x, y, idx) {}); * list.each(function (idx) {}) */ each(cb: EachCb0, ctx?: Ctx, ctxCompat?: Ctx): void; diff --git a/src/export/all.ts b/src/export/all.ts index 8778a8bb23..bc736a21d9 100644 --- a/src/export/all.ts +++ b/src/export/all.ts @@ -18,6 +18,8 @@ */ // This file is for providing types when import whole module. +// components/charts/renderers/... do not need to be exported here, +// since this is only used for the standalone export. export * from './core'; export * from './option'; diff --git a/src/export/option.ts b/src/export/option.ts index 1859271193..a490494e55 100644 --- a/src/export/option.ts +++ b/src/export/option.ts @@ -26,8 +26,11 @@ import type { AngleAxisOption as AngleAxisComponentOption } from '../coord/polar/AxisModel'; import type { + // Historical typo, deprecated but still exported for compatibility. XAXisOption as XAXisComponentOption, - YAXisOption as YAXisComponentOption + YAXisOption as YAXisComponentOption, + XAXisOption as XAxisComponentOption, + YAXisOption as YAxisComponentOption, } from '../coord/cartesian/AxisModel'; import type {SingleAxisOption as SingleAxisComponentOption} from '../coord/single/AxisModel'; import type {ParallelAxisOption as ParallelAxisComponentOption} from '../coord/parallel/AxisModel'; @@ -153,6 +156,8 @@ export { GeoComponentOption, XAXisComponentOption, YAXisComponentOption, + XAxisComponentOption, + YAxisComponentOption, SingleAxisComponentOption, RadiusAxisComponentOption, AngleAxisComponentOption, diff --git a/src/label/labelGuideHelper.ts b/src/label/labelGuideHelper.ts index 1177ceef09..1b80597f80 100644 --- a/src/label/labelGuideHelper.ts +++ b/src/label/labelGuideHelper.ts @@ -540,13 +540,13 @@ function setLabelLineState( stateObj.ignore = ignore; // Set smooth let smooth = stateModel.get('smooth'); - if (smooth && smooth === true) { - smooth = 0.3; - } + smooth = smooth === true ? 0.3 : Math.max(+smooth, 0) || 0; + stateObj.shape = stateObj.shape || {}; - if (smooth > 0) { - (stateObj.shape as Polyline['shape']).smooth = smooth as number; - } + + // always set the `smooth` property + (stateObj.shape as Polyline['shape']).smooth = smooth; + const styleObj = stateModel.getModel('lineStyle').getLineStyle(); isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj; } diff --git a/src/scale/Time.ts b/src/scale/Time.ts index 07f589867e..a3a7de479c 100644 --- a/src/scale/Time.ts +++ b/src/scale/Time.ts @@ -206,8 +206,10 @@ class TimeScale extends IntervalScale { let upperUnitIndex = primaryTimeUnits.length - 1; let maxLevel = 0; each(ticks, tick => { - upperUnitIndex = Math.min(upperUnitIndex, indexOf(primaryTimeUnits, tick.time.upperTimeUnit)); - maxLevel = Math.max(maxLevel, tick.time.level); + if (tick.time) { + upperUnitIndex = Math.min(upperUnitIndex, indexOf(primaryTimeUnits, tick.time.upperTimeUnit)); + maxLevel = Math.max(maxLevel, tick.time.level); + } }); if (scaleBreakHelper) { diff --git a/src/theme/dark.ts b/src/theme/dark.ts index 0b43606232..3da1abcec3 100644 --- a/src/theme/dark.ts +++ b/src/theme/dark.ts @@ -103,6 +103,16 @@ const theme = { toolbox: { iconStyle: { borderColor: color.accent50 + }, + feature: { + dataView: { + backgroundColor: backgroundColor, + textColor: color.primary, + textareaColor: color.background, + textareaBorderColor: color.border, + buttonColor: color.accent50, + buttonTextColor: color.neutral00 + } } }, tooltip: { diff --git a/src/util/model.ts b/src/util/model.ts index ee7637bda9..1b23063cbd 100644 --- a/src/util/model.ts +++ b/src/util/model.ts @@ -767,9 +767,9 @@ let innerUniqueIndex = getRandomIdBase(); * If both `abcIndex`, `abcId`, `abcName` specified, only one work. * The priority is: index > id > name, the same with `ecModel.queryComponents`. */ -export type ModelFinderIndexQuery = number | number[] | 'all' | 'none' | false; -export type ModelFinderIdQuery = OptionId | OptionId[]; -export type ModelFinderNameQuery = OptionId | OptionId[]; +export type ModelFinderIndexQuery = number | number[] | 'all' | 'none' | false | NullUndefined; +export type ModelFinderIdQuery = OptionId | OptionId[] | NullUndefined; +export type ModelFinderNameQuery = OptionId | OptionId[] | NullUndefined; // If string, like 'series', means { seriesIndex: 0 }. export type ModelFinder = string | ModelFinderObject; export type ModelFinderObject = { diff --git a/src/util/time.ts b/src/util/time.ts index 5157c63f41..6c6ed6bfe8 100644 --- a/src/util/time.ts +++ b/src/util/time.ts @@ -343,7 +343,7 @@ export function leveledFormat( else if (zrUtil.isFunction(formatter)) { const extra: TimeAxisLabelFormatterExtraParams = { time: tick.time, - level: tick.time.level, + level: tick.time ? tick.time.level : 0, }; const scaleBreakHelper = getScaleBreakHelper(); if (scaleBreakHelper) { diff --git a/src/util/types.ts b/src/util/types.ts index 2a37e39a0f..1d6521d51e 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -1946,33 +1946,38 @@ export interface SeriesOnCartesianOptionMixin { xAxisIndex?: number yAxisIndex?: number - xAxisId?: string - yAxisId?: string + xAxisId?: OptionId + yAxisId?: OptionId } export interface SeriesOnPolarOptionMixin { polarIndex?: number - polarId?: string; + polarId?: OptionId; } export interface SeriesOnSingleOptionMixin { singleAxisIndex?: number - singleAxisId?: string + singleAxisId?: OptionId } export interface SeriesOnGeoOptionMixin { geoIndex?: number; - geoId?: string + geoId?: OptionId } -export interface SeriesOnCalendarOptionMixin { +export interface SeriesOnRadarOptionMixin { + radarIndex?: number; + radarId?: OptionId +} + +export interface ComponentOnCalendarOptionMixin { calendarIndex?: number - calendarId?: string + calendarId?: OptionId } export interface ComponentOnMatrixOptionMixin { matrixIndex?: number - matrixId?: string + matrixId?: OptionId } export interface SeriesLargeOptionMixin { diff --git a/test/axis-customTicks.html b/test/axis-customTicks.html index 7f79f099d8..9aa8ec04e3 100644 --- a/test/axis-customTicks.html +++ b/test/axis-customTicks.html @@ -40,6 +40,7 @@
+
+ + diff --git a/test/axis-data-min-max.html b/test/axis-data-min-max.html new file mode 100644 index 0000000000..e0d510aa11 --- /dev/null +++ b/test/axis-data-min-max.html @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/test/axisLabel.html b/test/axisLabel.html index 16a08effb4..f50a7cb00f 100644 --- a/test/axisLabel.html +++ b/test/axisLabel.html @@ -46,6 +46,7 @@
+
+ + diff --git a/test/bar-zero-label.html b/test/bar-zero-label.html new file mode 100644 index 0000000000..c69de751a3 --- /dev/null +++ b/test/bar-zero-label.html @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + +

Bar chart zero value label position test

+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/test/candlestick-horizontal.html b/test/candlestick-horizontal.html new file mode 100644 index 0000000000..bc5fb0db42 --- /dev/null +++ b/test/candlestick-horizontal.html @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/test/check-build.html b/test/check-build.html index f11ed16ce6..43fb01452c 100644 --- a/test/check-build.html +++ b/test/check-build.html @@ -22,8 +22,8 @@ - - + +
\ No newline at end of file diff --git a/test/dataZoom-single-datapoint.html b/test/dataZoom-single-datapoint.html new file mode 100644 index 0000000000..bd78b45554 --- /dev/null +++ b/test/dataZoom-single-datapoint.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/test/echarts-in-vue.html b/test/echarts-in-vue.html new file mode 100644 index 0000000000..0f0b49eaf4 --- /dev/null +++ b/test/echarts-in-vue.html @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + diff --git a/test/gauge-progress.html b/test/gauge-progress.html index 82239497cf..97de79129e 100644 --- a/test/gauge-progress.html +++ b/test/gauge-progress.html @@ -346,6 +346,58 @@ chart5.setOption(option5, true); }}] }); + var option6 = { + tooltip: { + formatter: '{a}
{b} : {c}%' + }, + toolbox: { + feature: { + restore: {}, + saveAsImage: {} + } + }, + series: [ + { + name: '业务指标', + type: 'gauge', + axisLine: { + lineStyle: { + width: 5, + color: [ + [0.3, '#67e0e3'], + [0.7, '#37a2da'], + [1, '#fd666d'] + ] + } + }, + progress:{ + show:true, + overlap:true, + width:-10, + itemStyle: { + color: 'auto' + } + }, + pointer: { + show: false, + }, + data: [ + {value: 50, name: '本月跑步'} + ], + } + ] + }; + var chart6 = testHelper.create(echarts, 'main6', { + title: [ + 'progress.itemStyle.color: \'auto\'' + ], + renderer: 'svg', + option: option6 + }); + setInterval(function () { + option6.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0; + chart6.setOption(option6, true); + }, 2000); }); diff --git a/test/line-area-empty-dimension-name.html b/test/line-area-empty-dimension-name.html new file mode 100644 index 0000000000..9d0b41eb43 --- /dev/null +++ b/test/line-area-empty-dimension-name.html @@ -0,0 +1,60 @@ + + + + + Line Area Empty Dimension Name Test + + + + + + +
+ + + + diff --git a/test/lines-symbol.html b/test/lines-symbol.html index 560da4b6c8..d22371fb3f 100644 --- a/test/lines-symbol.html +++ b/test/lines-symbol.html @@ -23,27 +23,19 @@ - - - + + + - -
- + + - \ No newline at end of file + diff --git a/test/matrix-label-formatter.html b/test/matrix-label-formatter.html new file mode 100644 index 0000000000..e3f2e22f8b --- /dev/null +++ b/test/matrix-label-formatter.html @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + diff --git a/test/matrix.html b/test/matrix.html index 66bd853224..7fffee5e03 100644 --- a/test/matrix.html +++ b/test/matrix.html @@ -46,6 +46,7 @@
+
@@ -664,6 +665,49 @@ + + + + + + diff --git a/test/parallel-bounds.html b/test/parallel-bounds.html new file mode 100644 index 0000000000..59605ceacc --- /dev/null +++ b/test/parallel-bounds.html @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + +

normal

+
+

Max and Min of second series outside first second axis inverse

+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/test/pie-coordinate-system-amap.html b/test/pie-coordinate-system-amap.html new file mode 100644 index 0000000000..0a5a67f5e6 --- /dev/null +++ b/test/pie-coordinate-system-amap.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + +
+ + + + + + + diff --git a/test/pie-coordinate-system-bmap.html b/test/pie-coordinate-system-bmap.html new file mode 100644 index 0000000000..a8be144331 --- /dev/null +++ b/test/pie-coordinate-system-bmap.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/test/pie-coordinate-system.html b/test/pie-coordinate-system.html index cdc8bf0073..c44c74bc52 100644 --- a/test/pie-coordinate-system.html +++ b/test/pie-coordinate-system.html @@ -22,8 +22,6 @@ - - @@ -39,10 +37,7 @@
-
-
-
- - - diff --git a/test/pie-label-rotate.html b/test/pie-label-rotate.html index 91ecea316a..ef061473b5 100644 --- a/test/pie-label-rotate.html +++ b/test/pie-label-rotate.html @@ -63,6 +63,7 @@

Pie series label rotate

undefined, 'radial', 'tangential', + 'tangential-noflip', 30 ]; @@ -103,7 +104,7 @@

Pie series label rotate

100 / rows / 2 * 0.6 + '%' ] }); - var rotText = j === 3 ? '30°' : rotates[j]; + var rotText = j === 4 ? '30°' : rotates[j]; title.push({ text: 'startAngle: ' + (rot ? 0 : 90) + '\n' + positions[i] + ', rotate: ' + rotText, left: 100 / cols * (j + 0.5) + '%', diff --git a/test/pie-labelLine-smooth.html b/test/pie-labelLine-smooth.html new file mode 100644 index 0000000000..28f8f66d99 --- /dev/null +++ b/test/pie-labelLine-smooth.html @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/test/polyline-gon-event.html b/test/polyline-gon-event.html index 9b9410919f..667f60923f 100644 --- a/test/polyline-gon-event.html +++ b/test/polyline-gon-event.html @@ -21,33 +21,38 @@ - - - - - + + + + -
-
+ + +
- \ No newline at end of file + diff --git a/test/radar-clockwise-interactive.html b/test/radar-clockwise-interactive.html new file mode 100644 index 0000000000..eed01d2d63 --- /dev/null +++ b/test/radar-clockwise-interactive.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/test/radar-clockwise.html b/test/radar-clockwise.html new file mode 100644 index 0000000000..c2e18ba523 --- /dev/null +++ b/test/radar-clockwise.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 10f3d0937f..c78118d8db 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -178,6 +178,7 @@ "polar-rounded": 3, "polarLine": 1, "polarScatter": 1, + "polyline-gon-event": 1, "radar": 3, "radar2": 1, "radar3": 2, @@ -220,6 +221,7 @@ "tooltip-domnode": 1, "tooltip-event": 1, "tooltip-link": 2, + "tooltip-refresh": 1, "tooltip-rich": 1, "tooltip-setOption": 2, "tooltip-valueFormatter": 3, diff --git a/test/runTest/actions/polyline-gon-event.json b/test/runTest/actions/polyline-gon-event.json new file mode 100644 index 0000000000..f266767d64 --- /dev/null +++ b/test/runTest/actions/polyline-gon-event.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":463,"x":619,"y":176},{"type":"mousemove","time":663,"x":583,"y":196},{"type":"mousemove","time":863,"x":536,"y":221},{"type":"mousemove","time":1063,"x":530,"y":233},{"type":"mousemove","time":1263,"x":538,"y":247},{"type":"mousemove","time":1468,"x":541,"y":249},{"type":"mousemove","time":1685,"x":542,"y":251},{"type":"mousedown","time":2074,"x":542,"y":251},{"type":"mouseup","time":2086,"x":542,"y":251},{"time":2087,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":2213,"x":542,"y":252},{"type":"mousemove","time":2418,"x":541,"y":253},{"type":"mousemove","time":2797,"x":541,"y":254},{"type":"mousedown","time":2838,"x":541,"y":254},{"type":"mouseup","time":2978,"x":541,"y":254},{"time":2979,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":3540,"x":541,"y":254},{"type":"mouseup","time":3692,"x":541,"y":254},{"time":3693,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":3699,"x":540,"y":255},{"type":"mousemove","time":4096,"x":540,"y":256},{"type":"mousedown","time":4294,"x":547,"y":281},{"type":"mousemove","time":4306,"x":547,"y":281},{"type":"mouseup","time":4426,"x":547,"y":281},{"time":4427,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4763,"x":547,"y":287},{"type":"mousemove","time":4969,"x":545,"y":322},{"type":"mousemove","time":5171,"x":545,"y":321},{"type":"mousemove","time":5372,"x":544,"y":316},{"type":"mousemove","time":5589,"x":544,"y":315},{"type":"mousemove","time":5781,"x":545,"y":315},{"type":"mousemove","time":5988,"x":546,"y":317},{"type":"mousemove","time":6204,"x":546,"y":320},{"type":"mousemove","time":6420,"x":544,"y":318},{"type":"mousedown","time":6640,"x":542,"y":316},{"type":"mousemove","time":6653,"x":542,"y":316},{"type":"mouseup","time":6811,"x":542,"y":316},{"time":6812,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":6996,"x":542,"y":317},{"type":"mousemove","time":7212,"x":547,"y":329},{"type":"mousedown","time":7240,"x":547,"y":329},{"type":"mouseup","time":7358,"x":547,"y":329},{"time":7359,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":7496,"x":548,"y":329},{"type":"mousemove","time":7696,"x":548,"y":345},{"type":"mousemove","time":7902,"x":548,"y":347},{"type":"mousemove","time":8080,"x":549,"y":348},{"type":"mousemove","time":8289,"x":550,"y":348},{"type":"mousedown","time":8373,"x":551,"y":349},{"type":"mousemove","time":8503,"x":551,"y":349},{"type":"mouseup","time":8620,"x":551,"y":349},{"time":8621,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":8912,"x":551,"y":350},{"type":"mousedown","time":9106,"x":551,"y":364},{"type":"mousemove","time":9123,"x":551,"y":364},{"type":"mouseup","time":9238,"x":551,"y":364},{"time":9239,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":9513,"x":551,"y":365},{"type":"mousemove","time":9724,"x":551,"y":392},{"type":"mousemove","time":9937,"x":551,"y":397},{"type":"mousedown","time":10154,"x":551,"y":399},{"type":"mousemove","time":10169,"x":551,"y":399},{"type":"mouseup","time":10289,"x":551,"y":399},{"time":10290,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":10812,"x":551,"y":400},{"type":"mousemove","time":11020,"x":551,"y":403},{"type":"mousedown","time":11148,"x":551,"y":403},{"type":"mouseup","time":11295,"x":551,"y":403},{"time":11296,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":11562,"x":551,"y":405},{"type":"mousemove","time":11771,"x":551,"y":416},{"type":"mousemove","time":12014,"x":550,"y":416},{"type":"mousemove","time":12223,"x":548,"y":413},{"type":"mousedown","time":12405,"x":546,"y":412},{"type":"mousemove","time":12569,"x":546,"y":412},{"type":"mouseup","time":12587,"x":546,"y":412},{"time":12588,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":12881,"x":547,"y":414},{"type":"mousemove","time":13091,"x":548,"y":448},{"type":"mousedown","time":13109,"x":548,"y":449},{"type":"mouseup","time":13253,"x":548,"y":449},{"time":13254,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":13304,"x":548,"y":449},{"type":"mousemove","time":13762,"x":548,"y":448},{"type":"mousemove","time":13962,"x":535,"y":242},{"type":"mousemove","time":14162,"x":434,"y":159},{"type":"mousemove","time":14362,"x":172,"y":167},{"type":"mousemove","time":14568,"x":58,"y":171},{"type":"mousedown","time":14692,"x":57,"y":171},{"type":"mousemove","time":14803,"x":57,"y":171},{"type":"mouseup","time":14852,"x":57,"y":171},{"time":14853,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":15228,"x":58,"y":170},{"type":"mousemove","time":15428,"x":256,"y":197},{"type":"mousemove","time":15629,"x":280,"y":202},{"type":"mousemove","time":15834,"x":307,"y":249},{"type":"mousemove","time":16054,"x":312,"y":277},{"type":"mousedown","time":16138,"x":312,"y":277},{"type":"mouseup","time":16272,"x":312,"y":277},{"time":16273,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":16445,"x":312,"y":279},{"type":"mousemove","time":16653,"x":307,"y":329},{"type":"mousedown","time":16790,"x":306,"y":336},{"type":"mousemove","time":16887,"x":306,"y":336},{"type":"mouseup","time":16895,"x":306,"y":336},{"time":16896,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":17061,"x":306,"y":339},{"type":"mousemove","time":17274,"x":310,"y":359},{"type":"mousedown","time":17339,"x":310,"y":361},{"type":"mouseup","time":17470,"x":310,"y":361},{"time":17471,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":17487,"x":310,"y":361},{"type":"mousemove","time":17578,"x":310,"y":362},{"type":"mousemove","time":17786,"x":307,"y":393},{"type":"mousemove","time":18003,"x":306,"y":407},{"type":"mousedown","time":18094,"x":305,"y":408},{"type":"mouseup","time":18203,"x":305,"y":408},{"time":18204,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":18253,"x":305,"y":408},{"type":"mousemove","time":18345,"x":305,"y":409},{"type":"mousemove","time":18545,"x":307,"y":427},{"type":"mousedown","time":18575,"x":307,"y":428},{"type":"mouseup","time":18690,"x":307,"y":428},{"time":18691,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":18755,"x":307,"y":428},{"type":"mousemove","time":18811,"x":307,"y":427},{"type":"mousemove","time":19011,"x":306,"y":414},{"type":"mousedown","time":19160,"x":306,"y":413},{"type":"mousemove","time":19219,"x":306,"y":413},{"type":"mouseup","time":19320,"x":306,"y":413},{"time":19321,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":19462,"x":305,"y":412},{"type":"mousemove","time":19661,"x":303,"y":395},{"type":"mousedown","time":19804,"x":303,"y":394},{"type":"mousemove","time":19869,"x":303,"y":394},{"type":"mouseup","time":19939,"x":303,"y":394},{"time":19940,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":20095,"x":303,"y":393},{"type":"mousemove","time":20295,"x":303,"y":359},{"type":"mousemove","time":20504,"x":304,"y":348},{"type":"mousedown","time":20586,"x":304,"y":347},{"type":"mouseup","time":20710,"x":304,"y":347},{"time":20711,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":20726,"x":304,"y":347},{"type":"mousemove","time":20844,"x":304,"y":346},{"type":"mousemove","time":21045,"x":304,"y":316},{"type":"mousedown","time":21222,"x":304,"y":315},{"type":"mousemove","time":21254,"x":304,"y":315},{"type":"mouseup","time":21340,"x":304,"y":315},{"time":21341,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":21495,"x":304,"y":314},{"type":"mousemove","time":21695,"x":304,"y":255},{"type":"mousedown","time":21847,"x":304,"y":255},{"type":"mouseup","time":21969,"x":304,"y":255},{"time":21970,"delay":400,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1763136984452}] \ No newline at end of file diff --git a/test/runTest/actions/tooltip-refresh.json b/test/runTest/actions/tooltip-refresh.json new file mode 100644 index 0000000000..cddc6fab13 --- /dev/null +++ b/test/runTest/actions/tooltip-refresh.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":454,"x":481,"y":259},{"type":"mousemove","time":654,"x":492,"y":263},{"type":"mousedown","time":717,"x":492,"y":263},{"type":"mouseup","time":823,"x":492,"y":263},{"time":824,"delay":2200,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1737531200147}] \ No newline at end of file diff --git a/test/runTest/package-lock.json b/test/runTest/package-lock.json index 26f7bbdfef..bda55f4099 100644 --- a/test/runTest/package-lock.json +++ b/test/runTest/package-lock.json @@ -2042,11 +2042,10 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3191,11 +3190,10 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, - "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -5076,9 +5074,9 @@ "dev": true }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -5958,9 +5956,9 @@ } }, "tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "requires": { "bare-fs": "^4.0.1", diff --git a/test/sunburst-label-centering.html b/test/sunburst-label-centering.html new file mode 100644 index 0000000000..fbf7dd5f1b --- /dev/null +++ b/test/sunburst-label-centering.html @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/test/tooltip-refresh.html b/test/tooltip-refresh.html new file mode 100644 index 0000000000..9bc9e156a6 --- /dev/null +++ b/test/tooltip-refresh.html @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/test/types/cjs/main.ts b/test/types/cjs/main.ts new file mode 100644 index 0000000000..77afa46e10 --- /dev/null +++ b/test/types/cjs/main.ts @@ -0,0 +1,44 @@ +import echarts = require('echarts'); + +function init() { + var myChart = echarts.init(document.getElementById('chart0')); + + const option: echarts.EChartsOption = { + title: { + text: 'ECharts Getting Started Example' + }, + tooltip: {}, + xAxis: { + data: ['a', 'b', 'c', 'd', 'e', 'f'] + }, + yAxis: {}, + series: [ + { + name: 'sales', + type: 'bar', + data: [5, 20, 36, 10, 10, 20] + } + ] + }; + + myChart.on('click', function (params) { + console.log(params.name); + this.off('click'); + }); + + myChart.on('rendered', function (params) { + console.log(params.elapsedTime); + this.off('rendered'); + }); + + myChart.getZr().on('click', function (params) { + console.log(params.offsetX); + this.off('click'); + }); + + myChart.setOption(option); +} + +export function start() { + init(); +}; diff --git a/test/types/cjs/package.json b/test/types/cjs/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/test/types/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/test/types/basic.ts b/test/types/esm/basic.ts similarity index 96% rename from test/types/basic.ts rename to test/types/esm/basic.ts index fd39e4d0f4..0ce9ed4750 100644 --- a/test/types/basic.ts +++ b/test/types/esm/basic.ts @@ -17,7 +17,7 @@ * under the License. */ -import * as echarts from '../../'; +import * as echarts from 'echarts'; const dom = document.createElement('div'); dom.className = 'chart'; diff --git a/test/types/event.ts b/test/types/esm/event.ts similarity index 95% rename from test/types/event.ts rename to test/types/esm/event.ts index 6980abecd2..a5d272fd1a 100644 --- a/test/types/event.ts +++ b/test/types/esm/event.ts @@ -17,7 +17,7 @@ * under the License. */ -import * as echarts from '../../'; +import * as echarts from 'echarts'; const dom = document.createElement('div'); dom.className = 'chart'; @@ -31,13 +31,11 @@ const option: echarts.EChartsOption = { }; chart.setOption(option); -// Mouse event. chart.on('click', function (params) { console.log(params.name); this.off('click'); }); -// Rendered event. chart.on('rendered', function (params) { console.log(params.elapsedTime); this.off('rendered'); diff --git a/test/types/importPartial.ts b/test/types/esm/importPartial.ts similarity index 82% rename from test/types/importPartial.ts rename to test/types/esm/importPartial.ts index c4eb8c7dd0..57e42f286b 100644 --- a/test/types/importPartial.ts +++ b/test/types/esm/importPartial.ts @@ -17,33 +17,33 @@ * under the License. */ -import {init, use, ComposeOption} from '../../core'; +import {init, use, ComposeOption} from 'echarts/core'; import { BarChart, BarSeriesOption, LineChart, LineSeriesOption -} from '../../charts'; +} from 'echarts/charts'; import { GridComponent, GridComponentOption, - DataZoomComponent, DataZoomComponentOption, -} from '../../components'; +} from 'echarts/components'; import { CanvasRenderer -} from '../../renderers'; +} from 'echarts/renderers'; use([BarChart, LineChart, GridComponent, DataZoomComponent, CanvasRenderer]); type Option = ComposeOption< - GridComponentOption | DataZoomComponentOption - | BarSeriesOption | LineSeriesOption + GridComponentOption + | DataZoomComponentOption + | BarSeriesOption + | LineSeriesOption >; -const option: Option= { - // xAxis and yAxis should been add as dependencies +const option: Option = { xAxis: { min: 0, max: 10 diff --git a/test/types/no-module/main.ts b/test/types/no-module/main.ts new file mode 100644 index 0000000000..c30cb5600e --- /dev/null +++ b/test/types/no-module/main.ts @@ -0,0 +1,24 @@ +/// + +function init() { + var myChart = echarts.init(document.getElementById('chart0')); + + const option: echarts.EChartsOption = { + title: { + text: 'ECharts Getting Started Example' + }, + tooltip: {}, + xAxis: { + data: ['a', 'b', 'c', 'd', 'e', 'f'] + }, + yAxis: {}, + series: [{ + type: 'bar', + data: [5, 20, 36, 10, 10, 20] + }] + }; + + myChart.setOption(option); +} + +init(); diff --git a/test/types/package.json b/test/types/package.json new file mode 100644 index 0000000000..35be67643f --- /dev/null +++ b/test/types/package.json @@ -0,0 +1,8 @@ +{ + "name": "echarts-testDts", + "version": "1.0.0", + "type": "module", + "dependencies": { + "echarts": "file:../.." + } +} diff --git a/test/visualmap-seriesTargets.html b/test/visualmap-seriesTargets.html new file mode 100644 index 0000000000..b2f483ee4e --- /dev/null +++ b/test/visualmap-seriesTargets.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + +