未验证 提交 60664f97 编写于 作者: S sushuang 提交者: GitHub

Merge pull request #13438 from apache/fix-ut

Fix ut
# Note:
# If eslint does not work in VSCode, please check:
# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser"
# are npm installed locally. Should better in the same version.
# (2) Whether "VSCode ESlint extension" is installed.
# (3) If the project folder is not the root folder of your working space, please
# config the "VSCode ESlint extension" in "settings":
# ```json
# "eslint.workingDirectories": [{"mode": "auto"}]
# ```
# Note that it should be "workingDirectories" rather than "WorkingDirectories".
rules:
# Check the rules in: node_modules/@typescript-eslint/eslint-plugin/README.md
no-console:
- 2
-
allow:
- "warn"
- "error"
prefer-const: 1
no-constant-condition: 0
comma-dangle: 2
no-debugger: 2
no-dupe-keys: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 0
no-func-assign: 2
no-inner-declarations: 2
no-invalid-regexp: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-sparse-arrays: 2
no-unreachable: 2
use-isnan: 2
valid-typeof: 2
block-scoped-var: 2
curly:
- 2
- "all"
eqeqeq:
- 2
- "allow-null"
guard-for-in: 2
no-else-return: 0
no-labels:
- 2
-
allowLoop: true
no-eval: 2
no-extend-native: 2
no-extra-bind: 0
no-implied-eval: 2
no-iterator: 2
no-irregular-whitespace: 2
no-lone-blocks: 2
no-loop-func: 2
no-multi-str: 2
no-native-reassign: 2
no-new-wrappers: 2
no-octal: 2
no-octal-escape: 2
no-proto: 2
no-redeclare: 2
no-self-compare: 2
no-unneeded-ternary: 2
no-with: 2
radix: 2
wrap-iife:
- 2
- "any"
no-delete-var: 2
no-dupe-args: 2
no-duplicate-case: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-undef: 2
no-undef-init: 2
"no-use-before-define": "off"
"@typescript-eslint/no-use-before-define": 0
brace-style:
- 2
- "stroustrup"
- {}
comma-spacing:
- 2
-
before: false
after: true
comma-style:
- 2
- "last"
new-parens: 2
no-array-constructor: 2
no-multi-spaces:
- 1
-
ignoreEOLComments: true
exceptions:
Property: true
no-new-object: 2
no-trailing-spaces: 2
no-extra-parens:
- 2
- "functions"
no-mixed-spaces-and-tabs: 2
one-var:
- 2
- "never"
operator-linebreak:
- 2
- "before"
-
overrides:
"=": "after"
"quotes": "off"
"@typescript-eslint/quotes":
- 2
- "single"
"semi": "off"
"@typescript-eslint/semi":
- 2
- "always"
semi-spacing: 2
keyword-spacing: 2
key-spacing:
- 2
-
beforeColon: false
afterColon: true
"space-before-function-paren": "off"
"@typescript-eslint/space-before-function-paren":
- 2
-
anonymous: "always"
named: "never"
space-before-blocks:
- 2
- "always"
computed-property-spacing:
- 2
- "never"
space-in-parens:
- 2
- "never"
space-unary-ops: 2
spaced-comment: 0
max-nested-callbacks:
- 1
- 5
max-depth:
- 1
- 6
max-len:
- 2
- 120
- 4
-
ignoreUrls: true
ignoreComments: true
max-params:
- 1
- 15
space-infix-ops: 2
dot-notation:
- 2
-
allowKeywords: true
allowPattern: "^catch$"
arrow-spacing: 2
constructor-super: 2
no-confusing-arrow:
- 2
-
allowParens: true
no-class-assign: 2
no-const-assign: 2
# no-dupe-class-members: 2
no-this-before-super: 0
no-var: 2
no-duplicate-imports: 2
prefer-rest-params: 0
unicode-bom: 2
max-statements-per-line: 2
no-useless-constructor: 0
"func-call-spacing": "off"
"@typescript-eslint/func-call-spacing": "error"
"no-unused-vars": "off"
"@typescript-eslint/no-unused-vars":
- 1
-
vars: "local"
args: "none"
\ No newline at end of file
......@@ -106,13 +106,12 @@ exports.createECharts = function (opt = {}) {
output = nodePath.resolve(output);
}
else {
input = nodePath.resolve(ecDir, `echarts${srcType}.ts`);
input = nodePath.resolve(ecDir, `src/echarts${srcType}.ts`);
output = nodePath.resolve(ecDir, `dist/echarts${postfixLang}${postfixType}.js`);
}
const include = [
nodePath.resolve(ecDir, 'src/**/*.ts'),
nodePath.resolve(ecDir, 'echarts*.ts')
nodePath.resolve(ecDir, 'src/**/*.ts')
];
return {
......
......@@ -49,7 +49,7 @@ async function wrapUMDCode() {
function rebuild() {
build({
stdio: 'inherit',
entryPoints: [path.resolve(__dirname, '../echarts.all.ts')],
entryPoints: [path.resolve(__dirname, '../src/echarts.all.ts')],
outfile: outFilePath,
format: 'cjs',
sourcemap: true,
......
......@@ -53,11 +53,7 @@ const autoGeneratedFileAlert = `
const mainSrcGlobby = {
patterns: [
'src/**/*.ts',
'echarts.all.ts',
'echarts.blank.ts',
'echarts.common.ts',
'echarts.simple.ts'
'src/**/*.ts'
],
cwd: ecDir
};
......@@ -99,10 +95,10 @@ const compileWorkList = [
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.simple.js'));
},
after: async function () {
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.all.js'), nodePath.resolve(ecDir, 'index.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.blank.js'), nodePath.resolve(ecDir, 'index.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.common.js'), nodePath.resolve(ecDir, 'index.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.simple.js'), nodePath.resolve(ecDir, 'index.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.all.js'), nodePath.resolve(ecDir, 'index.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.blank.js'), nodePath.resolve(ecDir, 'index.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.common.js'), nodePath.resolve(ecDir, 'index.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.simple.js'), nodePath.resolve(ecDir, 'index.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src'), nodePath.resolve(ecDir, 'lib'));
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.js'), 'lib');
......@@ -141,10 +137,10 @@ const compileWorkList = [
fsExtra.removeSync(nodePath.resolve(ecDir, 'echarts.simple.js'));
},
after: async function () {
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.all.js'), nodePath.resolve(ecDir, 'echarts.all.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.blank.js'), nodePath.resolve(ecDir, 'echarts.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.common.js'), nodePath.resolve(ecDir, 'echarts.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'echarts.simple.js'), nodePath.resolve(ecDir, 'echarts.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.all.js'), nodePath.resolve(ecDir, 'echarts.all.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.blank.js'), nodePath.resolve(ecDir, 'echarts.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.common.js'), nodePath.resolve(ecDir, 'echarts.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.simple.js'), nodePath.resolve(ecDir, 'echarts.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src'), nodePath.resolve(ecDir, 'esm'));
transformRootFolderInEntry(nodePath.resolve(ecDir, 'echarts.all.js'), 'esm');
......@@ -280,14 +276,18 @@ async function tsCompile(compilerOptionsOverride, srcPathList) {
}
/**
* Transform `src` root in the entry file to `esm` or `lib`
* Transform import/require path in the entry file to `esm` or `lib`.
*/
function transformRootFolderInEntry(entryFile, replacement) {
let code = fs.readFileSync(entryFile, 'utf-8');
// Simple regex replacement
// TODO More robust way?
code = code.replace(/([\"\'])\.\/src\//g, `$1./${replacement}/`)
.replace(/([\"\'])src\//g, `$1${replacement}/`);
assert(
!/(import\s+|from\s+|require\(\s*)["']\.\/echarts\./.test(code)
&& !/(import\s+|from\s+|require\(\s*)["']echarts\./.test(code),
'Import echarts.xxx.ts is not supported.'
);
code = code.replace(/((import\s+|from\s+|require\(\s*)["'])\.\//g, `$1./${replacement}/`);
fs.writeFileSync(
entryFile,
// Also transform zrender.
......
# Note:
# If eslint does not work in VSCode, please check:
# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser"
# are npm installed locally. Should better in the same version.
# (2) Whether "VSCode ESlint extension" is installed.
# (3) If the project folder is not the root folder of your working space, please
# config the "VSCode ESlint extension" in "settings":
# ```json
# "eslint.workingDirectories": [{"mode": "auto"}]
# ```
# Note that it should be "workingDirectories" rather than "WorkingDirectories".
parser: "@typescript-eslint/parser"
parserOptions:
ecmaVersion: 6
......@@ -11,194 +23,7 @@ env:
node: true
es6: false
globals:
jQuery: true
Promise: true
rules:
# Check the rules in: node_modules/@typescript-eslint/eslint-plugin/README.md
no-console:
- 2
-
allow:
- "warn"
- "error"
no-constant-condition: 0
comma-dangle: 2
no-debugger: 2
prefer-const: 1
no-dupe-keys: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 0
no-func-assign: 2
no-inner-declarations: 2
no-invalid-regexp: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-sparse-arrays: 2
no-unreachable: 2
use-isnan: 2
valid-typeof: 2
block-scoped-var: 2
curly:
- 2
- "all"
eqeqeq:
- 2
- "allow-null"
guard-for-in: 2
no-else-return: 0
no-labels:
- 2
-
allowLoop: true
no-eval: 2
no-extend-native: 2
no-extra-bind: 0
no-implied-eval: 2
no-iterator: 2
no-irregular-whitespace: 2
no-lone-blocks: 2
no-loop-func: 2
no-multi-str: 2
no-native-reassign: 2
no-new-wrappers: 2
no-octal: 2
no-octal-escape: 2
no-proto: 2
no-redeclare: 2
no-self-compare: 2
no-unneeded-ternary: 2
no-with: 2
radix: 2
wrap-iife:
- 2
- "any"
no-delete-var: 2
no-dupe-args: 2
no-duplicate-case: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-undef: 2
no-undef-init: 2
"no-use-before-define": "off"
"@typescript-eslint/no-use-before-define": 0
brace-style:
- 2
- "stroustrup"
- {}
comma-spacing:
- 2
-
before: false
after: true
comma-style:
- 2
- "last"
new-parens: 2
no-array-constructor: 2
no-multi-spaces:
- 1
-
ignoreEOLComments: true
exceptions:
Property: true
no-new-object: 2
no-spaced-func: 2
no-trailing-spaces: 2
no-extra-parens:
- 2
- "functions"
no-mixed-spaces-and-tabs: 2
one-var:
- 2
- "never"
operator-linebreak:
- 2
- "before"
-
overrides:
"=": "after"
"quotes": "off"
"@typescript-eslint/quotes":
- 2
- "single"
"semi": "off"
"@typescript-eslint/semi":
- 2
- "always"
semi-spacing: 2
keyword-spacing: 2
key-spacing:
- 2
-
beforeColon: false
afterColon: true
"space-before-function-paren": "off"
"@typescript-eslint/space-before-function-paren":
- 2
-
anonymous: "always"
named: "never"
space-before-blocks:
- 2
- "always"
computed-property-spacing:
- 2
- "never"
space-in-parens:
- 2
- "never"
space-unary-ops: 2
spaced-comment: 0
max-nested-callbacks:
- 1
- 5
max-depth:
- 1
- 6
max-len:
- 2
- 120
- 4
-
ignoreUrls: true
ignoreComments: true
max-params:
- 1
- 15
space-infix-ops: 2
dot-notation:
- 2
-
allowKeywords: true
allowPattern: "^catch$"
arrow-spacing: 2
constructor-super: 2
no-confusing-arrow:
- 2
-
allowParens: true
no-class-assign: 2
no-const-assign: 2
# no-dupe-class-members: 2
no-this-before-super: 0
no-var: 2
no-duplicate-imports: 2
prefer-rest-params: 0
unicode-bom: 2
max-statements-per-line: 2
no-useless-constructor: 0
"func-call-spacing": "off"
"@typescript-eslint/func-call-spacing": "error"
"no-unused-vars": "off"
"@typescript-eslint/no-unused-vars":
- 1
-
vars: "local"
args: "none"
\ No newline at end of file
jQuery: false
Promise: false
__DEV__: true
extends: '../.eslintrc-common.yaml'
......@@ -22,6 +22,6 @@
/// Make sure run it before edit this file. ///
///////////////////////////////////////////////////////////////////////
export * from './types/echarts.all';
export * from './types/src/echarts.all';
export {EChartsFullOption as EChartsOption} from './types/src/option';
\ No newline at end of file
......@@ -27,7 +27,7 @@
"help": "node build/build.js --help",
"test:visual": "node test/runTest/server.js",
"test:visual:report": "node test/runTest/genReport.js",
"test": "node build/build.js --prepublish && jest --config test/ut/jest.config.js",
"test": "jest --config test/ut/jest.config.js",
"test:single": "jest --config test/ut/jest.config.js --coverage=false -t",
"mktest": "node test/build/mktest.js",
"mktest:help": "node test/build/mktest.js -h",
......@@ -42,9 +42,9 @@
"@babel/core": "7.3.4",
"@babel/types": "^7.10.5",
"@microsoft/api-extractor": "7.7.2",
"@types/jest": "^26.0.14",
"@typescript-eslint/eslint-plugin": "^2.15.0",
"@typescript-eslint/parser": "^2.18.0",
"husky": "^4.2.5",
"canvas": "^2.6.0",
"chalk": "^3.0.0",
"chokidar": "^3.4.0",
......@@ -54,9 +54,9 @@
"fs-extra": "0.26.7",
"glob": "7.0.0",
"globby": "11.0.0",
"husky": "^4.2.5",
"jest": "^24.9.0",
"jest-canvas-mock": "^2.2.0",
"jsdom": "^15.2.1",
"jshint": "2.10.2",
"lodash.debounce": "^4.0.8",
"open": "6.4.0",
......@@ -71,6 +71,7 @@
"serve-handler": "6.1.1",
"slugify": "1.3.4",
"socket.io": "2.2.0",
"ts-jest": "^26.4.1",
"typescript": "3.8.3",
"uglify-js": "^3.10.0"
}
......
......@@ -23,194 +23,7 @@ env:
node: true
es6: false
globals:
jQuery: true
Promise: true
jQuery: false
Promise: false
__DEV__: true
rules:
# Check the rules in: node_modules/@typescript-eslint/eslint-plugin/README.md
no-console:
- 2
-
allow:
- "warn"
- "error"
prefer-const: 1
no-constant-condition: 0
comma-dangle: 2
no-debugger: 2
no-dupe-keys: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 0
no-func-assign: 2
no-inner-declarations: 2
no-invalid-regexp: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-sparse-arrays: 2
no-unreachable: 2
use-isnan: 2
valid-typeof: 2
block-scoped-var: 2
curly:
- 2
- "all"
eqeqeq:
- 2
- "allow-null"
guard-for-in: 2
no-else-return: 0
no-labels:
- 2
-
allowLoop: true
no-eval: 2
no-extend-native: 2
no-extra-bind: 0
no-implied-eval: 2
no-iterator: 2
no-irregular-whitespace: 2
no-lone-blocks: 2
no-loop-func: 2
no-multi-str: 2
no-native-reassign: 2
no-new-wrappers: 2
no-octal: 2
no-octal-escape: 2
no-proto: 2
no-redeclare: 2
no-self-compare: 2
no-unneeded-ternary: 2
no-with: 2
radix: 2
wrap-iife:
- 2
- "any"
no-delete-var: 2
no-dupe-args: 2
no-duplicate-case: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-undef: 2
no-undef-init: 2
"no-use-before-define": "off"
"@typescript-eslint/no-use-before-define": 0
brace-style:
- 2
- "stroustrup"
- {}
comma-spacing:
- 2
-
before: false
after: true
comma-style:
- 2
- "last"
new-parens: 2
no-array-constructor: 2
no-multi-spaces:
- 1
-
ignoreEOLComments: true
exceptions:
Property: true
no-new-object: 2
no-trailing-spaces: 2
no-extra-parens:
- 2
- "functions"
no-mixed-spaces-and-tabs: 2
one-var:
- 2
- "never"
operator-linebreak:
- 2
- "before"
-
overrides:
"=": "after"
"quotes": "off"
"@typescript-eslint/quotes":
- 2
- "single"
"semi": "off"
"@typescript-eslint/semi":
- 2
- "always"
semi-spacing: 2
keyword-spacing: 2
key-spacing:
- 2
-
beforeColon: false
afterColon: true
"space-before-function-paren": "off"
"@typescript-eslint/space-before-function-paren":
- 2
-
anonymous: "always"
named: "never"
space-before-blocks:
- 2
- "always"
computed-property-spacing:
- 2
- "never"
space-in-parens:
- 2
- "never"
space-unary-ops: 2
spaced-comment: 0
max-nested-callbacks:
- 1
- 5
max-depth:
- 1
- 6
max-len:
- 2
- 120
- 4
-
ignoreUrls: true
ignoreComments: true
max-params:
- 1
- 15
space-infix-ops: 2
dot-notation:
- 2
-
allowKeywords: true
allowPattern: "^catch$"
arrow-spacing: 2
constructor-super: 2
no-confusing-arrow:
- 2
-
allowParens: true
no-class-assign: 2
no-const-assign: 2
# no-dupe-class-members: 2
no-this-before-super: 0
no-var: 2
no-duplicate-imports: 2
prefer-rest-params: 0
unicode-bom: 2
max-statements-per-line: 2
no-useless-constructor: 0
"func-call-spacing": "off"
"@typescript-eslint/func-call-spacing": "error"
"no-unused-vars": "off"
"@typescript-eslint/no-unused-vars":
- 1
-
vars: "local"
args: "none"
\ No newline at end of file
extends: '../.eslintrc-common.yaml'
......@@ -86,7 +86,7 @@ export interface MapSeriesOption extends
data?: OptionDataValueNumeric[] | OptionDataValueNumeric[][] | MapDataItemOption[]
nameProperty: string;
nameProperty?: string;
}
class MapSeries extends SeriesModel<MapSeriesOption> {
......
......@@ -28,6 +28,7 @@ import { curry, defaults } from 'zrender/src/core/util';
import { ZRElementEvent, BoxLayoutOptionMixin, ECElement } from '../../util/types';
import Element from 'zrender/src/Element';
import Model from '../../model/Model';
import { convertOptionIdName } from '../../util/model';
const TEXT_PADDING = 8;
const ITEM_GAP = 8;
......@@ -110,7 +111,7 @@ class Breadcrumb {
*/
_prepare(targetNode: TreeNode, layoutParam: LayoutParam, textStyleModel: BreadcrumbTextStyleModel) {
for (let node = targetNode; node; node = node.parentNode) {
const text = node.getModel<TreemapSeriesNodeItemOption>().get('name');
const text = convertOptionIdName(node.getModel<TreemapSeriesNodeItemOption>().get('name'), '');
const textRect = textStyleModel.getTextRect(text);
const itemWidth = Math.max(
textRect.width + TEXT_PADDING * 2,
......
......@@ -30,7 +30,9 @@ import {
RoamOptionMixin,
CallbackDataParams,
ColorString,
StatesOptionMixin
StatesOptionMixin,
OptionId,
OptionName
} from '../../util/types';
import GlobalModel from '../../model/Global';
import { LayoutRect } from '../../util/layout';
......@@ -119,8 +121,8 @@ export interface TreemapSeriesLevelOption extends TreemapSeriesVisualOption,
export interface TreemapSeriesNodeItemOption extends TreemapSeriesVisualOption,
TreemapStateOption, StatesOptionMixin<TreemapStateOption, ExtraStateOption> {
id?: string
name?: string
id?: OptionId
name?: OptionName
value?: TreemapSeriesDataValue
......
......@@ -44,7 +44,7 @@ import { LayoutRect } from '../../util/layout';
import { TreemapLayoutNode } from './treemapLayout';
import Element from 'zrender/src/Element';
import Displayable from 'zrender/src/graphic/Displayable';
import { makeInner } from '../../util/model';
import { makeInner, convertOptionIdName } from '../../util/model';
import { PathStyleProps, PathProps } from 'zrender/src/graphic/Path';
import { TreeSeriesNodeItemOption } from '../tree/TreeSeries';
import {
......@@ -954,7 +954,7 @@ function renderNode(
seriesModel.getFormattedLabel(
thisNode.dataIndex, 'normal', null, null, normalLabelModel.get('formatter')
),
nodeModel.get('name')
convertOptionIdName(nodeModel.get('name'), null)
);
if (!upperLabelRect && thisLayout.isLeafRoot) {
const iconChar = seriesModel.get('drillDownIcon', true);
......@@ -964,7 +964,8 @@ function renderNode(
const isShow = normalLabelModel.getShallow('show');
setLabelStyle(
rectEl, getLabelStatesModels(nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL),
rectEl,
getLabelStatesModels(nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL),
{
defaultText: isShow ? text : null,
inheritColor: visualColor,
......
......@@ -71,7 +71,7 @@ export interface CoordinateSystemMaster {
// null/undefined value.
convertFromPixel?(
ecModel: GlobalModel, finder: ParsedModelFinder, pixelValue: number | number[]
): ScaleDataValue | ScaleDataValue[];
): number | number[];
// @param point Point in global pixel coordinate system.
// The signature of this method should be the same as `CoordinateSystemExecutive`
......
......@@ -72,8 +72,10 @@ export interface GeoCommonOptionMixin extends RoamOptionMixin {
///// Layout with center and size
// If you wan't to put map in a fixed size box with right aspect ratio
// This two properties may more conveninet
layoutCenter?: number[];
layoutSize?: number;
// Like: `40` or `'50%'`.
layoutCenter?: (number | string)[];
// Like: `40` or `'50%'`.
layoutSize?: number | string;
// Define left-top, right-bottom coords to control view
// For example, [ [180, 90], [-180, -90] ]
......@@ -94,7 +96,7 @@ export interface GeoOption extends
show?: boolean;
silent?: boolean;
regions: RegoinOption[];
regions?: RegoinOption[];
stateAnimation?: AnimationOptionMixin
......
......@@ -59,8 +59,8 @@ function resizeGeo(this: Geo, geoModel: ComponentModel<GeoOption | MapSeriesOpti
const rect = this.getBoundingRect();
let center = geoModel.get('layoutCenter');
let size = geoModel.get('layoutSize');
const centerOption = geoModel.get('layoutCenter');
const sizeOption = geoModel.get('layoutSize');
const viewWidth = api.getWidth();
const viewHeight = api.getHeight();
......@@ -68,13 +68,15 @@ function resizeGeo(this: Geo, geoModel: ComponentModel<GeoOption | MapSeriesOpti
const aspect = rect.width / rect.height * this.aspectScale;
let useCenterAndSize = false;
let center: number[];
let size: number;
if (center && size) {
if (centerOption && sizeOption) {
center = [
numberUtil.parsePercent(center[0], viewWidth),
numberUtil.parsePercent(center[1], viewHeight)
numberUtil.parsePercent(centerOption[0], viewWidth),
numberUtil.parsePercent(centerOption[1], viewHeight)
];
size = numberUtil.parsePercent(size, Math.min(viewWidth, viewHeight));
size = numberUtil.parsePercent(sizeOption, Math.min(viewWidth, viewHeight));
if (!isNaN(center[0]) && !isNaN(center[1]) && !isNaN(size)) {
useCenterAndSize = true;
......
......@@ -100,9 +100,6 @@ export function summarizeDimensions(data: List): DimensionSummary {
notExtraCoordDimMap.each(function (v, coordDim) {
const dimArr = encode[coordDim];
// ??? FIXME extra coord should not be set in dataDimsOnCoord.
// But should fix the case that radar axes: simplify the logic
// of `completeDimension`, remove `extraPrefix`.
encodeFirstDimNotExtra[coordDim] = dimArr[0];
// Not necessary to remove duplicate, because a data
// dim canot on more than one coordDim.
......
......@@ -17,11 +17,11 @@
* under the License.
*/
export * from './src/echarts';
export * from './src/export';
export * from './echarts';
export * from './export';
import './src/component/dataset';
import './src/component/transform';
import './component/dataset';
import './component/transform';
// ----------------------------------------------
// All of the modules that are allowed to be
......@@ -46,28 +46,28 @@ import './src/component/transform';
// }]
// });
import './src/chart/line';
import './src/chart/bar';
import './src/chart/pie';
import './src/chart/scatter';
import './src/chart/radar';
import './src/chart/map';
import './src/chart/tree';
import './src/chart/treemap';
import './src/chart/graph';
import './src/chart/gauge';
import './src/chart/funnel';
import './src/chart/parallel';
import './src/chart/sankey';
import './src/chart/boxplot';
import './src/chart/candlestick';
import './src/chart/effectScatter';
import './src/chart/lines';
import './src/chart/heatmap';
import './src/chart/pictorialBar';
import './src/chart/themeRiver';
import './src/chart/sunburst';
import './src/chart/custom';
import './chart/line';
import './chart/bar';
import './chart/pie';
import './chart/scatter';
import './chart/radar';
import './chart/map';
import './chart/tree';
import './chart/treemap';
import './chart/graph';
import './chart/gauge';
import './chart/funnel';
import './chart/parallel';
import './chart/sankey';
import './chart/boxplot';
import './chart/candlestick';
import './chart/effectScatter';
import './chart/lines';
import './chart/heatmap';
import './chart/pictorialBar';
import './chart/themeRiver';
import './chart/sunburst';
import './chart/custom';
......@@ -89,7 +89,7 @@ import './src/chart/custom';
// yAxis: {...},
// series: [{...}]
// });
import './src/component/grid';
import './component/grid';
// `polar` coordinate system, for example:
// chart.setOption({
......@@ -100,7 +100,7 @@ import './src/component/grid';
// coordinateSystem: 'polar'
// }]
// });
import './src/component/polar';
import './component/polar';
// `geo` coordinate system, for example:
// chart.setOption({
......@@ -109,7 +109,7 @@ import './src/component/polar';
// coordinateSystem: 'geo'
// }]
// });
import './src/component/geo';
import './component/geo';
// `singleAxis` coordinate system (notice, it is a coordinate system
// with only one axis, work for chart like theme river), for example:
......@@ -117,7 +117,7 @@ import './src/component/geo';
// singleAxis: {...}
// series: [{type: 'themeRiver', ...}]
// });
import './src/component/singleAxis';
import './component/singleAxis';
// `parallel` coordinate system, only work for parallel series, for example:
// chart.setOption({
......@@ -127,7 +127,7 @@ import './src/component/singleAxis';
// type: 'parallel'
// }]
// });
import './src/component/parallel';
import './component/parallel';
// `calendar` coordinate system. for example,
// chart.setOptionp({
......@@ -136,7 +136,7 @@ import './src/component/parallel';
// coordinateSystem: 'calendar'
// }]
// );
import './src/component/calendar';
import './component/calendar';
......@@ -150,19 +150,19 @@ import './src/component/calendar';
// chart.setOption({
// graphic: {...}
// });
import './src/component/graphic';
import './component/graphic';
// `toolbox` component, for example:
// chart.setOption({
// toolbox: {...}
// });
import './src/component/toolbox';
import './component/toolbox';
// `tooltip` component, for example:
// chart.setOption({
// tooltip: {...}
// });
import './src/component/tooltip';
import './component/tooltip';
// `axisPointer` component, for example:
// chart.setOption({
......@@ -172,7 +172,7 @@ import './src/component/tooltip';
// chart.setOption({
// axisPointer: {...}
// });
import './src/component/axisPointer';
import './component/axisPointer';
// `brush` component, for example:
// chart.setOption({
......@@ -182,80 +182,80 @@ import './src/component/axisPointer';
// chart.setOption({
// tooltip: {feature: {brush: {...}}
// })
import './src/component/brush';
import './component/brush';
// `title` component, for example:
// chart.setOption({
// title: {...}
// });
import './src/component/title';
import './component/title';
// `timeline` component, for example:
// chart.setOption({
// timeline: {...}
// });
import './src/component/timeline';
import './component/timeline';
// `markPoint` component, for example:
// chart.setOption({
// series: [{markPoint: {...}}]
// });
import './src/component/markPoint';
import './component/markPoint';
// `markLine` component, for example:
// chart.setOption({
// series: [{markLine: {...}}]
// });
import './src/component/markLine';
import './component/markLine';
// `markArea` component, for example:
// chart.setOption({
// series: [{markArea: {...}}]
// });
import './src/component/markArea';
import './component/markArea';
// `legend` component scrollable, for example:
// chart.setOption({
// legend: {type: 'scroll'}
// });
import './src/component/legendScroll';
import './component/legendScroll';
// `legend` component not scrollable. for example:
// chart.setOption({
// legend: {...}
// });
import './src/component/legend';
import './component/legend';
// `dataZoom` component including both `dataZoomInside` and `dataZoomSlider`.
import './src/component/dataZoom';
import './component/dataZoom';
// `dataZoom` component providing drag, pinch, wheel behaviors
// inside coodinate system, for example:
// chart.setOption({
// dataZoom: {type: 'inside'}
// });
import './src/component/dataZoomInside';
import './component/dataZoomInside';
// `dataZoom` component providing a slider bar, for example:
// chart.setOption({
// dataZoom: {type: 'slider'}
// });
import './src/component/dataZoomSlider';
import './component/dataZoomSlider';
// `dataZoom` component including both `visualMapContinuous` and `visualMapPiecewise`.
import './src/component/visualMap';
import './component/visualMap';
// `visualMap` component providing continuous bar, for example:
// chart.setOption({
// visualMap: {type: 'continuous'}
// });
import './src/component/visualMapContinuous';
import './component/visualMapContinuous';
// `visualMap` component providing pieces bar, for example:
// chart.setOption({
// visualMap: {type: 'piecewise'}
// });
import './src/component/visualMapPiecewise';
import './component/visualMapPiecewise';
......@@ -266,7 +266,7 @@ import './src/component/visualMapPiecewise';
// Provide IE 6,7,8 compatibility.
// import 'zrender/src/vml/vml';
// import 'zrender/vml/vml';
// Render via SVG rather than canvas.
import 'zrender/src/svg/svg';
......@@ -17,7 +17,7 @@
* under the License.
*/
export * from './src/echarts';
export * from './src/export';
export * from './echarts';
export * from './export';
import './src/component/dataset';
import './component/dataset';
......@@ -17,28 +17,28 @@
* under the License.
*/
export * from './src/echarts';
export * from './src/export';
export * from './echarts';
export * from './export';
import './src/component/dataset';
import './component/dataset';
import './src/chart/line';
import './src/chart/bar';
import './src/chart/pie';
import './src/chart/scatter';
import './src/component/graphic';
import './src/component/tooltip';
import './src/component/axisPointer';
import './src/component/legendScroll';
import './chart/line';
import './chart/bar';
import './chart/pie';
import './chart/scatter';
import './component/graphic';
import './component/tooltip';
import './component/axisPointer';
import './component/legendScroll';
import './src/component/grid';
import './src/component/title';
import './component/grid';
import './component/title';
import './src/component/markPoint';
import './src/component/markLine';
import './src/component/markArea';
import './src/component/dataZoom';
import './src/component/toolbox';
import './component/markPoint';
import './component/markLine';
import './component/markArea';
import './component/dataZoom';
import './component/toolbox';
// import 'zrender/src/vml/vml';
import 'zrender/src/svg/svg';
\ No newline at end of file
// import 'zrender/vml/vml';
import 'zrender/src/svg/svg';
......@@ -17,11 +17,11 @@
* under the License.
*/
export * from './src/echarts';
export * from './echarts';
import './src/component/dataset';
import './component/dataset';
import './src/chart/line';
import './src/chart/bar';
import './src/chart/pie';
import './src/component/gridSimple';
\ No newline at end of file
import './chart/line';
import './chart/bar';
import './chart/pie';
import './component/gridSimple';
......@@ -88,7 +88,8 @@ import {
ComponentMainType,
ComponentSubType,
ColorString,
SelectChangedPayload
SelectChangedPayload,
ScaleDataValue
} from './util/types';
import Displayable from 'zrender/src/graphic/Displayable';
import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
......@@ -237,7 +238,12 @@ let updateMethods: {
updateVisual: UpdateMethod,
updateLayout: UpdateMethod
};
let doConvertPixel: (ecIns: ECharts, methodName: string, finder: ModelFinder, value: any) => any;
let doConvertPixel: (
ecIns: ECharts,
methodName: string,
finder: ModelFinder,
value: (number | number[]) | (ScaleDataValue | ScaleDataValue[])
) => (number | number[]);
let updateStreamModes: (ecIns: ECharts, ecModel: GlobalModel) => void;
let doDispatchAction: (this: ECharts, payload: Payload, silent: boolean) => void;
let flushPendingActions: (this: ECharts, silent: boolean) => void;
......@@ -779,7 +785,9 @@ class ECharts extends Eventful {
* Convert from logical coordinate system to pixel coordinate system.
* See CoordinateSystem#convertToPixel.
*/
convertToPixel(finder: ModelFinder, value: any): number[] {
convertToPixel(finder: ModelFinder, value: ScaleDataValue): number;
convertToPixel(finder: ModelFinder, value: ScaleDataValue[]): number[];
convertToPixel(finder: ModelFinder, value: ScaleDataValue | ScaleDataValue[]): number | number[] {
return doConvertPixel(this, 'convertToPixel', finder, value);
}
......@@ -787,7 +795,9 @@ class ECharts extends Eventful {
* Convert from pixel coordinate system to logical coordinate system.
* See CoordinateSystem#convertFromPixel.
*/
convertFromPixel(finder: ModelFinder, value: number[]): any {
convertFromPixel(finder: ModelFinder, value: number): number;
convertFromPixel(finder: ModelFinder, value: number[]): number[];
convertFromPixel(finder: ModelFinder, value: number | number[]): number | number[] {
return doConvertPixel(this, 'convertFromPixel', finder, value);
}
......@@ -1377,9 +1387,15 @@ class ECharts extends Eventful {
subType && (condition.subType = subType); // subType may be '' by parseClassType;
const excludeSeriesId = payload.excludeSeriesId;
let excludeSeriesIdMap: zrUtil.HashMap<string[], string>;
let excludeSeriesIdMap: zrUtil.HashMap<true, string>;
if (excludeSeriesId != null) {
excludeSeriesIdMap = zrUtil.createHashMap(modelUtil.normalizeToArray(excludeSeriesId));
excludeSeriesIdMap = zrUtil.createHashMap();
each(modelUtil.normalizeToArray(excludeSeriesId), id => {
const modelId = modelUtil.convertOptionIdName(id, null);
if (modelId != null) {
excludeSeriesIdMap.set(modelId, true);
}
});
}
// If dispatchAction before setOption, do nothing.
......@@ -1620,8 +1636,8 @@ class ECharts extends Eventful {
ecIns: ECharts,
methodName: 'convertFromPixel' | 'convertToPixel',
finder: ModelFinder,
value: any
): any {
value: (number | number[]) | (ScaleDataValue | ScaleDataValue[])
): (number | number[]) {
if (ecIns._disposed) {
disposedWarning(ecIns.id);
return;
......@@ -1635,7 +1651,7 @@ class ECharts extends Eventful {
for (let i = 0; i < coordSysList.length; i++) {
const coordSys = coordSysList[i];
if (coordSys[methodName]
&& (result = coordSys[methodName](ecModel, parsedFinder, value)) != null
&& (result = coordSys[methodName](ecModel, parsedFinder, value as any)) != null
) {
return result;
}
......
......@@ -52,7 +52,9 @@ import {
ThemeOption,
ComponentOption,
ComponentMainType,
ComponentSubType
ComponentSubType,
OptionId,
OptionName
} from '../util/types';
import OptionManager from './OptionManager';
import Scheduler from '../stream/Scheduler';
......@@ -258,7 +260,7 @@ class GlobalModel extends Model<ECUnitOption> {
// (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`.
// (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`.
replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) {
if (!newCmptTypeMap.get(mainTypeInReplaceMerge)) {
if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) {
newCmptTypes.push(mainTypeInReplaceMerge);
newCmptTypeMap.set(mainTypeInReplaceMerge, true);
}
......@@ -540,8 +542,8 @@ class GlobalModel extends Model<ECUnitOption> {
mainType: mainType,
// subType will be filtered finally.
index: q[indexAttr] as (number | number[]),
id: q[idAttr] as (string | string[]),
name: q[nameAttr] as (string | string[])
id: q[idAttr] as (OptionId | OptionId[]),
name: q[nameAttr] as (OptionName | OptionName[])
}
: null;
}
......@@ -622,10 +624,11 @@ class GlobalModel extends Model<ECUnitOption> {
/**
* Get series list before filtered by name.
*/
getSeriesByName(name: string): SeriesModel[] {
getSeriesByName(name: OptionName): SeriesModel[] {
const nameStr = modelUtil.convertOptionIdName(name, null);
return filter(
this._componentsMap.get('series') as SeriesModel[],
oneSeries => !!oneSeries && oneSeries.name === name
oneSeries => !!oneSeries && nameStr != null && oneSeries.name === nameStr
);
}
......@@ -755,7 +758,9 @@ class GlobalModel extends Model<ECUnitOption> {
const componentsMap = this._componentsMap;
const componentTypes: string[] = [];
componentsMap.each(function (components, componentType) {
componentTypes.push(componentType);
if (ComponentModel.hasClass(componentType)) {
componentTypes.push(componentType);
}
});
(ComponentModel as ComponentModelConstructor).topologicalTravel(
......@@ -851,8 +856,8 @@ export interface QueryConditionKindB {
mainType: ComponentMainType;
subType?: ComponentSubType;
index?: number | number[];
id?: string | number | (string | number)[];
name?: (string | number) | (string | number)[];
id?: OptionId | OptionId[];
name?: OptionName | OptionName[];
}
export interface EachComponentAllCallback {
(mainType: string, model: ComponentModel, componentIndex: number): void;
......@@ -907,18 +912,18 @@ function queryByIdOrName<T extends { id?: string, name?: string }>(
// Here is a break from echarts4: string and number are
// traded as equal.
if (isArray(idOrName)) {
const keyMap = createHashMap<boolean>(idOrName);
const keyMap = createHashMap<boolean>();
each(idOrName, function (idOrNameItem) {
if (idOrNameItem != null) {
modelUtil.validateIdOrName(idOrNameItem);
keyMap.set(idOrNameItem, true);
const idName = modelUtil.convertOptionIdName(idOrNameItem, null);
idName != null && keyMap.set(idOrNameItem, true);
}
});
return filter(cmpts, cmpt => cmpt && keyMap.get(cmpt[attr]));
}
else {
modelUtil.validateIdOrName(idOrName);
return filter(cmpts, cmpt => cmpt && cmpt[attr] === idOrName + '');
const idName = modelUtil.convertOptionIdName(idOrName, null);
return filter(cmpts, cmpt => cmpt && idName != null && cmpt[attr] === idName);
}
}
......
......@@ -21,6 +21,7 @@ import * as zrUtil from 'zrender/src/core/util';
import {parseClassType, ClassManager} from './clazz';
import { ComponentOption, ComponentMainType, ComponentSubType, ComponentFullType } from './types';
import { Dictionary } from 'zrender/src/core/types';
import { makePrintable } from './log';
// A random offset
let base = Math.round(Math.random() * 10);
......@@ -127,15 +128,15 @@ export function enableTopologicalTravel<T>(
const result = makeDepndencyGraph(fullNameList);
const graph = result.graph;
const stack = result.noEntryList;
const noEntryList = result.noEntryList;
const targetNameSet: {[cmtpMainType: string]: boolean} = {};
zrUtil.each(targetNameList, function (name) {
targetNameSet[name] = true;
});
while (stack.length) {
const currComponentType = stack.pop();
while (noEntryList.length) {
const currComponentType = noEntryList.pop();
const currVertex = graph[currComponentType];
const isInTargetNameSet = !!targetNameSet[currComponentType];
if (isInTargetNameSet) {
......@@ -149,13 +150,17 @@ export function enableTopologicalTravel<T>(
}
zrUtil.each(targetNameSet, function () {
throw new Error('Circle dependency may exists');
let errMsg = '';
if (__DEV__) {
errMsg = makePrintable('Circle dependency may exists: ', targetNameSet, targetNameList, fullNameList);
}
throw new Error(errMsg);
});
function removeEdge(succComponentType: ComponentMainType): void {
graph[succComponentType].entryCount--;
if (graph[succComponentType].entryCount === 0) {
stack.push(succComponentType);
noEntryList.push(succComponentType);
}
}
......
......@@ -52,6 +52,7 @@ import CartesianAxisModel from '../coord/cartesian/AxisModel';
import GridModel from '../coord/cartesian/GridModel';
import { isNumeric, getRandomIdBase, getPrecisionSafe, round } from './number';
import { interpolateNumber } from 'zrender/src/animation/Animator';
import { warn } from './log';
/**
* Make the name displayable. But we should
......@@ -232,8 +233,17 @@ export function mappingToExists<T extends MappingExistingItem>(
newCmptOptions[index] = null;
return;
}
cmptOption.id == null || validateIdOrName(cmptOption.id);
cmptOption.name == null || validateIdOrName(cmptOption.name);
if (__DEV__) {
// There is some legacy case that name is set as `false`.
// But should work normally rather than throw error.
if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) {
warnInvalidateIdOrName(cmptOption.id);
}
if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) {
warnInvalidateIdOrName(cmptOption.name);
}
}
});
const result = prepareResult(existings, existingIdIdxMap, mode);
......@@ -356,7 +366,6 @@ function mappingByIndex<T extends MappingExistingItem>(
newCmptOptions: ComponentOption[],
brandNew: boolean
): void {
let nextIdx = 0;
each(newCmptOptions, function (cmptOption) {
if (!cmptOption) {
return;
......@@ -364,6 +373,7 @@ function mappingByIndex<T extends MappingExistingItem>(
// Find the first place that not mapped by id and not internal component (consider the "hole").
let resultItem;
let nextIdx = 0;
while (
// Be `!resultItem` only when `nextIdx >= result.length`.
(resultItem = result[nextIdx])
......@@ -508,10 +518,10 @@ function keyExistAndEqual(
obj1: { id?: OptionId, name?: OptionName },
obj2: { id?: OptionId, name?: OptionName }
): boolean {
const key1 = obj1[attr];
const key2 = obj2[attr];
const key1 = convertOptionIdName(obj1[attr], null);
const key2 = convertOptionIdName(obj2[attr], null);
// See `MappingExistingItem`. `id` and `name` trade string equals to number.
return key1 != null && key2 != null && key1 + '' === key2 + '';
return key1 != null && key2 != null && key1 === key2;
}
/**
......@@ -535,12 +545,9 @@ export function convertOptionIdName(idOrName: unknown, defaultValue: string): st
: defaultValue;
}
export function validateIdOrName(idOrName: unknown) {
function warnInvalidateIdOrName(idOrName: unknown) {
if (__DEV__) {
assert(
isValidIdOrName(idOrName),
'`' + idOrName + '` is invalid id or name. Must be a string.'
);
warn('`' + idOrName + '` is invalid id or name. Must be a string or number.');
}
}
......@@ -603,8 +610,8 @@ function determineSubType(
type BatchItem = {
seriesId: string,
dataIndex: number[]
seriesId: OptionId,
dataIndex: number | number[]
};
/**
* A helper for removing duplicate items between batchA and batchB,
......@@ -634,7 +641,10 @@ export function compressBatches(
function makeMap(sourceBatch: BatchItem[], map: InnerMap, otherMap?: InnerMap): void {
for (let i = 0, len = sourceBatch.length; i < len; i++) {
const seriesId = sourceBatch[i].seriesId;
const seriesId = convertOptionIdName(sourceBatch[i].seriesId, null);
if (seriesId == null) {
return;
}
const dataIndices = normalizeToArray(sourceBatch[i].dataIndex);
const otherDataIndices = otherMap && otherMap[seriesId];
......@@ -795,7 +805,12 @@ export type ParsedModelFinder = ParsedModelFinderKnown & {
export function parseFinder(
ecModel: GlobalModel,
finderInput: ModelFinder,
opt?: {defaultMainType?: ComponentMainType, includeMainTypes?: ComponentMainType[]}
opt?: {
// If no main type specified, use this main type.
defaultMainType?: ComponentMainType,
// If pervided, types out of this list will be ignored.
includeMainTypes?: ComponentMainType[]
}
): ParsedModelFinder {
let finder: ModelFinderObject;
if (isString(finderInput)) {
......@@ -807,9 +822,9 @@ export function parseFinder(
finder = finderInput;
}
const defaultMainType = opt ? opt.defaultMainType : null;
const queryOptionMap = createHashMap<QueryReferringUserOption, ComponentMainType>();
const result = {} as ParsedModelFinder;
let mainTypeSpecified = false;
each(finder, function (value, key) {
// Exclude 'dataIndex' and other illgal keys.
......@@ -825,16 +840,22 @@ export function parseFinder(
if (
!mainType
|| !queryType
|| (mainType !== defaultMainType && value == null)
|| (opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0)
) {
return;
}
mainTypeSpecified = mainTypeSpecified || !!mainType;
const queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {});
queryOption[queryType] = value as any;
});
const defaultMainType = opt ? opt.defaultMainType : null;
if (!mainTypeSpecified && defaultMainType) {
queryOptionMap.set(defaultMainType, {});
}
queryOptionMap.each(function (queryOption, mainType) {
const queryResult = queryReferringComponents(
ecModel,
......
......@@ -133,7 +133,7 @@ export interface DataModel extends DataHost, DataFormatMixin {}
// Pick<DataFormatMixin, 'getDataParams' | 'formatTooltip'> {}
interface PayloadItem {
excludeSeriesId?: string | string[];
excludeSeriesId?: OptionId | OptionId[];
animation?: PayloadAnimationPart
[other: string]: any;
}
......@@ -302,12 +302,27 @@ export type OrdinalSortInfo = {
ordinalNumber: OrdinalNumber,
beforeSortIndex: number
};
export type ParsedValueNumeric = number | OrdinalNumber;
/**
* `OptionDataValue` is the primitive value in `series.data` or `dataset.source`.
* `OptionDataValue` are parsed (see `src/data/helper/dataValueHelper.parseDataValue`)
* into `ParsedValue` and stored into `data/List` storage.
* Note:
* (1) The term "parse" does not mean `src/scale/Scale['parse']`.
* (2) If a category dimension is not mapped to any axis, its raw value will NOT be
* parsed to `OrdinalNumber` but keep the original `OrdinalRawValue` in `src/data/List` storage.
*/
export type ParsedValue = ParsedValueNumeric | OrdinalRawValue;
// FIXME:TS better name?
// This is not `OptionDataPrimitive` because the "dataProvider parse"
// will not be performed. But "scale parse" will be performed.
export type ScaleDataValue = ParsedValue | Date;
export type ParsedValueNumeric = number | OrdinalNumber;
/**
* `ScaleDataValue` means that the user input primitive value to `src/scale/Scale`.
* (For example, used in `axis.min`, `axis.max`, `convertToPixel`).
* Note:
* `ScaleDataValue` is a little different from `OptionDataValue`, because it will not go through
* `src/data/helper/dataValueHelper.parseDataValue`, but go through `src/scale/Scale['parse']`.
*/
export type ScaleDataValue = ParsedValueNumeric | OrdinalRawValue | Date;
export interface ScaleTick {
value: number
};
......@@ -353,7 +368,7 @@ export interface DataVisualDimensions {
export type DimensionDefinition = {
type?: ListDimensionType,
name: DimensionName,
name?: DimensionName,
displayName?: string
};
export type DimensionDefinitionLoose = DimensionDefinition['name'] | DimensionDefinition;
......@@ -621,13 +636,13 @@ export interface MediaQuery {
maxAspectRatio?: number;
};
export type MediaUnit = {
query: MediaQuery,
query?: MediaQuery,
option: ECUnitOption
};
export type ComponentLayoutMode = {
// Only support 'box' now.
type: 'box',
type?: 'box',
ignoreSize?: boolean | boolean[]
};
/******************* Mixins for Common Option Properties ********************** */
......@@ -1329,8 +1344,6 @@ export interface SeriesOption<StateOption=any, ExtraStateOpts extends {
ColorPaletteOptionMixin,
StatesOptionMixin<StateOption, ExtraStateOpts>
{
name?: string
silent?: boolean
blendMode?: string
......
# Note:
# If eslint does not work in VSCode, please check:
# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser"
# are npm installed locally. Should better in the same version.
# (2) Whether "VSCode ESlint extension" is installed.
# (3) If the project folder is not the root folder of your working space, please
# config the "VSCode ESlint extension" in "settings":
# ```json
# "eslint.workingDirectories": [{"mode": "auto"}]
# ```
# Note that it should be "workingDirectories" rather than "WorkingDirectories".
parser: "@typescript-eslint/parser"
parserOptions:
# If using ES Module, ecmaVersion have to be set as `2015`.
ecmaVersion: 2015
sourceType: "module"
ecmaVersion: 6
sourceType: module
ecmaFeatures:
modules: true
project: "test/ut/tsconfig.json"
plugins: ["@typescript-eslint"]
env:
browser: true
node: true
jest: true
es6: false
globals:
jQuery: true
jQuery: false
Promise: true
rules:
no-console:
- 2
-
allow:
- "warn"
- "error"
no-constant-condition: 0
comma-dangle: 2
no-debugger: 2
no-dupe-keys: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 0
no-func-assign: 2
no-inner-declarations: 2
no-invalid-regexp: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-sparse-arrays: 2
no-unreachable: 2
use-isnan: 2
valid-typeof: 2
block-scoped-var: 0
curly:
- 2
- "all"
eqeqeq:
- 2
- "allow-null"
guard-for-in: 2
no-else-return: 0
no-labels:
- 2
-
allowLoop: true
no-eval: 2
no-extend-native: 2
no-extra-bind: 0
no-implied-eval: 2
no-iterator: 2
no-irregular-whitespace: 2
no-lone-blocks: 2
no-loop-func: 2
no-multi-str: 2
no-native-reassign: 2
no-new-wrappers: 2
no-octal: 2
no-octal-escape: 2
no-proto: 2
no-redeclare: 0
no-self-compare: 2
no-unneeded-ternary: 2
no-with: 2
radix: 2
wrap-iife:
- 2
- "any"
no-delete-var: 2
no-dupe-args: 2
no-duplicate-case: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-undef: 2
no-undef-init: 2
no-unused-vars:
- 2
-
vars: "local"
args: "none"
no-use-before-define: 0
brace-style:
- 2
- "stroustrup"
- {}
comma-spacing:
- 2
-
before: false
after: true
comma-style:
- 2
- "last"
new-parens: 2
no-array-constructor: 2
no-multi-spaces:
- 2
-
ignoreEOLComments: true
exceptions:
Property: true
no-new-object: 2
no-spaced-func: 2
no-trailing-spaces: 2
no-extra-parens:
- 2
- "functions"
no-mixed-spaces-and-tabs: 2
one-var:
- 2
- "never"
operator-linebreak:
- 2
- "before"
-
overrides:
"=": "after"
quotes:
- 2
- "single"
semi:
- 2
- "always"
semi-spacing: 2
keyword-spacing: 2
key-spacing:
- 2
-
beforeColon: false
afterColon: true
space-before-function-paren:
- 2
-
anonymous: "always"
named: "never"
space-before-blocks:
- 2
- "always"
computed-property-spacing:
- 2
- "never"
space-in-parens:
- 2
- "never"
space-unary-ops: 2
spaced-comment: 0
max-nested-callbacks:
- 1
- 5
max-depth:
- 1
- 6
max-len:
- 2
- 120
- 4
-
ignoreUrls: true
ignoreComments: true
max-params:
- 1
- 15
space-infix-ops: 2
dot-notation:
- 2
-
allowKeywords: true
allowPattern: "^catch$"
arrow-spacing: 2
constructor-super: 2
no-confusing-arrow:
- 2
-
allowParens: true
no-class-assign: 2
no-const-assign: 2
no-dupe-class-members: 2
no-this-before-super: 0
no-var: 0
no-duplicate-imports: 2
prefer-rest-params: 0
unicode-bom: 2
max-statements-per-line: 2
no-useless-constructor: 0
\ No newline at end of file
__DEV__: true
describe: true
beforeEach: true
afterEach: true
it: true
expect: true
extends: '../../.eslintrc-common.yaml'
......@@ -18,13 +18,13 @@
* under the License.
*/
import { isValueFinite } from './utHelper';
const utHelper = require('./utHelper');
// Setup expectes
expect.extend({
toBeFinite(received) {
const passed = utHelper.isValueFinite(received);
const passed = isValueFinite(received);
return {
message: passed
? () => `expected ${received} not to be finite`
......
......@@ -17,12 +17,12 @@
* under the License.
*/
const jsdom = require('jsdom');
const Canvas = require('canvas');
const {JSDOM} = jsdom;
const {window} = new JSDOM();
// import { JSDOM } from 'jsdom';
import { Image } from 'canvas';
global.window = window;
global.navigator = window.navigator;
global.document = window.document;
global.Image = Canvas.Image;
// const { window } = new JSDOM();
// (global as any).window = window;
// (global as any).navigator = window.navigator;
// (global as any).document = window.document;
(global as any).Image = Image;
......@@ -17,146 +17,111 @@
* under the License.
*/
/**
* @public
* @type {Object}
*/
var echarts = require('../../../index');
var utHelper = {};
var nativeSlice = Array.prototype.slice;
utHelper.createChart = function (width, height, theme, opts) {
var el = document.createElement('div');
import { init, EChartsType } from '../../../src/echarts.all';
import {
curry as zrUtilCurry,
bind as zrUtilBind,
extend as zrUtilExtend
} from 'zrender/src/core/util';
import { ComponentMainType } from '../../../src/util/types';
import Group from 'zrender/src/graphic/Group';
import Element from 'zrender/src/Element';
export function createChart(params?: {
width?: number,
height?: number,
theme?: Parameters<typeof init>[1],
opts?: Parameters<typeof init>[2]
}): EChartsType {
params = params || {};
const el = document.createElement('div');
el.style.cssText = [
'visibility:hidden',
'width:' + (width || '500') + 'px',
'height:' + (height || '400') + 'px',
'width:' + (params.width || '500') + 'px',
'height:' + (params.height || '400') + 'px',
'position:absolute',
'bottom:0',
'right:0'
].join(';');
var chart = echarts.init(el, theme, opts);
const chart = init(el, params.theme, params.opts);
return chart;
};
/**
* @public
*/
utHelper.removeChart = function (chart) {
export function removeChart(chart: EChartsType): void {
chart.dispose();
};
/**
* @param {*} target
* @param {*} source
*/
utHelper.extend = function (target, source) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
return target;
};
export const extend = zrUtilExtend;
/**
* @public
*/
utHelper.g = function (id) {
export function g(id: string): HTMLElement {
return document.getElementById(id);
};
}
/**
* @public
*/
utHelper.removeEl = function (el) {
var parent = utHelper.parentEl(el);
export function removeEl(el: HTMLElement): void {
const parent = parentEl(el);
parent && parent.removeChild(el);
};
}
/**
* @public
*/
utHelper.parentEl = function (el) {
export function parentEl(el: HTMLElement): HTMLElement {
//parentElement for ie.
return el.parentElement || el.parentNode;
};
return el.parentElement || el.parentNode as HTMLElement;
}
/**
* 得到head
*
* @public
*/
utHelper.getHeadEl = function (s) {
export function getHeadEl(): HTMLElement {
return document.head
|| document.getElementsByTagName('head')[0]
|| document.documentElement;
};
/**
* @public
*/
utHelper.curry = function (func) {
var args = nativeSlice.call(arguments, 1);
return function () {
return func.apply(this, args.concat(nativeSlice.call(arguments)));
};
};
/**
* @public
*/
utHelper.bind = function (func, context) {
var args = nativeSlice.call(arguments, 2);
return function () {
return func.apply(context, args.concat(nativeSlice.call(arguments)));
};
};
/**
* @public
*/
utHelper.isValueFinite = function (val) {
return val != null && val !== '' && isFinite(val);
};
/**
* @public
* @param {Array.<string>} deps
* @param {Array.<Function>} testFnList
* @param {Function} done All done callback.
*/
utHelper.resetAMDLoaderEachTest = function (deps, testFnList, done) {
var i = -1;
next();
function next() {
i++;
if (testFnList.length <= i) {
done();
return;
}
utHelper.resetAMDLoader(function () {
global.require(deps, function () {
testFnList[i].apply(null, arguments);
next();
});
});
}
};
utHelper.getGraphicElements = function (chartOrGroup, mainType, index) {
if (chartOrGroup.type === 'group') {
return chartOrGroup.children();
}
export const curry = zrUtilCurry;
export const bind = zrUtilBind;
export function isValueFinite(val: unknown): boolean {
return val != null && val !== '' && isFinite(val as number);
}
// /**
// * @public
// * @param {Array.<string>} deps
// * @param {Array.<Function>} testFnList
// * @param {Function} done All done callback.
// */
// export function resetAMDLoaderEachTest(deps, testFnList, done) {
// const i = -1;
// next();
// function next() {
// i++;
// if (testFnList.length <= i) {
// done();
// return;
// }
// utHelper.resetAMDLoader(function () {
// global.require(deps, function () {
// testFnList[i].apply(null, arguments);
// next();
// });
// });
// }
// };
export function getGraphicElements(
chartOrGroup: EChartsType | Group,
mainType: ComponentMainType,
index?: number
): Element[] {
if ((chartOrGroup as Group).type === 'group') {
return (chartOrGroup as Group).children();
}
else {
var viewGroup = utHelper.getViewGroup(chartOrGroup, mainType, index);
const viewGroup = getViewGroup(chartOrGroup as EChartsType, mainType, index);
if (viewGroup) {
var list = [viewGroup];
viewGroup.traverse(function (el) {
const list: Element[] = [viewGroup];
viewGroup.traverse(function (el: Element) {
list.push(el);
});
return list;
......@@ -165,13 +130,16 @@ utHelper.getGraphicElements = function (chartOrGroup, mainType, index) {
return [];
}
}
};
utHelper.getViewGroup = function (chart, mainType, index) {
var component = chart.getModel().getComponent(mainType, index);
}
export function getViewGroup(
chart: EChartsType,
mainType: ComponentMainType,
index?: number
): Group {
const component = chart.getModel().getComponent(mainType, index);
return component ? chart[
mainType === 'series' ? '_chartsMap' : '_componentsMap'
][component.__viewId].group : null;
};
}
module.exports = utHelper;
......@@ -17,27 +17,28 @@
* under the License.
*/
const path = require('path');
module.exports = {
testEnvironment: 'node',
rootDir: path.resolve(__dirname, '../../'),
preset: 'ts-jest',
testEnvironment: 'jsdom',
rootDir: __dirname,
collectCoverage: true,
setupFiles: [
'jest-canvas-mock',
'<rootDir>/test/ut/core/setup.js'
'<rootDir>/core/setup.ts'
],
setupFilesAfterEnv: [
'<rootDir>/test/ut/core/extendExpect.js'
'<rootDir>/core/extendExpect.ts'
],
globals: {
'__DEV__': true
},
testMatch: [
'**/spec/api/*.test.js',
'**/spec/component/**/*.test.js',
'**/spec/data/*.test.js',
'**/spec/model/*.test.js',
'**/spec/scale/*.test.js',
'**/spec/util/*.test.js',
'!**/spec/api/containPixel.test.js',
'!**/spec/component/graphic/setOption.test.js'
'**/spec/api/*.test.ts',
'**/spec/component/**/*.test.ts',
'**/spec/data/*.test.ts',
'**/spec/model/*.test.ts',
'**/spec/scale/*.test.ts',
'**/spec/util/*.test.ts',
'!**/spec/component/graphic/setOption.test.ts'
]
};
......@@ -18,16 +18,17 @@
* under the License.
*/
/* jshint maxlen:200 */
import { createChart, removeChart } from '../../core/utHelper';
import { EChartsType, registerMap } from '../../../../src/echarts';
import { GeoJSON } from '../../../../src/coord/geo/geoTypes';
const echarts = require('../../../../lib/echarts');
const utHelper = require('../../core/utHelper');
describe('api/containPixel', function () {
var testGeoJson1 = {
const testGeoJson1: GeoJSON = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
......@@ -59,10 +60,11 @@ describe('api/containPixel', function () {
]
};
var testGeoJson2 = {
const testGeoJson2: GeoJSON = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
......@@ -94,26 +96,23 @@ describe('api/containPixel', function () {
]
};
var chart = '';
var createResult = '';
let chart: EChartsType;
beforeEach(function () {
createResult = utHelper.createChart(context, echarts);
chart = createResult.charts[0];
chart = createChart({
width: 200,
height: 150
});
});
afterEach(function () {
utHelper.removeChart(createResult);
removeChart(chart);
});
it('geo', function () {
context.width = 200;
context.height = 150;
createResult = utHelper.createChart(context, echarts);
chart = createResult.charts[0];
echarts.registerMap('test1', testGeoJson1);
echarts.registerMap('test2', testGeoJson2);
registerMap('test1', testGeoJson1);
registerMap('test2', testGeoJson2);
chart.setOption({
geo: [
......@@ -149,8 +148,8 @@ describe('api/containPixel', function () {
]
});
var width = chart.getWidth();
var height = chart.getWidth();
const width = chart.getWidth();
// const height = chart.getWidth();
expect(chart.containPixel('geo', [15, 30])).toEqual(true);
expect(chart.containPixel('geo', [9.5, 30])).toEqual(false);
......@@ -161,12 +160,8 @@ describe('api/containPixel', function () {
it('map', function () {
context.width = 200;
context.height = 150;
createResult = utHelper.createChart(context, echarts);
chart = createResult.charts[0];
echarts.registerMap('test1', testGeoJson1);
echarts.registerMap('test2', testGeoJson2);
registerMap('test1', testGeoJson1);
registerMap('test2', testGeoJson2);
chart.setOption({
series: [
......@@ -190,7 +185,7 @@ describe('api/containPixel', function () {
]
});
var width = chart.getWidth();
const width = chart.getWidth();
expect(chart.containPixel('series', [15, 30])).toEqual(true);
expect(chart.containPixel('series', [9.5, 30])).toEqual(false);
......@@ -200,7 +195,7 @@ describe('api/containPixel', function () {
it('cartesian', function () {
echarts.registerMap('test1', testGeoJson1);
registerMap('test1', testGeoJson1);
chart.setOption({
geo: [ // Should not affect grid converter.
......@@ -268,38 +263,38 @@ describe('api/containPixel', function () {
{
id: 'k1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[1000, 700]]
},
{
id: 'k2',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[100, 800]]
},
{
id: 'j1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[100, 800]],
xAxisIndex: 1
},
{
id: 'i1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [],
xAxisId: 'x2',
yAxisId: 'y1'
......@@ -307,7 +302,7 @@ describe('api/containPixel', function () {
]
});
var width = chart.getWidth();
const width = chart.getWidth();
expect(chart.containPixel('grid', [15, 30])).toEqual(true);
expect(chart.containPixel('grid', [9.5, 30])).toEqual(false);
......@@ -336,7 +331,7 @@ describe('api/containPixel', function () {
// ]
// });
// var height = chart.getHeight();
// const height = chart.getHeight();
// expect(chart.containPixel('series', [40, height / 2])).toEqual(false);
// expect(chart.containPixel('series', [40, height / 2 + 10])).toEqual(true);
......@@ -345,8 +340,8 @@ describe('api/containPixel', function () {
// it('pieAndGeo', function () {
// echarts.registerMap('test1', testGeoJson1);
// echarts.registerMap('test2', testGeoJson2);
// registerMap('test1', testGeoJson1);
// registerMap('test2', testGeoJson2);
// chart.setOption({
// geo: [
......@@ -394,7 +389,7 @@ describe('api/containPixel', function () {
it('graph', function () {
echarts.registerMap('test1', testGeoJson1);
registerMap('test1', testGeoJson1);
chart.setOption({
geo: [ // Should not affect graph converter.
......@@ -426,4 +421,4 @@ describe('api/containPixel', function () {
});
});
\ No newline at end of file
});
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
......@@ -18,27 +17,33 @@
* under the License.
*/
/* jshint maxlen:200 */
var utHelper = require('../../core/utHelper');
var echarts = require('../../../../index');
import { EChartsType, registerMap } from '../../../../src/echarts';
import { GeoJSON } from '../../../../src/coord/geo/geoTypes';
import { createChart } from '../../core/utHelper';
describe('api/converter', function () {
var DELTA = 1E-3;
const DELTA = 1E-3;
function pointEquals(p1, p2) {
function pointEquals(p1: number | number[], p2: number | number[]): boolean {
if (p1 instanceof Array && p2 instanceof Array) {
return Math.abs(p1[0] - p2[0]) < DELTA && Math.abs(p1[1] - p2[1]) < DELTA;
}
else {
else if (typeof p1 === 'number' && typeof p2 === 'number') {
return Math.abs(p1 - p2) < DELTA;
}
else {
throw Error('Iillegal p1 or p2');
}
}
var testGeoJson1 = {
const testGeoJson1: GeoJSON = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
......@@ -70,10 +75,11 @@ describe('api/converter', function () {
]
};
var testGeoJson2 = {
const testGeoJson2: GeoJSON = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
......@@ -104,12 +110,12 @@ describe('api/converter', function () {
}
]
};
echarts.registerMap('converter_test_geo_1', testGeoJson1);
echarts.registerMap('converter_test_geo_2', testGeoJson2);
registerMap('converter_test_geo_1', testGeoJson1);
registerMap('converter_test_geo_2', testGeoJson2);
var chart;
let chart: EChartsType;
beforeEach(function () {
chart = utHelper.createChart();
chart = createChart();
});
afterEach(function () {
......@@ -153,8 +159,8 @@ describe('api/converter', function () {
]
});
var width = chart.getWidth();
var height = chart.getHeight();
const width = chart.getWidth();
const height = chart.getHeight();
expect(pointEquals(chart.convertToPixel('geo', [5000, 3000]), [width - 20, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel('geo', [width - 20, height - 40]), [5000, 3000])).toEqual(true);
......@@ -283,38 +289,38 @@ describe('api/converter', function () {
{
id: 'k1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[1000, 700]]
},
{
id: 'k2',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[100, 800]]
},
{
id: 'j1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [[100, 800]],
xAxisIndex: 1
},
{
id: 'i1',
type: 'scatter',
left: 0,
right: 0,
top: 0,
bottom: 0,
// left: 0,
// right: 0,
// top: 0,
// bottom: 0,
data: [],
xAxisId: 'x2',
yAxisId: 'y1'
......@@ -322,20 +328,36 @@ describe('api/converter', function () {
]
});
var width = chart.getWidth();
var height = chart.getHeight();
expect(pointEquals(chart.convertToPixel({seriesIndex: 1}, [-500, 6000]), [10, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({seriesIndex: 1}, [10, height - 40]), [-500, 6000])).toEqual(true);
expect(pointEquals(chart.convertToPixel({seriesId: 'i1'}, [300, 900]), [width - 20, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({seriesId: 'i1'}, [width - 20, height - 40]), [300, 900])).toEqual(true);
expect(pointEquals(chart.convertToPixel({xAxisIndex: 2, yAxisId: 'y1'}, [300, 900]), [width - 20, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({xAxisIndex: 2, yAxisId: 'y1'}, [width - 20, height - 40]), [300, 900])).toEqual(true);
expect(pointEquals(chart.convertToPixel({gridId: 'g1'}, [300, 900]), [width - 20, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({gridId: 'g1'}, [width - 20, height - 40]), [300, 900])).toEqual(true);
const width = chart.getWidth();
const height = chart.getHeight();
expect(
pointEquals(chart.convertToPixel({seriesIndex: 1}, [-500, 6000]), [10, height - 40])
).toEqual(true);
expect(
pointEquals(chart.convertFromPixel({seriesIndex: 1}, [10, height - 40]), [-500, 6000])
).toEqual(true);
expect(
pointEquals(chart.convertToPixel({seriesId: 'i1'}, [300, 900]), [width - 20, height - 40])
).toEqual(true);
expect(
pointEquals(chart.convertFromPixel({seriesId: 'i1'}, [width - 20, height - 40]), [300, 900])
).toEqual(true);
expect(
pointEquals(chart.convertToPixel({xAxisIndex: 2, yAxisId: 'y1'}, [300, 900]), [width - 20, height - 40])
).toEqual(true);
expect(
pointEquals(chart.convertFromPixel({xAxisIndex: 2, yAxisId: 'y1'}, [width - 20, height - 40]), [300, 900])
).toEqual(true);
expect(
pointEquals(chart.convertToPixel({gridId: 'g1'}, [300, 900]), [width - 20, height - 40])
).toEqual(true);
expect(
pointEquals(chart.convertFromPixel({gridId: 'g1'}, [width - 20, height - 40]), [300, 900])
).toEqual(true);
expect(pointEquals(chart.convertToPixel({xAxisId: 'x0'}, 3000), width / 2)).toEqual(true);
expect(pointEquals(chart.convertFromPixel({xAxisId: 'x0'}, width / 2), 3000)).toEqual(true);
......@@ -386,11 +408,19 @@ describe('api/converter', function () {
]
});
var width = chart.getWidth();
var height = chart.getHeight();
expect(pointEquals(chart.convertToPixel({seriesIndex: 0}, [2000, 3500]), [10 + (width - 30) / 2, 30 + (height - 70) / 2])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({seriesIndex: 0}, [10 + (width - 30) / 2, 30 + (height - 70) / 2]), [2000, 3500])).toEqual(true);
const width = chart.getWidth();
const height = chart.getHeight();
expect(
pointEquals(
chart.convertToPixel({seriesIndex: 0}, [2000, 3500]), [10 + (width - 30) / 2, 30 + (height - 70) / 2]
)
).toEqual(true);
expect(
pointEquals(
chart.convertFromPixel({seriesIndex: 0}, [10 + (width - 30) / 2, 30 + (height - 70) / 2]), [2000, 3500]
)
).toEqual(true);
expect(pointEquals(chart.convertToPixel({seriesId: 'k2'}, [100, 500]), [10, height - 40])).toEqual(true);
expect(pointEquals(chart.convertFromPixel({seriesId: 'k2'}, [10, height - 40]), [100, 500])).toEqual(true);
......
......@@ -18,25 +18,26 @@
* under the License.
*/
const utHelper = require('../../core/utHelper');
import { createChart } from '../../core/utHelper';
import { EChartsType } from '../../../../src/echarts';
/* jshint maxlen:200 */
describe('api/getVisual', function () {
describe('api/getVisual', function () {
// TODO
// test each chart type, which may set visual on view which can not get from List.
// each of which should test visual map.
// symbol and symbolSize should be tested.
var chart;
let chart: EChartsType;
beforeEach(function () {
chart = utHelper.createChart();
chart = createChart();
});
afterEach(function () {
chart.dispose();
});
it('scatter', function () {
chart.setOption({
xAxis: {},
......@@ -44,7 +45,7 @@ describe('api/getVisual', function () {
color: ['#000', '#111', '#222'],
visualMap: {
seriesIndex: 3,
demension: 1,
dimension: 1,
min: 0,
max: 10000,
inRange: {
......@@ -62,9 +63,7 @@ describe('api/getVisual', function () {
type: 'scatter',
data: [[10, 7]],
itemStyle: {
normal: {
color: '#fff'
}
color: '#fff'
}
},
{
......@@ -75,16 +74,12 @@ describe('api/getVisual', function () {
{
value: [333, 222],
itemStyle: {
normal: {
color: '#ff0'
}
color: '#ff0'
}
}
],
itemStyle: {
normal: {
color: '#eee'
}
color: '#eee'
}
},
{
......@@ -95,16 +90,12 @@ describe('api/getVisual', function () {
{
value: [333, 9999],
itemStyle: {
normal: {
color: '#ff0'
}
color: 'red'
}
}
],
itemStyle: {
normal: {
color: '#eee'
}
color: '#eee'
}
}
]
......@@ -118,7 +109,7 @@ describe('api/getVisual', function () {
expect(chart.getVisual({dataIndex: 1, seriesId: 'k2'}, 'color')).toEqual('#ff0');
expect(chart.getVisual({seriesId: 'k2'}, 'color')).toEqual('#eee');
expect(chart.getVisual({dataIndex: 1, seriesId: 'k3'}, 'color')).toEqual('rgba(255,0,0,1)');
expect(chart.getVisual({dataIndex: 1, seriesId: 'k3'}, 'color')).toEqual('red');
expect(chart.getVisual({seriesId: 'k3'}, 'color')).toEqual('#eee');
});
......@@ -145,16 +136,12 @@ describe('api/getVisual', function () {
{
value: [50, 222],
itemStyle: {
normal: {
color: '#ff0'
}
color: '#ff0'
}
}
],
itemStyle: {
normal: {
color: '#eee'
}
color: '#eee'
}
}
]
......@@ -167,7 +154,7 @@ describe('api/getVisual', function () {
// it('pie', function () {
// var chart = this.chart;
// const chart = this.chart;
// chart.setOption({
// series: [
......@@ -187,7 +174,7 @@ describe('api/getVisual', function () {
// ]
// });
// var height = chart.getHeight();
// const height = chart.getHeight();
// expect(chart.containPixel('series', [40, height / 2])).toEqual(false);
// expect(chart.containPixel('series', [40, height / 2 + 10])).toEqual(true);
......@@ -196,7 +183,7 @@ describe('api/getVisual', function () {
// it('graph', function () {
// var chart = this.chart;
// const chart = this.chart;
// chart.setOption({
// series: [
......
/*
* 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.
*/
const helper = require('../../../../../lib/component/dataZoom/helper');
const utHelper = require('../../../core/utHelper');
describe('dataZoom/helper', function () {
function makeRecords(result) {
var o = {};
helper.eachAxisDim(function (dimNames) {
o[dimNames.name] = {};
var r = result[dimNames.name] || [];
for (var i = 0; i < r.length; i++) {
o[dimNames.name][r[i]] = true;
}
});
return o;
}
describe('findLinkedNodes', function () {
function forEachModel(models, callback) {
for (var i = 0; i < models.length; i++) {
callback(models[i]);
}
}
function axisIndicesGetter(model, dimNames) {
return model[dimNames.axisIndex];
}
it('findLinkedNodes_base', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [1]},
{xAxisIndex: [5], yAxisIndex: []},
{xAxisIndex: [2, 5], yAxisIndex: []}
];
var result = helper.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
helper.eachAxisDim,
axisIndicesGetter
)(models[0]);
expect(result).toEqual({
nodes: [models[0], models[3], models[2]],
records: makeRecords({x: [1, 2, 5], y: [0]})
});
done();
});
it('findLinkedNodes_crossXY', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [3, 0]},
{xAxisIndex: [6, 3], yAxisIndex: [9]},
{xAxisIndex: [5, 3], yAxisIndex: []},
{xAxisIndex: [8], yAxisIndex: [4]}
];
var result = helper.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
helper.eachAxisDim,
axisIndicesGetter
)(models[0]);
expect(result).toEqual({
nodes: [models[0], models[1], models[2], models[3]],
records: makeRecords({x: [1, 2, 3, 5, 6], y: [0, 3, 9]})
});
done();
});
it('findLinkedNodes_emptySourceModel', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [3, 0]},
{xAxisIndex: [6, 3], yAxisIndex: [9]},
{xAxisIndex: [5, 3], yAxisIndex: []},
{xAxisIndex: [8], yAxisIndex: [4]}
];
var result = helper.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
helper.eachAxisDim,
axisIndicesGetter
)();
expect(result).toEqual({
nodes: [],
records: makeRecords({x: [], y: []})
});
done();
});
});
});
\ No newline at end of file
/*
* 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 { findEffectedDataZooms } from '../../../../../src/component/dataZoom/helper';
import { createChart } from '../../../core/utHelper';
import { EChartsType } from '../../../../../src/echarts';
describe('dataZoom/helper', function () {
describe('findLinkedNodes', function () {
let chart: EChartsType;
beforeEach(function () {
chart = createChart();
});
afterEach(function () {
chart.dispose();
});
it('findLinkedNodes_base', function () {
chart.setOption({
xAxis: [{}, {}, {}, {}, {}, {}],
yAxis: [{}, {}, {}, {}, {}, {}],
dataZoom: [
{ id: 'dz0', xAxisIndex: [1, 2], yAxisIndex: [0] },
{ id: 'dz1', xAxisIndex: [3], yAxisIndex: [1] },
{ id: 'dz2', xAxisIndex: [5], yAxisIndex: [] },
{ id: 'dz3', xAxisIndex: [2, 5], yAxisIndex: [] }
]
});
const payload = { type: 'dataZoom', dataZoomIndex: 0 };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
expect(dzModels.length === 3);
expect(dzModels[0] === chart.getModel().getComponent('dataZoom', 0)).toEqual(true);
expect(dzModels[1] === chart.getModel().getComponent('dataZoom', 3)).toEqual(true);
expect(dzModels[2] === chart.getModel().getComponent('dataZoom', 2)).toEqual(true);
});
it('findLinkedNodes_crossXY', function () {
chart.setOption({
xAxis: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
yAxis: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
dataZoom: [
{ id: 'dz0', xAxisIndex: [1, 2], yAxisIndex: [0] },
{ id: 'dz1', xAxisIndex: [3], yAxisIndex: [3, 0] },
{ id: 'dz2', xAxisIndex: [6, 3], yAxisIndex: [9] },
{ id: 'dz3', xAxisIndex: [5, 3], yAxisIndex: [] },
{ id: 'dz4', xAxisIndex: [8], yAxisIndex: [4] }
]
});
const payload = { type: 'dataZoom', dataZoomIndex: 0 };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
expect(dzModels.length === 4);
expect(dzModels[0] === chart.getModel().getComponent('dataZoom', 0)).toEqual(true);
expect(dzModels[1] === chart.getModel().getComponent('dataZoom', 1)).toEqual(true);
expect(dzModels[2] === chart.getModel().getComponent('dataZoom', 2)).toEqual(true);
expect(dzModels[3] === chart.getModel().getComponent('dataZoom', 3)).toEqual(true);
});
it('findLinkedNodes_emptySourceModel', function () {
chart.setOption({
xAxis: [{}, {}, {}, {}, {}, {}, {}, {}, {}],
yAxis: [{}, {}, {}, {}, {}, {}, {}, {}, {}],
dataZoom: [
{ id: 'dz0', xAxisIndex: [1, 2], yAxisIndex: [0] },
{ id: 'dz1', xAxisIndex: [3], yAxisIndex: [3, 0] },
{ id: 'dz2', xAxisIndex: [6, 3], yAxisIndex: [9] },
{ id: 'dz3', xAxisIndex: [5, 3], yAxisIndex: [] },
{ id: 'dz4', xAxisIndex: [8], yAxisIndex: [4] }
]
});
const payload = { type: 'other' };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
expect(dzModels.length === 0);
});
});
});
\ No newline at end of file
......@@ -17,15 +17,18 @@
* specific language governing permissions and limitations
* under the License.
*/
const sliderMove = require('../../../../../lib/component/helper/sliderMove');
import sliderMove from '../../../../../src/component/helper/sliderMove';
describe('component/helper/sliderMove', function () {
describe('sliderMove', function () {
it('normalize', function () {
// Return input handleEnds
var inputHandleEnds = [22, 50];
var outputHandleEnds = sliderMove(0, inputHandleEnds, [20, 50], 0);
const inputHandleEnds = [22, 50];
const outputHandleEnds = sliderMove(0, inputHandleEnds, [20, 50], 0);
expect(inputHandleEnds === outputHandleEnds).toEqual(true);
expect(outputHandleEnds).toEqual([22, 50]);
......
......@@ -17,12 +17,19 @@
* specific language governing permissions and limitations
* under the License.
*/
const utHelper = require('../../../core/utHelper');
import { createChart } from '../../../core/utHelper';
import { EChartsType } from '../../../../../src/echarts';
import { EChartsFullOption } from '../../../../../src/option';
import { ContinousVisualMapOption } from '../../../../../src/component/visualMap/ContinuousModel';
import { PiecewiseVisualMapOption } from '../../../../../src/component/visualMap/PiecewiseModel';
import VisualMapModel from '../../../../../src/component/visualMap/VisualMapModel';
describe('vsiaulMap_setOption', function () {
var chart;
let chart: EChartsType;
beforeEach(function () {
chart = utHelper.createChart();
chart = createChart();
});
afterEach(function () {
......@@ -41,12 +48,13 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
const option = chart.getOption();
const visualMapOptionGotten = option.visualMap as (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(option.visualMap[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(option.visualMap[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
done();
});
......@@ -60,12 +68,13 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
const option = chart.getOption();
const visualMapOptionGotten = option.visualMap as (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].color).toEqual(['yellow', 'blue', 'red']);
expect(option.visualMap[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(option.visualMap[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].color).toEqual(['yellow', 'blue', 'red']);
expect(visualMapOptionGotten[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
done();
});
......@@ -93,11 +102,12 @@ describe('vsiaulMap_setOption', function () {
expectTheSame(chart.getOption());
function expectTheSame(option) {
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(option.visualMap[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(option.visualMap[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
function expectTheSame(option: EChartsFullOption) {
const visualMapOptionGotten = option.visualMap as (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten[0].target.inRange.color).toEqual(['red', 'blue', 'yellow']);
expect(visualMapOptionGotten[0].controller.inRange.color).toEqual(['red', 'blue', 'yellow']);
done();
}
});
......@@ -115,7 +125,7 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
// const option = chart.getOption();
chart.setOption({
visualMap: {
......@@ -125,14 +135,15 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
const option = chart.getOption();
const visualMapOptionGotten = option.visualMap as (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].target.inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].controller.inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].inRange.symbolSize).toEqual([0.4, 0.6]);
expect(option.visualMap[0].target.inRange.symbolSize).toEqual([0.4, 0.6]);
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].target.inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].controller.inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].inRange.symbolSize).toEqual([0.4, 0.6]);
expect(visualMapOptionGotten[0].target.inRange.symbolSize).toEqual([0.4, 0.6]);
done();
// Do not compare controller.inRange.symbolSize, which will be amplified to controller size.
// expect(option.visualMap[0].controller.inRange.symbolSize).toEqual([?, ?]);
......@@ -159,15 +170,15 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].target.inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].controller.inRange.hasOwnProperty('color')).toEqual(false);
expect(option.visualMap[0].inRange.colorAlpha).toEqual([0.4, 0.6]);
expect(option.visualMap[0].target.inRange.colorAlpha).toEqual([0.4, 0.6]);
expect(option.visualMap[0].controller.inRange.colorAlpha).toEqual([0.4, 0.6]);
let visualMapOptionGotten: (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
visualMapOptionGotten = chart.getOption().visualMap as typeof visualMapOptionGotten;
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].target.inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].controller.inRange.hasOwnProperty('color')).toEqual(false);
expect(visualMapOptionGotten[0].inRange.colorAlpha).toEqual([0.4, 0.6]);
expect(visualMapOptionGotten[0].target.inRange.colorAlpha).toEqual([0.4, 0.6]);
expect(visualMapOptionGotten[0].controller.inRange.colorAlpha).toEqual([0.4, 0.6]);
chart.setOption({
visualMap: {
......@@ -175,13 +186,12 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
expect(option.visualMap.length).toEqual(1);
expect(option.visualMap[0].target.inRange.hasOwnProperty('colorAlpha')).toEqual(false);
expect(option.visualMap[0].controller.inRange.hasOwnProperty('colorAlpha')).toEqual(false);
expect(option.visualMap[0].target.inRange.color).toEqual(['green', 'blue', 'red']);
expect(option.visualMap[0].controller.inRange.color).toEqual(['green', 'blue', 'red']);
visualMapOptionGotten = chart.getOption().visualMap as typeof visualMapOptionGotten;
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].target.inRange.hasOwnProperty('colorAlpha')).toEqual(false);
expect(visualMapOptionGotten[0].controller.inRange.hasOwnProperty('colorAlpha')).toEqual(false);
expect(visualMapOptionGotten[0].target.inRange.color).toEqual(['green', 'blue', 'red']);
expect(visualMapOptionGotten[0].controller.inRange.color).toEqual(['green', 'blue', 'red']);
chart.setOption({
visualMap: {
......@@ -193,20 +203,20 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
visualMapOptionGotten = chart.getOption().visualMap as typeof visualMapOptionGotten;
expect(option.visualMap.length).toEqual(1);
expect(!!option.visualMap[0].target.inRange).toEqual(true);
var onlyColor = true;
for (var i in option.visualMap[0].target.inRange) {
expect(visualMapOptionGotten.length).toEqual(1);
expect(!!visualMapOptionGotten[0].target.inRange).toEqual(true);
let onlyColor = true;
for (const i in visualMapOptionGotten[0].target.inRange) {
if (i !== 'color') {
onlyColor = false;
}
}
var inRangeColor = option.visualMap[0].target.inRange.color;
const inRangeColor = visualMapOptionGotten[0].target.inRange.color;
expect(onlyColor).toEqual(true);
expect(inRangeColor).toEqual(['#f6efa6', '#d88273', '#bf444c']);
expect(option.visualMap[0].controller.outOfRange.symbol).toEqual(['diamond']);
expect(visualMapOptionGotten[0].controller.outOfRange.symbol).toEqual(['diamond']);
done();
});
......@@ -222,9 +232,10 @@ describe('vsiaulMap_setOption', function () {
}
});
var option = chart.getOption();
expect(!!option.visualMap[0].target.outOfRange.opacity).toEqual(true);
const visualMapOptionGotten = chart.getOption().visualMap as (
ContinousVisualMapOption | PiecewiseVisualMapOption
)[];
expect(!!visualMapOptionGotten[0].target.outOfRange.opacity).toEqual(true);
done();
});
......@@ -245,21 +256,21 @@ describe('vsiaulMap_setOption', function () {
]
});
var ecModel = chart.getModel();
const ecModel = chart.getModel();
function getVisual(idx, visualType) {
return ecModel.getComponent('visualMap', idx)
function getVisual(idx: number, visualType: 'color' | 'opacity' | 'symbol') {
return (ecModel.getComponent('visualMap', idx) as VisualMapModel)
.targetVisuals.inRange[visualType].option.visual;
}
function makeCategoryVisual(val) {
var CATEGORY_DEFAULT_VISUAL_INDEX = -1;
var arr = [];
if (val != null) {
arr[CATEGORY_DEFAULT_VISUAL_INDEX] = val;
function makeCategoryVisual(...args: unknown[]) {
const CATEGORY_DEFAULT_VISUAL_INDEX = -1;
const arr = [];
if (args[0] != null) {
arr[CATEGORY_DEFAULT_VISUAL_INDEX] = args[0];
}
for (var i = 1; i < arguments.length; i++) {
arr.push(arguments[i]);
for (let i = 1; i < args.length; i++) {
arr.push(args[i]);
}
return arr;
}
......
......@@ -17,14 +17,19 @@
* specific language governing permissions and limitations
* under the License.
*/
const Source = require('../../../../lib/data/Source');
const List = require('../../../../lib/data/List');
import List from '../../../../src/data/List';
import Model from '../../../../src/model/Model';
import { createSourceFromSeriesDataOption } from '../../../../src/data/Source';
describe('List', function () {
describe('Data Manipulation', function () {
it('initData 1d', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([10, 20, 30]);
expect(list.get('x', 0)).toEqual(10);
expect(list.get('x', 1)).toEqual(20);
......@@ -33,41 +38,41 @@ describe('List', function () {
});
it('initData 2d', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.get('x', 1)).toEqual(20);
expect(list.get('y', 1)).toEqual(25);
});
it('initData 2d yx', function () {
var list = new List(['y', 'x']);
const list = new List(['y', 'x'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.get('x', 1)).toEqual(25);
expect(list.get('y', 1)).toEqual(20);
});
it('Data with option 1d', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([1, {
value: 2,
somProp: 'foo'
}]);
expect(list.getItemModel(1).get('somProp')).toEqual('foo');
expect(list.getItemModel(0).get('somProp')).toBeNull();
expect(list.getItemModel(1).get('somProp' as any)).toEqual('foo');
expect(list.getItemModel(0).get('somProp' as any)).toBeNull();
});
it('Empty data', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([1, '-']);
expect(list.get('y', 1)).toBeNaN();
});
it('getRawValue', function () {
var list1 = new List(['x', 'y']);
const list1 = new List(['x', 'y'], new Model());
// here construct a new list2 because if we only use one list
// to call initData() twice, list._chunkCount will be accumulated
// to 1 instead of 0.
var list2 = new List(['x', 'y']);
const list2 = new List(['x', 'y'], new Model());
list1.initData([1, 2, 3]);
expect(list1.getItemModel(1).option).toEqual(2);
......@@ -77,22 +82,22 @@ describe('List', function () {
});
it('indexOfRawIndex', function () {
var list = new List(['x']);
const list = new List(['x'], new Model());
list.initData([]);
expect(list.indexOfRawIndex(1)).toEqual(-1);
var list1 = new List(['x']);
const list1 = new List(['x'], new Model());
list1.initData([0]);
expect(list1.indexOfRawIndex(0)).toEqual(0);
expect(list1.indexOfRawIndex(1)).toEqual(-1);
var list2 = new List(['x']);
const list2 = new List(['x'], new Model());
list2.initData([0, 1, 2, 3]);
expect(list2.indexOfRawIndex(1)).toEqual(1);
expect(list2.indexOfRawIndex(2)).toEqual(2);
expect(list2.indexOfRawIndex(5)).toEqual(-1);
var list3 = new List(['x']);
const list3 = new List(['x'], new Model());
list3.initData([0, 1, 2, 3, 4]);
expect(list3.indexOfRawIndex(2)).toEqual(2);
expect(list3.indexOfRawIndex(3)).toEqual(3);
......@@ -105,29 +110,29 @@ describe('List', function () {
});
it('getDataExtent', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([1, 2, 3]);
expect(list.getDataExtent('x')).toEqual([1, 3]);
expect(list.getDataExtent('y')).toEqual([1, 3]);
});
it('Data types', function () {
var list = new List([{
const list = new List([{
name: 'x',
type: 'int'
}, {
name: 'y',
type: 'float'
}]);
}], new Model());
list.initData([[1.1, 1.1]]);
expect(list.get('x', 0)).toEqual(1);
expect(list.get('y', 0)).toBeCloseTo(1.1, 5);
});
it('map', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.map(['x', 'y'], function (x, y) {
expect(list.map(['x', 'y'], function (x: number, y: number) {
return [x + 2, y + 2];
}).mapArray('x', function (x) {
return x;
......@@ -135,7 +140,7 @@ describe('List', function () {
});
it('mapArray', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.mapArray(['x', 'y'], function (x, y) {
return [x, y];
......@@ -143,7 +148,7 @@ describe('List', function () {
});
it('filterSelf', function () {
var list = new List(['x', 'y']);
const list = new List(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.filterSelf(['x', 'y'], function (x, y) {
return x < 30 && x > 10;
......@@ -153,14 +158,14 @@ describe('List', function () {
});
it('dataProvider', function () {
var list = new List(['x', 'y']);
var typedArray = new Float32Array([10, 10, 20, 20]);
var source = Source.seriesDataToSource(typedArray);
const list = new List(['x', 'y'], new Model());
const typedArray = new Float32Array([10, 10, 20, 20]);
const source = createSourceFromSeriesDataOption(typedArray);
list.initData({
count: function () {
return typedArray.length / 2;
},
getItem: function (idx) {
getItem: function (idx: number) {
return [typedArray[idx * 2], typedArray[idx * 2 + 1]];
},
getSource: function () {
......@@ -177,7 +182,7 @@ describe('List', function () {
describe('Data read', function () {
it('indicesOfNearest', function () {
var list = new List(['value']);
const list = new List(['value'], new Model());
// ---- index: 0 1 2 3 4 5 6 7
list.initData([10, 20, 30, 35, 40, 40, 35, 50]);
......@@ -194,4 +199,4 @@ describe('List', function () {
expect(list.indicesOfNearest('value', 50.5, 0.5)).toEqual([7]);
});
});
});
\ No newline at end of file
});
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
......@@ -17,19 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
const completeDimensions = require('../../../../lib/data/helper/completeDimensions');
const Source = require('../../../../lib/data/Source');
const types = require('../../../../lib/util/types');
import completeDimensions from '../../../../src/data/helper/completeDimensions';
import { createSource } from '../../../../src/data/Source';
import { SOURCE_FORMAT_ARRAY_ROWS, SERIES_LAYOUT_BY_COLUMN } from '../../../../src/util/types';
type ParametersOfCompleteDimensions = Parameters<typeof completeDimensions>;
describe('completeDimensions', function () {
function doCompleteDimensions(completeDimensions, sysDims, data, opt) {
var result = completeDimensions(sysDims, data, opt);
function doCompleteDimensions(
sysDims: ParametersOfCompleteDimensions[0],
data: ParametersOfCompleteDimensions[1],
opt: ParametersOfCompleteDimensions[2]
) {
const result = completeDimensions(sysDims, data, opt);
if (result) {
for (var i = 0; i < result.length; i++) {
var item = result[i];
if (item && item.hasOwnProperty('dimsDef') && item.dimsDef == null) {
delete item.dimsDef;
for (let i = 0; i < result.length; i++) {
const item = result[i];
if (item && item.hasOwnProperty('dimsDef') && (item as any).dimsDef == null) {
delete (item as any).dimsDef;
}
}
}
......@@ -37,12 +44,12 @@ describe('completeDimensions', function () {
}
it('namesMoreThanDimCount', function () {
var sysDims = [
const sysDims = [
{
'name': 'x',
'type': 'ordinal',
'type': 'ordinal' as const,
'otherDims': {
'tooltip': false,
'tooltip': false as const,
'itemName': 0
},
'dimsDef': [
......@@ -51,7 +58,7 @@ describe('completeDimensions', function () {
},
{
'name': 'y',
'type': 'float',
'type': 'float' as const,
'dimsDef': [
'open',
'close',
......@@ -61,14 +68,20 @@ describe('completeDimensions', function () {
}
];
var source = new Source({
data: [],
fromDataset: true,
sourceFormat: types.SOURCE_FORMAT_ARRAY_ROWS,
dimensionsDetectCount: 11
});
const source = createSource(
[
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
],
{
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
sourceHeader: 0,
dimensions: void 0
},
SOURCE_FORMAT_ARRAY_ROWS,
null
);
var opt = {
const opt = {
'dimsDef': [
{
'name': 'date',
......@@ -133,7 +146,7 @@ describe('completeDimensions', function () {
'dimCount': 5
};
var result = [
const result: unknown = [
{
'otherDims': {
'tooltip': false,
......@@ -240,13 +253,18 @@ describe('completeDimensions', function () {
}
];
expect(doCompleteDimensions(completeDimensions, sysDims, source, opt)).toEqual(result);
expect(doCompleteDimensions(sysDims, source, opt)).toEqual(result);
});
it('differentData', function () {
function doTest(sysDims, data, opt, result) {
expect(doCompleteDimensions(completeDimensions, sysDims, data, opt)).toEqual(result);
function doTest(
sysDims: ParametersOfCompleteDimensions[0],
data: ParametersOfCompleteDimensions[1],
opt: ParametersOfCompleteDimensions[2],
result: unknown
) {
expect(doCompleteDimensions(sysDims, data, opt)).toEqual(result);
}
// test dimcount
......@@ -372,11 +390,16 @@ describe('completeDimensions', function () {
it('differentSysDims', function () {
function doTest(sysDims, data, opt, result) {
expect(doCompleteDimensions(completeDimensions, sysDims, data, opt)).toEqual(result);
function doTest(
sysDims: ParametersOfCompleteDimensions[0],
data: ParametersOfCompleteDimensions[1],
opt: ParametersOfCompleteDimensions[2],
result: unknown
) {
expect(doCompleteDimensions(sysDims, data, opt)).toEqual(result);
}
var data = [
const data = [
['iw', 332, 4434, 323, 59],
['vrr', 44, 11, 144, 55]
];
......@@ -414,13 +437,14 @@ describe('completeDimensions', function () {
);
doTest(
[{name: 'time', type: 'time', stackable: false}, 'value'], data, null,
[{name: 'time', type: 'time' as const}, 'value'],
data,
null,
[
{
'otherDims': {},
'name': 'time',
'type': 'time',
'stackable': false,
'coordDimIndex': 0,
'ordinalMeta': undefined,
'coordDim': 'time'
......@@ -580,11 +604,16 @@ describe('completeDimensions', function () {
it('dimsDef', function () {
function doTest(sysDims, data, opt, result) {
expect(doCompleteDimensions(completeDimensions, sysDims, data, opt)).toEqual(result);
function doTest(
sysDims: ParametersOfCompleteDimensions[0],
data: ParametersOfCompleteDimensions[1],
opt: ParametersOfCompleteDimensions[2],
result: unknown
) {
expect(doCompleteDimensions(sysDims, data, opt)).toEqual(result);
}
var data = [['iw', 332, 4434, 323, 59], ['vrr', 44, 11, 144, 55]];
const data = [['iw', 332, 4434, 323, 59], ['vrr', 44, 11, 144, 55]];
doTest(
['x', 'y', 'value'], data,
{dimsDef: ['挨克思', null, '歪溜']},
......@@ -615,7 +644,7 @@ describe('completeDimensions', function () {
doTest(
['x', 'y', 'value'], data,
{dimsDef: ['挨克思', null, {type: 'ordinal'}]}, // no name but only type
{dimsDef: ['挨克思', null, {type: 'ordinal' as const}]}, // no name but only type
[
{
'otherDims': {},
......@@ -642,7 +671,7 @@ describe('completeDimensions', function () {
);
doTest(
[{name: 'time', type: 'time', stackable: false}, 'value'], data,
[{name: 'time', type: 'time' as const}, 'value'], data,
{dimsDef: [{name: '泰亩', type: 'ordinal'}, {name: '歪溜', type: 'float'}]},
[
{
......@@ -650,7 +679,6 @@ describe('completeDimensions', function () {
'displayName': '泰亩',
'name': '泰亩',
'type': 'ordinal',
'stackable': false,
'ordinalMeta': undefined,
'coordDimIndex': 0,
'coordDim': 'time'
......@@ -676,11 +704,16 @@ describe('completeDimensions', function () {
it('encodeDef', function () {
function doTest(sysDims, data, opt, result) {
expect(doCompleteDimensions(completeDimensions, sysDims, data, opt)).toEqual(result);
function doTest(
sysDims: ParametersOfCompleteDimensions[0],
data: ParametersOfCompleteDimensions[1],
opt: ParametersOfCompleteDimensions[2],
result: unknown
) {
expect(doCompleteDimensions(sysDims, data, opt)).toEqual(result);
}
var data = [['iw', 332, 4434, 323, 'd8', 59], ['vrr', 44, 11, 144, '-', 55]];
const data = [['iw', 332, 4434, 323, 'd8', 59], ['vrr', 44, 11, 144, '-', 55]];
doTest(
null, data,
......@@ -744,7 +777,7 @@ describe('completeDimensions', function () {
);
doTest(
['x', {name: 'y', type: 'time', stackable: false}, 'z'], data,
['x', {name: 'y', type: 'time' as const}, 'z'], data,
{
dimsDef: ['挨克思', null, '歪溜'],
encodeDef: {
......@@ -769,7 +802,6 @@ describe('completeDimensions', function () {
'coordDimIndex': 0,
'name': 'y',
'type': 'time',
'stackable': false,
'ordinalMeta': undefined
},
{
......@@ -785,14 +817,13 @@ describe('completeDimensions', function () {
);
doTest(
[{name: 'time', type: 'time', stackable: false}, 'value'], data,
[{name: 'time', type: 'time' as const}, 'value'], data,
{
// dimsDef type 'ordinal' has higher priority then sysDims type 'time'.
dimsDef: [{name: '泰亩', type: 'ordinal'}, {name: '歪溜', type: 'float'}],
encodeDef: {
tooltip: 2
},
extraPrefix: 'aaa'
}
},
[
{
......@@ -800,7 +831,6 @@ describe('completeDimensions', function () {
'displayName': '泰亩',
'name': '泰亩',
'type': 'ordinal',
'stackable': false,
'ordinalMeta': undefined,
'coordDimIndex': 0,
'coordDim': 'time'
......@@ -817,15 +847,13 @@ describe('completeDimensions', function () {
);
doTest(
[{name: 'time', type: 'time', stackable: false}, 'value'], data,
[{name: 'time', type: 'time' as const}, 'value'], data,
{
// dimsDef type 'ordinal' has higher priority then sysDims type 'time'.
dimsDef: [{name: '泰亩', type: 'ordinal'}, {name: '歪溜', type: 'float'}],
encodeDef: {
tooltip: 2
},
extraPrefix: 'aaa',
extraFromZero: true
}
},
[
{
......@@ -833,7 +861,6 @@ describe('completeDimensions', function () {
'displayName': '泰亩',
'name': '泰亩',
'type': 'ordinal',
'stackable': false,
'ordinalMeta': undefined,
'coordDimIndex': 0,
'coordDim': 'time'
......
......@@ -18,7 +18,8 @@
*/
const dataValueHelper = require('../../../../lib/data/helper/dataValueHelper');
import * as dataValueHelper from '../../../../src/data/helper/dataValueHelper';
const NO_SUCH_CASE = 'NO_SUCH_CASE';
......@@ -35,7 +36,15 @@ const TAG = {
BothIncmpr_NotEQ: 'BothIncmpr_NotEQ',
L_Incmpr_R_NumberOrString: 'L_Incmpr_R_NumberOrString',
R_Incmpr_L_NumberOrString: 'R_Incmpr_L_NumberOrString'
};
} as const;
type CaseTag = typeof TAG[keyof typeof TAG];
type Operation = 'lt' | 'lte' | 'gt' | 'gte' | 'eq' | 'ne';
type Order = 'asc' | 'desc';
type Incomparable = 'min' | 'max';
const tagRevertPairs = [
['BothNumeric_AtLeastOneNumber_L_LT_R', 'BothNumeric_AtLeastOneNumber_L_GT_R'],
['BothString_L_LT_R', 'BothString_L_GT_R'],
......@@ -44,7 +53,7 @@ const tagRevertPairs = [
['BothNumeric_OneNumber_NumericEQ', 'BothNumeric_OneNumber_NumericEQ'],
['BothIncmpr_NotEQ', 'BothIncmpr_NotEQ'],
['L_Incmpr_R_NumberOrString', 'R_Incmpr_L_NumberOrString']
];
] as const;
const filterResultMap = {
BothNumeric_AtLeastOneNumber_L_LT_R: {
......@@ -127,7 +136,7 @@ const filterResultMap = {
eq: false,
ne: true
}
};
} as const;
const sortResultMap = {
BothNumeric_AtLeastOneNumber_L_LT_R: {
......@@ -190,12 +199,11 @@ const sortResultMap = {
desc_incmprmin: -1,
desc_incmprmax: 1
}
};
} as const;
type EvaluateFunction = (lval: unknown, rval: unknown, caseTag: CaseTag) => void;
/**
* @param {(lval: unknown, rval: unknown, caseTag: TAG) => void} evalFn
*/
function eachRelationalComparisonCase(evalFn) {
function eachRelationalComparisonCase(evalFn: EvaluateFunction) {
const FULL_WIDTH_SPACE = String.fromCharCode(12288);
......@@ -300,7 +308,7 @@ function eachRelationalComparisonCase(evalFn) {
equalOtherTypes: function () {
const emptyObj = {};
const emptyArr = [];
const emptyArr = [] as unknown[];
const date = new Date(2012, 5, 12);
const fn = function () {};
expectDual(emptyObj, emptyObj, TAG.Strict_EQ);
......@@ -310,7 +318,7 @@ function eachRelationalComparisonCase(evalFn) {
}
};
function expectDual(lval, rval, caseTag) {
function expectDual(lval: unknown, rval: unknown, caseTag: CaseTag) {
validateCaseTag(caseTag);
evalFn(lval, rval, caseTag);
......@@ -319,11 +327,11 @@ function eachRelationalComparisonCase(evalFn) {
evalFn(rval, lval, revertedCaseTag);
}
function validateCaseTag(caseTag) {
function validateCaseTag(caseTag: CaseTag) {
expect(TAG.hasOwnProperty(caseTag)).toEqual(true);
}
function findRevertTag(caseTag) {
function findRevertTag(caseTag: CaseTag) {
for (let i = 0; i < tagRevertPairs.length; i++) {
const item = tagRevertPairs[i];
if (item[0] === caseTag) {
......@@ -335,18 +343,19 @@ function eachRelationalComparisonCase(evalFn) {
}
}
Object.keys(testerMap).forEach(name => testerMap[name]());
Object.keys(testerMap).forEach((name: keyof typeof testerMap) => testerMap[name]());
}
describe('data/helper/dataValueHelper', function () {
describe('filter_relational_comparison', function () {
function testFilterComparator(op) {
function testFilterComparator(op: Operation) {
it(op + '_filter_comparator', () => {
eachRelationalComparisonCase((lval, rval, caseTag) => {
expect(filterResultMap.hasOwnProperty[caseTag]);
expect(filterResultMap[caseTag].hasOwnProperty[op]);
expect(filterResultMap.hasOwnProperty(caseTag));
expect(filterResultMap[caseTag].hasOwnProperty(op));
const expectedResult = filterResultMap[caseTag][op];
if ((op === 'lt' || op === 'lte' || op === 'gt' || op === 'gte')
......@@ -358,7 +367,7 @@ describe('data/helper/dataValueHelper', function () {
}
else {
const comparator = dataValueHelper.createFilterComparator(op, rval);
expect(comparator.evaluate(lval, rval)).toEqual(expectedResult);
expect(comparator.evaluate(lval)).toEqual(expectedResult);
}
});
});
......@@ -372,15 +381,16 @@ describe('data/helper/dataValueHelper', function () {
});
describe('sort_relational_comparison', function () {
function testSortComparator(order, incomparable) {
function testSortComparator(order: Order, incomparable: Incomparable) {
const key = order + '_incmpr' + incomparable;
const SortOrderComparator = dataValueHelper.SortOrderComparator;
const sortOrderComparator = new SortOrderComparator(order, incomparable);
it(key + '_sort_comparator', () => {
eachRelationalComparisonCase((lval, rval, caseTag) => {
expect(sortResultMap.hasOwnProperty[caseTag]);
expect(sortResultMap[caseTag].hasOwnProperty[key]);
const expectedResult = sortResultMap[caseTag][key];
expect(sortResultMap.hasOwnProperty(caseTag));
expect(sortResultMap[caseTag].hasOwnProperty(key));
const expectedResult = (sortResultMap[caseTag] as any)[key];
expect(sortOrderComparator.evaluate(lval, rval)).toEqual(expectedResult);
});
});
......
/*
* 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.
*/
const ComponentModel = require('../../../../lib/model/Component');
describe('Component', function () {
let idx = 0;
function makeTypes(count) {
let arr = [];
for (let i = 0; i < count; i++) {
arr.push('type_' + idx++);
}
return arr;
}
describe('topologicalTravel', function () {
it('topologicalTravel_base', function () {
var [m1, a1, a2] = makeTypes(3);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a1});
ComponentModel.extend({type: a2});
var result = [];
var allList = ComponentModel.getAllClassMainTypes();
ComponentModel.topologicalTravel([m1, a1, a2], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_a1IsAbsent', function () {
var [m1, a1, a2] = makeTypes(3);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a2});
var allList = ComponentModel.getAllClassMainTypes();
var result = [];
ComponentModel.topologicalTravel([m1, a2], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a2, ['dataset']], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_empty', function () {
var [m1, a1, a2] = makeTypes(3);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a1});
ComponentModel.extend({type: a2});
var allList = ComponentModel.getAllClassMainTypes();
var result = [];
ComponentModel.topologicalTravel([], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([]);
});
it('topologicalTravel_isolate', function () {
var [m1, a1, a2] = makeTypes(3);
ComponentModel.extend({type: a2});
ComponentModel.extend({type: a1});
ComponentModel.extend({type: m1, dependencies: [a2]});
var allList = ComponentModel.getAllClassMainTypes();
var result = [];
ComponentModel.topologicalTravel([a1, a2, m1], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a1, ['dataset']], [a2, ['dataset']], [m1, ['dataset',a2]]]);
});
it('topologicalTravel_diamond', function () {
var [m1, a1, a2, a3] = makeTypes(4);
ComponentModel.extend({type: a1, dependencies: []});
ComponentModel.extend({type: a2, dependencies: [a1]});
ComponentModel.extend({type: a3, dependencies: [a1]});
ComponentModel.extend({type: m1, dependencies: [a2, a3]});
var allList = ComponentModel.getAllClassMainTypes();
var result = [];
ComponentModel.topologicalTravel([m1, a1, a2, a3], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a1, ['dataset']], [a3, ['dataset', a1]], [a2, ['dataset', a1]], [m1, ['dataset', a2, a3]]]);
});
it('topologicalTravel_loop', function () {
var [m1, m2, a1, a2, a3] = makeTypes(5);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: m2, dependencies: [m1, a2]});
ComponentModel.extend({type: a1, dependencies: [m2, a2, a3]});
ComponentModel.extend({type: a2});
ComponentModel.extend({type: a3});
var allList = ComponentModel.getAllClassMainTypes();
expect(function () {
ComponentModel.topologicalTravel([m1, m2, a1], allList);
}).toThrowError(/Circl/);
});
it('topologicalTravel_multipleEchartsInstance', function () {
var [m1, m2, a1, a2] = makeTypes(4);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a1});
ComponentModel.extend({type: a2});
var allList = ComponentModel.getAllClassMainTypes();
var result = [];
ComponentModel.topologicalTravel([m1, a1, a2], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]);
result = [];
ComponentModel.extend({type: m2, dependencies: [a1, m1]});
var allList = ComponentModel.getAllClassMainTypes();
ComponentModel.topologicalTravel([m2, m1, a1, a2], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]], [m2, ['dataset', a1, m1]]]);
});
it('topologicalTravel_missingSomeNodeButHasDependencies', function () {
var [m1, a1, a2, a3, a4] = makeTypes(5);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a2, dependencies: [a3]});
ComponentModel.extend({type: a3});
ComponentModel.extend({type: a4});
var result = [];
var allList = ComponentModel.getAllClassMainTypes();
ComponentModel.topologicalTravel([a3, m1], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]);
var result = [];
var allList = ComponentModel.getAllClassMainTypes();
ComponentModel.topologicalTravel([m1, a3], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_subType', function () {
var [m1, a1, a2, a3, a4] = makeTypes(5);
ComponentModel.extend({type: m1, dependencies: [a1, a2]});
ComponentModel.extend({type: a1 + '.aaa', dependencies: [a2]});
ComponentModel.extend({type: a1 + '.bbb', dependencies: [a3, a4]});
ComponentModel.extend({type: a2});
ComponentModel.extend({type: a3});
ComponentModel.extend({type: a4});
var result = [];
var allList = ComponentModel.getAllClassMainTypes();
ComponentModel.topologicalTravel([m1, a1, a2, a4], allList, function (componentType, dependencies) {
result.push([componentType, dependencies]);
});
expect(result).toEqual([[a4, ['dataset']], [a2, ['dataset']], [a1, ['dataset', a2, a3, a4]], [m1, ['dataset', a1, a2]]]);
});
});
});
\ No newline at end of file
/*
* 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 ComponentModel, { ComponentModelConstructor } from '../../../../src/model/Component';
import { ComponentMainType } from '../../../../src/util/types';
const componentModelConstructor = ComponentModel as ComponentModelConstructor;
describe('Component', function () {
let idx = 0;
function makeTypes(count: number): string[] {
const arr = [];
for (let i = 0; i < count; i++) {
arr.push('type_' + idx++);
}
return arr;
}
type TopoResultItem = [ComponentMainType, ComponentMainType[]];
describe('topologicalTravel', function () {
it('topologicalTravel_base', function () {
const [m1, a1, a2] = makeTypes(3);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a1});
componentModelConstructor.extend({type: a2});
const result: TopoResultItem[] = [];
const allList = componentModelConstructor.getAllClassMainTypes();
componentModelConstructor.topologicalTravel(
[m1, a1, a2],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_a1IsAbsent', function () {
const [m1, a1, a2] = makeTypes(3);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a2});
const allList = componentModelConstructor.getAllClassMainTypes();
const result: TopoResultItem[] = [];
componentModelConstructor.topologicalTravel(
[m1, a2],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a2, ['dataset']], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_empty', function () {
const [m1, a1, a2] = makeTypes(3);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a1});
componentModelConstructor.extend({type: a2});
const allList = componentModelConstructor.getAllClassMainTypes();
const result: TopoResultItem[] = [];
componentModelConstructor.topologicalTravel(
[],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([]);
});
it('topologicalTravel_isolate', function () {
const [m1, a1, a2] = makeTypes(3);
componentModelConstructor.extend({type: a2});
componentModelConstructor.extend({type: a1});
componentModelConstructor.extend({type: m1, dependencies: [a2]});
const allList = componentModelConstructor.getAllClassMainTypes();
const result: TopoResultItem[] = [];
componentModelConstructor.topologicalTravel(
[a1, a2, m1],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a1, ['dataset']], [a2, ['dataset']], [m1, ['dataset', a2]]]);
});
it('topologicalTravel_diamond', function () {
const [m1, a1, a2, a3] = makeTypes(4);
componentModelConstructor.extend({type: a1, dependencies: []});
componentModelConstructor.extend({type: a2, dependencies: [a1]});
componentModelConstructor.extend({type: a3, dependencies: [a1]});
componentModelConstructor.extend({type: m1, dependencies: [a2, a3]});
const allList = componentModelConstructor.getAllClassMainTypes();
const result: TopoResultItem[] = [];
componentModelConstructor.topologicalTravel(
[m1, a1, a2, a3],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual(
[[a1, ['dataset']],
[a3, ['dataset', a1]],
[a2, ['dataset', a1]],
[m1, ['dataset', a2, a3]]
]);
});
it('topologicalTravel_loop', function () {
const [m1, m2, a1, a2, a3] = makeTypes(5);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: m2, dependencies: [m1, a2]});
componentModelConstructor.extend({type: a1, dependencies: [m2, a2, a3]});
componentModelConstructor.extend({type: a2});
componentModelConstructor.extend({type: a3});
const allList = componentModelConstructor.getAllClassMainTypes();
expect(function () {
componentModelConstructor.topologicalTravel(
[m1, m2, a1],
allList,
() => {}
);
}).toThrowError(/Circl/);
});
it('topologicalTravel_multipleEchartsInstance', function () {
const [m1, m2, a1, a2] = makeTypes(4);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a1});
componentModelConstructor.extend({type: a2});
let allList = componentModelConstructor.getAllClassMainTypes();
let result: TopoResultItem[] = [];
componentModelConstructor.topologicalTravel(
[m1, a1, a2],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]);
result = [];
componentModelConstructor.extend({type: m2, dependencies: [a1, m1]});
allList = componentModelConstructor.getAllClassMainTypes();
componentModelConstructor.topologicalTravel(
[m2, m1, a1, a2],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual(
[[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]], [m2, ['dataset', a1, m1]]]
);
});
it('topologicalTravel_missingSomeNodeButHasDependencies', function () {
const [m1, a1, a2, a3, a4] = makeTypes(5);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a2, dependencies: [a3]});
componentModelConstructor.extend({type: a3});
componentModelConstructor.extend({type: a4});
let result: TopoResultItem[] = [];
let allList = componentModelConstructor.getAllClassMainTypes();
componentModelConstructor.topologicalTravel(
[a3, m1],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]);
result = [];
allList = componentModelConstructor.getAllClassMainTypes();
componentModelConstructor.topologicalTravel(
[m1, a3],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]);
});
it('topologicalTravel_subType', function () {
const [m1, a1, a2, a3, a4] = makeTypes(5);
componentModelConstructor.extend({type: m1, dependencies: [a1, a2]});
componentModelConstructor.extend({type: a1 + '.aaa', dependencies: [a2]});
componentModelConstructor.extend({type: a1 + '.bbb', dependencies: [a3, a4]});
componentModelConstructor.extend({type: a2});
componentModelConstructor.extend({type: a3});
componentModelConstructor.extend({type: a4});
const result: TopoResultItem[] = [];
const allList = componentModelConstructor.getAllClassMainTypes();
componentModelConstructor.topologicalTravel(
[m1, a1, a2, a4],
allList,
function (componentType, dependencies) {
result.push([componentType, dependencies]);
}
);
expect(result).toEqual(
[[a4, ['dataset']],
[a2, ['dataset']],
[a1, ['dataset', a2, a3, a4]],
[m1, ['dataset', a1, a2]]
]);
});
});
});
\ No newline at end of file
......@@ -17,26 +17,37 @@
* specific language governing permissions and limitations
* under the License.
*/
const utHelper = require('../../core/utHelper');
import { EChartsType } from '../../../../src/echarts';
import SeriesModel from '../../../../src/model/Series';
import { ParsedValue } from '../../../../src/util/types';
import { LegendOption } from '../../../../src/component/legend/LegendModel';
import TimelineModel from '../../../../src/component/timeline/TimelineModel';
import { createChart } from '../../core/utHelper';
import { EChartsFullOption } from '../../../../src/option';
describe('timelineMediaOptions', function () {
function getData0(chart, seriesIndex) {
function getData0(chart: EChartsType, seriesIndex: number): ParsedValue {
return getSeries(chart, seriesIndex).getData().get('y', 0);
}
function getSeries(chart, seriesIndex) {
return chart.getModel().getComponent('series', seriesIndex);
function getSeries(chart: EChartsType, seriesIndex: number): SeriesModel {
return chart.getModel().getComponent('series', seriesIndex) as SeriesModel;
}
function getLegendOption(chart) {
function getLegendOption(chart: EChartsType): LegendOption {
return chart.getModel().getComponent('legend', 0).option;
}
function getTimelineComponent(chart) {
return chart.getModel().getComponent('timeline', 0);
function getTimelineComponent(chart: EChartsType): TimelineModel {
return chart.getModel().getComponent('timeline', 0) as TimelineModel;
}
var chart;
let chart: EChartsType;
beforeEach(function () {
chart = utHelper.createChart(10, 10);
chart = createChart({
width: 10,
height: 10
});
});
afterEach(function () {
......@@ -49,7 +60,7 @@ describe('timelineMediaOptions', function () {
describe('parse_timeline_media_option', function () {
it('parse_media_has_baseOption_has_default', function () {
var option = {
const option: EChartsFullOption = {
baseOption: {
xAxis: { data: ['a'] },
yAxis: {},
......@@ -77,7 +88,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_media_no_baseOption_has_default', function () {
var option = {
const option: EChartsFullOption = {
xAxis: { data: ['a'] },
yAxis: {},
legend: { left: 10 },
......@@ -101,7 +112,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_media_no_baseOption_no_default', function () {
var option = {
const option: EChartsFullOption = {
xAxis: { data: ['a'] },
yAxis: {},
legend: { left: 10 },
......@@ -121,7 +132,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_media_has_baseOption', function () {
var option = {
const option: EChartsFullOption = {
baseOption: {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
......@@ -161,7 +172,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_media_no_baseOption', function () {
var option = {
const option: EChartsFullOption = {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
yAxis: {},
......@@ -197,7 +208,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_has_baseOption', function () {
var option = {
const option: EChartsFullOption = {
baseOption: {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
......@@ -221,7 +232,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_has_baseOption_compat', function () {
var option = {
const option: EChartsFullOption = {
timeline: { axisType: 'category' },
baseOption: {
xAxis: { data: ['a'] },
......@@ -245,7 +256,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_has_baseOption_compat', function () {
var option = {
const option: EChartsFullOption = {
timeline: { axisType: 'category' },
baseOption: {
xAxis: { data: ['a'] },
......@@ -269,7 +280,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_no_baseOption', function () {
var option = {
const option: EChartsFullOption = {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
yAxis: {},
......@@ -299,7 +310,7 @@ describe('timelineMediaOptions', function () {
describe('timeline_onceMore', function () {
it('timeline_setOptionOnceMore_baseOption', function () {
var option = {
const option: EChartsFullOption = {
baseOption: {
timeline: {
axisType: 'category',
......@@ -347,7 +358,7 @@ describe('timelineMediaOptions', function () {
it('timeline_setOptionOnceMore_substitudeTimelineOptions', function () {
var option = {
const option: EChartsFullOption = {
baseOption: {
timeline: {
axisType: 'category',
......@@ -377,7 +388,7 @@ describe('timelineMediaOptions', function () {
};
chart.setOption(option);
var ecModel = chart.getModel();
let ecModel = chart.getModel();
expect(getData0(chart, 0)).toEqual(1111);
expect(getData0(chart, 1)).toEqual(2222);
......@@ -399,9 +410,9 @@ describe('timelineMediaOptions', function () {
}]
});
var ecModel = chart.getModel();
var option = ecModel.getOption();
expect(option.backgroundColor).toEqual('#987654');
ecModel = chart.getModel();
const optionGotten = ecModel.getOption();
expect(optionGotten.backgroundColor).toEqual('#987654');
expect(getData0(chart, 0)).toEqual(1111);
expect(getData0(chart, 1)).toEqual(2222);
......
......@@ -17,22 +17,25 @@
* specific language governing permissions and limitations
* under the License.
*/
const layoutUtil = require('../../../../lib/util/layout');
// import { Dictionary } from 'zrender/src/core/types';
import { mergeLayoutParam } from '../../../../src/util/layout';
import { BoxLayoutOptionMixin } from '../../../../src/util/types';
describe('util/number', function () {
describe('mergeLayoutParam', function () {
// The given obj has exactly the given props, has no other props.
function expectPropsEqual(obj, props) {
function expectPropsEqual(obj: object, props: object): void {
expect(propContain(obj, props) && propContain(props, obj)).toEqual(true);
}
function propContain(more, less) {
for (var key in more) {
function propContain(more: object, less: object): boolean {
for (const key in more) {
if (more.hasOwnProperty(key)) {
if (more[key] !== less[key]
&& !(more[key] == null && less[key] == null)
if ((more as any)[key] !== (less as any)[key]
&& !((more as any)[key] == null && (less as any)[key] == null)
) {
return false;
}
......@@ -41,9 +44,9 @@ describe('util/number', function () {
return true;
}
function shadowClone(obj) {
var newObj = {};
for (var key in obj) {
function shadowClone<T extends object>(obj: T): T {
const newObj = {} as T;
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
......@@ -53,18 +56,23 @@ describe('util/number', function () {
it('all', function () {
function testMerge(targetOption, newOption, result, resultIgnoreSize) {
var t1 = shadowClone(targetOption);
var t2 = shadowClone(targetOption);
var n1 = shadowClone(newOption);
var n2 = shadowClone(newOption);
layoutUtil.mergeLayoutParam(t1, n1);
layoutUtil.mergeLayoutParam(t2, n2, {ignoreSize: true});
function testMerge(
targetOption: BoxLayoutOptionMixin,
newOption: BoxLayoutOptionMixin,
result: BoxLayoutOptionMixin,
resultIgnoreSize?: BoxLayoutOptionMixin
) {
const t1 = shadowClone(targetOption);
const t2 = shadowClone(targetOption);
const n1 = shadowClone(newOption);
const n2 = shadowClone(newOption);
mergeLayoutParam(t1, n1);
mergeLayoutParam(t2, n2, {ignoreSize: true});
expectPropsEqual(t1, result);
expectPropsEqual(t2, resultIgnoreSize || result);
}
function singleValueAdd(val) {
function singleValueAdd(val: number | string): void {
testMerge({}, {width: val}, {width: val});
testMerge({}, {left: val}, {left: val});
testMerge({}, {right: val}, {right: val});
......@@ -79,7 +87,7 @@ describe('util/number', function () {
singleValueAdd('right');
singleValueAdd('center');
function singleValueReplace(val) {
function singleValueReplace(val: number | string): void {
testMerge({width: -999}, {width: val}, {width: val});
testMerge({left: -999}, {left: val}, {left: val});
testMerge({right: -999}, {right: val}, {right: val});
......
{
"compilerOptions": {
"target": "ES3",
"noImplicitAny": true,
"noImplicitThis": true,
"strictBindCallApply": true,
"removeComments": true,
"sourceMap": true,
// https://github.com/ezolenko/rollup-plugin-typescript2/issues/12#issuecomment-536173372
"moduleResolution": "node",
"importHelpers": true,
"pretty": true
},
"include": [
"../../src/global.d.ts",
"**/*.ts"
],
"exclude": [
]
}
\ No newline at end of file
......@@ -22,7 +22,6 @@
},
"include": [
"src/**/*.ts",
"echarts.*.ts",
"extension-src/**/*.ts"
]
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册