Please visit the official Apache ECharts Website at

https://echarts.apache.org
Visit Official Website
x

Coding Standard

Please follow this standard when contributing to ECharts project.

Apache EChartsTM

Code Style

File

[MUST] JavaScript Source files must be encoded in UTF-8 without BOM.

Indentation

[MUST] 4 space indentation. tabs and 2 space are not allowed.

[MUST] case and default in switch must be indented.

// good
switch (variable) {
    case '1':
        // do...
        break;
    case '2':
        // do...
        break;
    default:
        // do...
}

// bad
switch (variable) {
case '1':
    // do...
    break;
case '2':
    // do...
    break;
default:
    // do...
}

Space

[MUST] Set off binary operator with spaces. But place no space between unary operator and its operand.

let a = !arr.length;
a++;
a = b + c;

[MUST] Place 1 space before the leading brace.

// good

if (condition) {
}

set('attr', {
    some: 'xxx',
    any: 'yyy'
});

function funcName() {
}


// bad

if (condition){
}

set('attr',{
    some: 'xxx',
    any: 'yyy'
});

function funcName(){
}

[MUST] Place 1 space after if / else / for / while / function / switch / do / try / catch / finally.

// good

if (condition) {
}

while (condition) {
}

(function () {
})();


// bad

if(condition) {
}

while(condition) {
}

(function() {
})();

[MUST] In the object creating statement, place 1 space after :, but no space before it.

// good
const obj = {
    a: 1,
    b: 2,
    c: 3
};

// bad
const obj = {
    a : 1,
    b:2,
    c :3
};

[MUST] Place no space between the function name and ( in function declaration, expression of named function and function call.

// good

function funcName() {
}

const funcName = function funcName() {
};

funcName();


// bad

function funcName () {
}

const funcName = function funcName () {
};

funcName ();

[MUST] Place no space between , and ;.

// good
callFunc(a, b);

// bad
callFunc(a , b) ;

[MUST] Place no space after ( and [ and before ) and ].

// good

callFunc(param1, param2, param3);

save(this.list[this.indexes[i]]);

needIncream && (variable += increament);

if (num > list.length) {
}

while (len--) {
}


// bad

callFunc( param1, param2, param3 );

save( this.list[ this.indexes[ i ] ] );

needIncreament && ( variable += increament );

if ( num > list.length ) {
}

while ( len-- ) {
}


// good
const arr1 = [];
const arr2 = [1, 2, 3];
const obj1 = {};
const obj2 = {name: 'obj'};
const obj3 = {
    name: 'obj',
    age: 20,
    sex: 1
};

// bad
const arr1 = [ ];
const arr2 = [ 1, 2, 3 ];
const obj1 = { };
const obj2 = { name: 'obj' };
const obj3 = {name: 'obj', age: 20, sex: 1};

[MUST] Must no trailing space in each line.

Line Break

[MUST] Place line break in the end of a statement.

[MUST] No more than 120 characters per line.

[MUST] Place operator at the beginning of a line if it break lines.

// good
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}

const result = number1 + number2 + number3
    + number4 + number5;


// bad
if (user.isAuthenticated() &&
    user.isInRole('admin') &&
    user.hasAuthority('add-admin') ||
    user.hasAuthority('delete-admin')) {
    // Code
}

const result = number1 + number2 + number3 +
    number4 + number5;

[MUST] Start a new line for ), ], } if the content inside the brackets occupies multiple lines. Make the same indent as the line where the corresponding (, [, { placed.

// good
if (product) {
    product.load();
    if (user.isAuthenticated()
        && user.isInRole('admin')
        && user.hasAuthority('add-admin')
    ) {
        sendProduct(user, product);
    }
}
const arr = [
    'candy', 'sugar'
];

// bad
if (product) {
    product.load();
    if (user.isAuthenticated()
        && user.isInRole('admin')
        && user.hasAuthority('add-admin')) {
        sendProduct(user, product);
    }
}
const arr = [
        'candy', 'sugar'
    ];

[MUST] Must not break lines before , or ;.

// good
const obj = {
    a: 1,
    b: 2,
    c: 3
};

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);


// bad
const obj = {
    a: 1
    , b: 2
    , c: 3
};

foo(
    aVeryVeryLongArgument
    , anotherVeryLongArgument
    , callback
);

[SUGGEST] Suggestion about line break and indent:

if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
) {
    // Code
}

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);

baidu.format(
    dateFormatTemplate,
    year, month, date, hour, minute, second
);

$('#items')
    .find('.selected')
    .highlight()
    .end();

const result = thisIsAVeryVeryLongCondition
    ? resultA : resultB;

const res = condition
    ? thisIsAVeryVeryLongResult
    : resultB;

[MUST] Start a new line for else and catch if using multi-line blocks.

// good

if (condition) {
    // some statements;
}
else {
    // some statements;
}

try {
    // some statements;
}
catch (ex) {
    // some statements;
}


// bad

if (condition) {
    // some statements;
} else {
    // some statements;
}

try {
    // some statements;
} catch (ex) {
    // some statements;
}

Statement

[MUST] The semicolon must not be ignored at the end of a statement.

[MUST] The {} must not be ignored even if there is only one line.

// good
if (condition) {
    callFunc();
}

// bad
if (condition) callFunc();
if (condition)
    callFunc();

[MUST] Place no semicolon at the end of a function definition.

// good
function funcName() {
}

// bad
function funcName() {
};

// For function expression, the semicolon must not be ignored.
const funcName = function () {
};

[MUST] No trailing comma in object and array declarations.

// good

const obj = {
    attr1: 'xxx',
    attr2: 'yyy'
};

const arr = [
    'xxx',
    'yyy'
];


// bad

const obj = {
    attr1: 'xxx',
    attr2: 'yyy',
};

const arr = [
    'xxx',
    'yyy',
];

Naming Conventions

[MUST] Use lowerCamelCase for variables, properties and function names.

const loadingModules = {};
function loadProduct() {
}

[MUST] Use UpperCamelCase (Pascal) for class names.

function Element(options) {
}

[SUGGEST] All of the letters of a abbreviation should be both upper cases or both lower cases.

function parseSVG() {
}
const svgParser;

Language features

Compatibility

Language features can be polyfilled by some utilities, but must not by modifying the prototype of the built-in JS objects.

// good

import * as zrUtil from 'zrender/src/core/util';

zrUtil.each(array, function (val, index) {
    sum += val;
});

const result = zrUtil.map(array, function (val) {
    return parse(val);
});

const pos = zrUtil.indexOf(array, val);

const obj2 = zrUtil.extend({}, obj1);

function Element() {
    // ...
}


// bad

array.forEach(function (val, index) {
    sum += val;
});

let result = array.map(function (val) {
    return parse(val);
});

const pos = array.indexOf(val);

const obj2 = Object.assign({}, obj1);

class Element {
    // ...
}

String.prototype.trim = function () {
};

Variable

[MUST] Prefer using const to declare variable. And one line can not declares more than one variable.

// good
const name = 'MyName';
const hangModules = [];
const missModules = [];
const visited = {};

// bad
name = 'MyName';
const hangModules = [],
    missModules = [],
    visited = {};

Condition

[MUST] In equality expression, == can only be used on null or undefined detection. === should be used in the rest of cases .

// good
if (age === 30) {
    // ...
}
if (type == null) {
    // ...
}

// bad
if (age == 30) {
    // ......
}

[SUGGEST] Use xxx == null to determine null or undefined.

[SUGGEST] Try best to make the meaning of null and undefined the same, namely, do not make users or developers distinguishing whether a variable is null or undefined.

[SUGGEST] The function expression or function declaration should not be placed inside a loop body.

// good
function clicker() {
    // ......
}

for (let i = 0, len = elements.length; i < len; i++) {
    const element = elements[i];
    addListener(element, 'click', clicker);
}


// bad
for (let i = 0, len = elements.length; i < len; i++) {
    const element = elements[i];
    addListener(element, 'click', function () {});
}

Type Conversion

[SUGGEST] Use + '' to convert a value to string.

// good
num + '';

// bad
new String(num);
num.toString();
String(num);

[SUGGEST] Use + to convert a value to number.

// good
+str;

// bad
Number(str);

[MUST] The second parameter must not be ignored when using parseInt.

// good
parseInt(str, 10);

// bad
parseInt(str);

String, Object, Array

[MUST] Use ' but not " to define a string.

[MUST] Use object literal {} to create a plain object.

// good
const obj = {};

// bad
const obj = new Object();

[MUST] If all of the properties of an object literal do not need quotation marks, they should ignore them. If quotation marks is necessary, use ' but not ".

// good
const info = {
    name: 'someone',
    age: 28
};

// bad
const info = {
    'name': 'someone',
    'age': 28
};
const info2 = {
    "age": 40
};

[MUST] The prototype of built-in objects must not be modified.

// Forbidden
String.prototype.trim = function () {
};

[SUGGEST] Try best to use . but not [] to visit properties of an object.

[SUGGEST] hasOwnProperty should be used to when using for ... in ..., in case that some extra properties is added on the prototype of Object in some runtime environment.

const newInfo = {};
for (const key in info) {
    if (info.hasOwnProperty(key)) {
        newInfo[key] = info[key];
    }
}

[MUST] Use array literal [] to create an array, except intending to create an array with a given length.

// good
const arr = [];
const arr2 = new Array(1e4);

// bad
const arr = new Array();

[MUST] Do not use for in in array traverse.

Others

[MUST] Do not use eval and with. new Function can be used.