提交 ca83c55b 编写于 作者: 1 100pah

Merge branch 'master' into fix/geo-svg

......@@ -36,13 +36,13 @@ jobs:
run: |
npm run release
test:
runs-on: ubuntu-latest
needs: build
# test:
# runs-on: ubuntu-latest
# needs: build
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release'
# # if: ${{ github.base_ref == 'refs/heads/master' || github.base_ref == 'refs/heads/release' }}
steps:
- name: unit test
run: |
npm run test
# steps:
# - name: unit test
# run: |
# npm run test
......@@ -71,6 +71,7 @@ export interface EffectScatterSeriesOption extends SeriesOption<EffectScatterSta
* When to show the effect
*/
showEffectOn?: 'render' | 'emphasis'
clip?: boolean
/**
* Ripple effect config
......@@ -107,6 +108,7 @@ class EffectScatterSeriesModel extends SeriesModel<EffectScatterSeriesOption> {
// When to show the effect, option: 'render'|'emphasis'
showEffectOn: 'render',
clip: true,
// Ripple effect config
rippleEffect: {
......
......@@ -41,10 +41,16 @@ class EffectScatterView extends ChartView {
render(seriesModel: EffectScatterSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const data = seriesModel.getData();
const effectSymbolDraw = this._symbolDraw;
effectSymbolDraw.updateData(data);
effectSymbolDraw.updateData(data, {clipShape: this._getClipShape(seriesModel)});
this.group.add(effectSymbolDraw.group);
}
_getClipShape(seriesModel: EffectScatterSeriesModel) {
const coordSys = seriesModel.coordinateSystem;
const clipArea = coordSys && coordSys.getArea && coordSys.getArea();
return seriesModel.get('clip', true) ? clipArea : null;
}
updateTransform(seriesModel: EffectScatterSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const data = seriesModel.getData();
......
......@@ -30,6 +30,10 @@ import { ColorString, ECElement } from '../../util/types';
import List from '../../data/List';
import Sausage from '../../util/shape/sausage';
import {createSymbol} from '../../util/symbol';
import ZRImage from 'zrender/src/graphic/Image';
import {extend} from 'zrender/src/core/util';
type ECSymbol = ReturnType<typeof createSymbol>;
interface PosInfo {
cx: number
......@@ -476,9 +480,25 @@ class GaugeView extends ChartView {
const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
const emphasisModel = itemModel.getModel('emphasis');
if (showPointer) {
const pointer = data.getItemGraphicEl(idx) as PointerPath;
pointer.useStyle(data.getItemVisual(idx, 'style'));
const pointer = data.getItemGraphicEl(idx) as ECSymbol;
const symbolStyle = data.getItemVisual(idx, 'style');
const visualColor = symbolStyle.fill;
if (pointer instanceof ZRImage) {
const pathStyle = pointer.style;
pointer.useStyle(extend({
image: pathStyle.image,
x: pathStyle.x, y: pathStyle.y,
width: pathStyle.width, height: pathStyle.height
}, symbolStyle));
}
else {
pointer.useStyle(symbolStyle);
pointer.type !== 'pointer' && pointer.setColor(visualColor);
}
pointer.setStyle(itemModel.getModel(['pointer', 'itemStyle']).getItemStyle());
if (pointer.style.fill === 'auto') {
pointer.setStyle('fill', getColor(
linearMap(data.get(valueDim, idx) as number, valueExtent, [0, 1], true)
......
......@@ -110,7 +110,8 @@ class EffectSymbol extends Group {
// TODO Configurable effectCfg.period
ripplePath.animate('', true)
.when(effectCfg.period, {
scale: [effectCfg.rippleScale / 2, effectCfg.rippleScale / 2]
scaleX: effectCfg.rippleScale / 2,
scaleY: effectCfg.rippleScale / 2
})
.delay(delay)
.start();
......@@ -184,11 +185,15 @@ class EffectSymbol extends Group {
ripplePath.setStyle('fill', color);
});
const symbolOffset = itemModel.getShallow('symbolOffset');
let symbolOffset = data.getItemVisual(idx, 'symbolOffset');
if (symbolOffset) {
if (!zrUtil.isArray(symbolOffset)) {
symbolOffset = [symbolOffset, symbolOffset];
}
rippleGroup.x = parsePercent(symbolOffset[0], symbolSize[0]);
rippleGroup.y = parsePercent(symbolOffset[1], symbolSize[1]);
rippleGroup.y = parsePercent(zrUtil.retrieve2(symbolOffset[1], symbolOffset[0]) || 0, symbolSize[1]);
}
const symbolRotate = data.getItemVisual(idx, 'symbolRotate');
rippleGroup.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
......@@ -247,4 +252,4 @@ class EffectSymbol extends Group {
}
zrUtil.inherits(EffectSymbol, Group);
export default EffectSymbol;
\ No newline at end of file
export default EffectSymbol;
......@@ -17,14 +17,14 @@
* under the License.
*/
import * as zrUtil from 'zrender/src/core/util';
import { isArray, each, retrieve2 } from 'zrender/src/core/util';
import * as vector from 'zrender/src/core/vector';
import * as symbolUtil from '../../util/symbol';
import ECLinePath from './LinePath';
import * as graphic from '../../util/graphic';
import { enableHoverEmphasis, enterEmphasis, leaveEmphasis, SPECIAL_STATES } from '../../util/states';
import {getLabelStatesModels, setLabelStyle} from '../../label/labelStyle';
import {round} from '../../util/number';
import {round, parsePercent} from '../../util/number';
import List from '../../data/List';
import { ZRTextAlign, ZRTextVerticalAlign, LineLabelOption, ColorString } from '../../util/types';
import SeriesModel from '../../model/Series';
......@@ -70,12 +70,27 @@ function createSymbol(name: 'fromSymbol' | 'toSymbol', lineData: LineList, idx:
const symbolSize = lineData.getItemVisual(idx, name + 'Size' as 'fromSymbolSize' | 'toSymbolSize');
const symbolRotate = lineData.getItemVisual(idx, name + 'Rotate' as 'fromSymbolRotate' | 'toSymbolRotate');
const symbolOffset = lineData.getItemVisual(idx, name + 'Offset' as 'fromSymbolOffset' | 'toSymbolOffset') || 0;
const symbolKeepAspect = lineData.getItemVisual(idx,
name + 'KeepAspect' as 'fromSymbolKeepAspect' | 'toSymbolKeepAspect');
const symbolSizeArr = zrUtil.isArray(symbolSize)
const symbolSizeArr = isArray(symbolSize)
? symbolSize : [symbolSize, symbolSize];
const symbolOffsetArr = isArray(symbolOffset)
? symbolOffset : [symbolOffset, symbolOffset];
symbolOffsetArr[0] = parsePercent(symbolOffsetArr[0], symbolSizeArr[0]);
symbolOffsetArr[1] = parsePercent(retrieve2(symbolOffsetArr[1], symbolOffsetArr[0]),symbolSizeArr[1]);
const symbolPath = symbolUtil.createSymbol(
symbolType, -symbolSizeArr[0] / 2, -symbolSizeArr[1] / 2,
symbolSizeArr[0], symbolSizeArr[1]
symbolType,
-symbolSizeArr[0] / 2 + (symbolOffsetArr as number[])[0],
-symbolSizeArr[1] / 2 + (symbolOffsetArr as number[])[1],
symbolSizeArr[0],
symbolSizeArr[1],
null,
symbolKeepAspect
);
(symbolPath as LineECSymbol).__specifiedRotation = symbolRotate == null || isNaN(symbolRotate)
......@@ -142,7 +157,7 @@ class Line extends graphic.Group {
this.add(line);
zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
each(SYMBOL_CATEGORIES, function (symbolCategory) {
const symbol = createSymbol(symbolCategory, lineData, idx);
// symbols must added after line to make sure
// it will be updated after line#update.
......@@ -167,7 +182,7 @@ class Line extends graphic.Group {
setLinePoints(target.shape, linePoints);
graphic.updateProps(line, target, seriesModel, idx);
zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
each(SYMBOL_CATEGORIES, function (symbolCategory) {
const symbolType = (lineData as LineList).getItemVisual(idx, symbolCategory);
const key = makeSymbolTypeKey(symbolCategory);
// Symbol changed
......@@ -220,7 +235,7 @@ class Line extends graphic.Group {
line.ensureState('select').style = selectLineStyle;
// Update symbol
zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
each(SYMBOL_CATEGORIES, function (symbolCategory) {
const symbol = this.childOfName(symbolCategory) as ECSymbol;
if (symbol) {
// Share opacity and color with line.
......@@ -275,7 +290,7 @@ class Line extends graphic.Group {
label.__position = labelNormalModel.get('position') || 'middle';
let distance = labelNormalModel.get('distance');
if (!zrUtil.isArray(distance)) {
if (!isArray(distance)) {
distance = [distance, distance];
}
label.__labelDistance = distance;
......
......@@ -28,7 +28,7 @@ import { ColorString, BlurScope, AnimationOption } from '../../util/types';
import SeriesModel from '../../model/Series';
import { PathProps } from 'zrender/src/graphic/Path';
import { SymbolDrawSeriesScope, SymbolDrawItemModelOption } from './SymbolDraw';
import { extend } from 'zrender/src/core/util';
import { extend, isArray, retrieve2 } from 'zrender/src/core/util';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
import ZRImage from 'zrender/src/graphic/Image';
......@@ -216,8 +216,6 @@ class Symbol extends graphic.Group {
let focus;
let blurScope: BlurScope;
let symbolOffset;
let labelStatesModels;
let hoverScale;
......@@ -230,8 +228,6 @@ class Symbol extends graphic.Group {
focus = seriesScope.focus;
blurScope = seriesScope.blurScope;
symbolOffset = seriesScope.symbolOffset;
labelStatesModels = seriesScope.labelStatesModels;
hoverScale = seriesScope.hoverScale;
......@@ -250,8 +246,6 @@ class Symbol extends graphic.Group {
focus = emphasisModel.get('focus');
blurScope = emphasisModel.get('blurScope');
symbolOffset = itemModel.getShallow('symbolOffset');
labelStatesModels = getLabelStatesModels(itemModel);
hoverScale = emphasisModel.getShallow('scale');
......@@ -259,12 +253,15 @@ class Symbol extends graphic.Group {
}
const symbolRotate = data.getItemVisual(idx, 'symbolRotate');
symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
let symbolOffset = data.getItemVisual(idx, 'symbolOffset') || 0;
if (symbolOffset) {
if (!isArray(symbolOffset)) {
symbolOffset = [symbolOffset, symbolOffset];
}
symbolPath.x = parsePercent(symbolOffset[0], symbolSize[0]);
symbolPath.y = parsePercent(symbolOffset[1], symbolSize[1]);
symbolPath.y = parsePercent(retrieve2(symbolOffset[1], symbolOffset[0]) || 0, symbolSize[1]);
}
cursorStyle && symbolPath.attr('cursor', cursorStyle);
......@@ -398,7 +395,7 @@ class Symbol extends graphic.Group {
static getSymbolSize(data: List, idx: number) {
const symbolSize = data.getItemVisual(idx, 'symbolSize');
return symbolSize instanceof Array
return isArray(symbolSize)
? symbolSize.slice()
: [+symbolSize, +symbolSize];
}
......
......@@ -115,9 +115,6 @@ export interface SymbolDrawSeriesScope {
focus?: DefaultEmphasisFocus
blurScope?: BlurScope
symbolRotate?: ScatterSeriesOption['symbolRotate']
symbolOffset?: (number | string)[]
labelStatesModels: Record<DisplayState, Model<LabelOption>>
itemModel?: Model<SymbolDrawItemModelOption>
......@@ -139,8 +136,6 @@ function makeSeriesScope(data: List): SymbolDrawSeriesScope {
focus: emphasisModel.get('focus'),
blurScope: emphasisModel.get('blurScope'),
symbolRotate: seriesModel.get('symbolRotate'),
symbolOffset: seriesModel.get('symbolOffset'),
hoverScale: emphasisModel.get('scale'),
labelStatesModels: getLabelStatesModels(seriesModel),
......
......@@ -738,7 +738,7 @@ class LineView extends ChartView {
if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
const emphasisLineStyle = polyline.getState('emphasis').style;
emphasisLineStyle.lineWidth = polyline.style.lineWidth + 1;
emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
}
// Needs seriesIndex for focus
......
......@@ -132,30 +132,7 @@ export default function lineAnimationDiff(
rawIndices.push(newData.getRawIndex(newIdx));
break;
case '-':
const oldIdx = diffItem.idx;
const rawIndex = oldData.getRawIndex(oldIdx);
const oldDataDimsForPoint = oldDataNewCoordInfo.dataDimsForPoint;
oldIdx2 = oldIdx * 2;
// Data is replaced. In the case of dynamic data queue
// FIXME FIXME FIXME
if (rawIndex !== oldIdx) {
const newPt = newCoordSys.dataToPoint([
oldData.get(oldDataDimsForPoint[0], oldIdx),
oldData.get(oldDataDimsForPoint[1], oldIdx)
]);
const newStackedOnPt = getStackedOnPoint(oldDataNewCoordInfo, newCoordSys, oldData, oldIdx);
currPoints.push(oldPoints[oldIdx2], oldPoints[oldIdx2 + 1]);
nextPoints.push(newPt[0], newPt[1]);
currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
nextStackedPoints.push(newStackedOnPt[0], newStackedOnPt[1]);
rawIndices.push(rawIndex);
}
else {
pointAdded = false;
}
pointAdded = false;
}
// Original indices
......@@ -205,4 +182,4 @@ export default function lineAnimationDiff(
status: sortedStatus
};
}
\ No newline at end of file
}
......@@ -518,7 +518,7 @@ class CalendarView extends ComponentView {
).time;
const cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
margin = numberUtil.parsePercent(margin, cellSize[orient === 'horizontal' ? 0 : 1]);
margin = numberUtil.parsePercent(margin, Math.min(cellSize[1], cellSize[0]));
if (pos === 'start') {
start = coordSys.getNextNDay(
......
......@@ -60,6 +60,8 @@ export interface MarkLine1DDataItemOption extends MarkLineDataItemOptionBase {
*/
symbol?: string[] | string
symbolSize?: number[] | number
symbolRotate?: number[] | number
symbolOffset: number | string | (number | string)[]
}
// 2D markLine on any direction
......@@ -82,6 +84,8 @@ export interface MarkLineOption extends MarkerOption,
symbol?: string[] | string
symbolSize?: number[] | number
symbolRotate?: number[] | number
symbolOffset?: number | string | (number | string)[]
/**
* Precision used on statistic method
......@@ -112,6 +116,7 @@ class MarkLineModel extends MarkerModel<MarkLineOption> {
symbolSize: [8, 16],
//symbolRotate: 0,
symbolOffset: 0,
precision: 2,
tooltip: {
......@@ -137,4 +142,4 @@ class MarkLineModel extends MarkerModel<MarkLineOption> {
};
}
export default MarkLineModel;
\ No newline at end of file
export default MarkLineModel;
......@@ -35,6 +35,7 @@ import MarkerModel from './MarkerModel';
import {
isArray,
retrieve,
retrieve2,
clone,
extend,
logError,
......@@ -319,12 +320,20 @@ class MarkLineView extends MarkerView {
let symbolType = mlModel.get('symbol');
let symbolSize = mlModel.get('symbolSize');
let symbolRotate = mlModel.get('symbolRotate');
let symbolOffset = mlModel.get('symbolOffset');
if (!isArray(symbolType)) {
symbolType = [symbolType, symbolType];
}
if (!isArray(symbolSize)) {
symbolSize = [symbolSize, symbolSize];
}
if (!isArray(symbolRotate)) {
symbolRotate = [symbolRotate, symbolRotate];
}
if (!isArray(symbolOffset)) {
symbolOffset = [symbolOffset, symbolOffset];
}
// Update visual and layout of from symbol and to symbol
mlData.from.each(function (idx) {
......@@ -349,9 +358,13 @@ class MarkLineView extends MarkerView {
}
lineData.setItemVisual(idx, {
fromSymbolKeepAspect: fromData.getItemVisual(idx, 'symbolKeepAspect'),
fromSymbolOffset: fromData.getItemVisual(idx, 'symbolOffset'),
fromSymbolRotate: fromData.getItemVisual(idx, 'symbolRotate'),
fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize') as number,
fromSymbol: fromData.getItemVisual(idx, 'symbol'),
toSymbolKeepAspect: toData.getItemVisual(idx, 'symbolKeepAspect'),
toSymbolOffset: toData.getItemVisual(idx, 'symbolOffset'),
toSymbolRotate: toData.getItemVisual(idx, 'symbolRotate'),
toSymbolSize: toData.getItemVisual(idx, 'symbolSize') as number,
toSymbol: toData.getItemVisual(idx, 'symbol'),
......@@ -386,9 +399,12 @@ class MarkLineView extends MarkerView {
}
data.setItemVisual(idx, {
symbolRotate: itemModel.get('symbolRotate'),
symbolSize: itemModel.get('symbolSize') || (symbolSize as number[])[isFrom ? 0 : 1],
symbol: itemModel.get('symbol', true) || (symbolType as string[])[isFrom ? 0 : 1],
symbolKeepAspect: itemModel.get('symbolKeepAspect'),
// `0` should be considered as a valid value, so use `retrieve2` instead of `||`
symbolOffset: retrieve2(itemModel.get('symbolOffset'), (symbolOffset as (string | number)[])[isFrom ? 0 : 1]),
symbolRotate: retrieve2(itemModel.get('symbolRotate', true), (symbolRotate as number[])[isFrom ? 0 : 1]),
symbolSize: retrieve2(itemModel.get('symbolSize'), (symbolSize as number[])[isFrom ? 0 : 1]),
symbol: retrieve2(itemModel.get('symbol', true), (symbolType as string[])[isFrom ? 0 : 1]),
style
});
}
......@@ -462,4 +478,4 @@ function createList(coordSys: CoordinateSystem, seriesModel: SeriesModel, mlMode
};
}
export default MarkLineView;
\ No newline at end of file
export default MarkLineView;
/*
* 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 { isArray } from 'zrender/src/core/util';
import { SeriesOption } from '../../util/types';
type MarkerTypes = 'markPoint' | 'markLine' | 'markArea';
type SeriesWithMarkerOption = SeriesOption & Partial<Record<MarkerTypes, unknown>>;
export default function checkMarkerInSeries(
seriesOpts: SeriesOption | SeriesOption[], markerType: MarkerTypes
): boolean {
if (!seriesOpts) {
return false;
}
const seriesOptArr = isArray(seriesOpts) ? seriesOpts : [seriesOpts];
for (let idx = 0; idx < seriesOptArr.length; idx++) {
if (seriesOptArr[idx] && (seriesOptArr[idx] as SeriesWithMarkerOption)[markerType]) {
return true;
}
}
return false;
}
\ No newline at end of file
......@@ -18,6 +18,7 @@
*/
import { EChartsExtensionInstallRegisters } from '../../extension';
import checkMarkerInSeries from './checkMarkerInSeries';
import MarkAreaModel from './MarkAreaModel';
import MarkAreaView from './MarkAreaView';
......@@ -26,7 +27,9 @@ export function install(registers: EChartsExtensionInstallRegisters) {
registers.registerComponentView(MarkAreaView);
registers.registerPreprocessor(function (opt) {
// Make sure markArea component is enabled
opt.markArea = opt.markArea || {};
if (checkMarkerInSeries(opt.series, 'markArea')) {
// Make sure markArea component is enabled
opt.markArea = opt.markArea || {};
}
});
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
* under the License.
*/
import { EChartsExtensionInstallRegisters } from '../../extension';
import checkMarkerInSeries from './checkMarkerInSeries';
import MarkLineModel from './MarkLineModel';
import MarkLineView from './MarkLineView';
......@@ -25,7 +26,9 @@ export function install(registers: EChartsExtensionInstallRegisters) {
registers.registerComponentView(MarkLineView);
registers.registerPreprocessor(function (opt) {
// Make sure markLine component is enabled
opt.markLine = opt.markLine || {};
if (checkMarkerInSeries(opt.series, 'markLine')) {
// Make sure markLine component is enabled
opt.markLine = opt.markLine || {};
}
});
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
* under the License.
*/
import { EChartsExtensionInstallRegisters } from '../../extension';
import checkMarkerInSeries from './checkMarkerInSeries';
import MarkPointModel from './MarkPointModel';
import MarkPointView from './MarkPointView';
......@@ -25,7 +26,9 @@ export function install(registers: EChartsExtensionInstallRegisters) {
registers.registerComponentView(MarkPointView);
registers.registerPreprocessor(function (opt) {
// Make sure markPoint component is enabled
opt.markPoint = opt.markPoint || {};
if (checkMarkerInSeries(opt.series, 'markPoint')) {
// Make sure markPoint component is enabled
opt.markPoint = opt.markPoint || {};
}
});
}
\ No newline at end of file
......@@ -550,15 +550,16 @@ class SliderTimelineView extends TimelineView {
controlSize
);
const rect = [0, -iconSize / 2, iconSize, iconSize];
const opt = {
position: position,
origin: [controlSize / 2, 0],
const btn = makeControlIcon(timelineModel, iconName + 'Icon' as ControlIconName, rect, {
x: position[0],
y: position[1],
originX: controlSize / 2,
originY: 0,
rotation: willRotate ? -rotation : 0,
rectHover: true,
style: itemStyle,
onclick: onclick
};
const btn = makeControlIcon(timelineModel, iconName + 'Icon' as ControlIconName, rect, opt);
});
btn.ensureState('emphasis').style = hoverStyle;
group.add(btn);
enableHoverEmphasis(btn);
......
......@@ -89,7 +89,8 @@ import {
DimensionLoose,
ScaleDataValue,
ZRElementEventName,
ECElementEvent
ECElementEvent,
AnimationOption
} from '../util/types';
import Displayable from 'zrender/src/graphic/Displayable';
import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
......@@ -212,7 +213,15 @@ export interface SetOptionTransitionOptItem {
from?: SetOptionTransitionOptFinder;
to: SetOptionTransitionOptFinder;
dividingMethod: MorphDividingMethod;
}
};
export interface ResizeOpts {
width?: number | 'auto', // Can be 'auto' (the same as null/undefined)
height?: number | 'auto', // Can be 'auto' (the same as null/undefined)
animation?: AnimationOption
silent?: boolean // by default false.
};
interface SetOptionTransitionOptFinder extends modelUtil.ModelFinderObject {
dimension: DimensionLoose;
}
......@@ -1131,11 +1140,7 @@ class ECharts extends Eventful<ECEventDefinition> {
/**
* Resize the chart
*/
resize(opts?: {
width?: number | 'auto', // Can be 'auto' (the same as null/undefined)
height?: number | 'auto', // Can be 'auto' (the same as null/undefined)
silent?: boolean // by default false.
}): void {
resize(opts?: ResizeOpts): void {
if (__DEV__) {
assert(!this[IN_MAIN_PROCESS_KEY], '`resize` should not be called during main process.');
}
......@@ -1164,10 +1169,10 @@ class ECharts extends Eventful<ECEventDefinition> {
optionChanged && prepare(this);
updateMethods.update.call(this, {
type: 'resize',
animation: {
animation: zrUtil.extend({
// Disable animation
duration: 0
}
}, opts && opts.animation)
});
this[IN_MAIN_PROCESS_KEY] = false;
......@@ -1531,12 +1536,12 @@ class ECharts extends Eventful<ECEventDefinition> {
updateMethods = {
prepareAndUpdate: function (this: ECharts, payload: Payload): void {
prepareAndUpdate(this: ECharts, payload: Payload): void {
prepare(this);
updateMethods.update.call(this, payload);
},
update: function (this: ECharts, payload: Payload): void {
update(this: ECharts, payload: Payload): void {
// console.profile && console.profile('update');
const ecModel = this._model;
......@@ -1608,7 +1613,7 @@ class ECharts extends Eventful<ECEventDefinition> {
// console.profile && console.profileEnd('update');
},
updateTransform: function (this: ECharts, payload: Payload): void {
updateTransform(this: ECharts, payload: Payload): void {
const ecModel = this._model;
const api = this._api;
......@@ -1665,7 +1670,7 @@ class ECharts extends Eventful<ECEventDefinition> {
performPostUpdateFuncs(ecModel, this._api);
},
updateView: function (this: ECharts, payload: Payload): void {
updateView(this: ECharts, payload: Payload): void {
const ecModel = this._model;
// update before setOption
......@@ -1687,7 +1692,7 @@ class ECharts extends Eventful<ECEventDefinition> {
performPostUpdateFuncs(ecModel, this._api);
},
updateVisual: function (this: ECharts, payload: Payload): void {
updateVisual(this: ECharts, payload: Payload): void {
// updateMethods.update.call(this, payload);
const ecModel = this._model;
......@@ -1728,7 +1733,7 @@ class ECharts extends Eventful<ECEventDefinition> {
performPostUpdateFuncs(ecModel, this._api);
},
updateLayout: function (this: ECharts, payload: Payload): void {
updateLayout(this: ECharts, payload: Payload): void {
updateMethods.update.call(this, payload);
}
};
......
......@@ -135,6 +135,7 @@ export interface DefaultDataVisual {
symbolSize?: number | number[]
symbolRotate?: number
symbolKeepAspect?: boolean
symbolOffset?: string | number | (string | number)[]
liftZ?: number
// For legend.
......
......@@ -38,4 +38,4 @@ export default {
// @ts-ignore
return init.apply(null, arguments);
}
}
\ No newline at end of file
};
\ No newline at end of file
......@@ -61,6 +61,7 @@ import Scheduler from '../core/Scheduler';
import { concatInternalOptions } from './internalComponentCreator';
import { LocaleOption } from '../core/locale';
import {PaletteMixin} from './mixin/palette';
import { error } from '../util/log';
export interface GlobalModelSetOptionOpts {
replaceMerge: ComponentMainType | ComponentMainType[];
......@@ -79,6 +80,63 @@ let initBase: (ecModel: GlobalModel, baseOption: ECUnitOption) => void;
const OPTION_INNER_KEY = '\0_ec_inner';
const OPTION_INNER_VALUE = 1;
const BUITIN_COMPONENTS_MAP = {
grid: 'GridComponent',
polar: 'PolarComponent',
geo: 'GeoComponent',
singleAxis: 'SingleAxisComponent',
parallel: 'ParallelComponent',
calendar: 'CalendarComponent',
graphic: 'GraphicComponent',
toolbox: 'ToolboxComponent',
tooltip: 'TooltipComponent',
axisPointer: 'AxisPointerComponent',
brush: 'BrushComponent',
title: 'TitleComponent',
timeline: 'TimelineComponent',
markPoint: 'MarkPointComponent',
markLine: 'MarkLineComponent',
markArea: 'MarkAreaComponent',
legend: 'LegendComponent',
dataZoom: 'DataZoomComponent',
visualMap: 'VisualMapComponent',
// aria: 'AriaComponent',
// dataset: 'DatasetComponent',
// Dependencies
xAxis: 'GridComponent',
yAxis: 'GridComponent',
angleAxis: 'PolarComponent',
radiusAxis: 'PolarComponent'
} as const;
const BUILTIN_CHARTS_MAP = {
line: 'LineChart',
bar: 'BarChart',
pie: 'PieChart',
scatter: 'ScatterChart',
radar: 'RadarChart',
map: 'MapChart',
tree: 'TreeChart',
treemap: 'TreemapChart',
graph: 'GraphChart',
gauge: 'GaugeChart',
funnel: 'FunnelChart',
parallel: 'ParallelChart',
sankey: 'SankeyChart',
boxplot: 'BoxplotChart',
candlestick: 'CandlestickChart',
effectScatter: 'EffectScatterChart',
lines: 'LinesChart',
heatmap: 'HeatmapChart',
pictorialBar: 'PictorialBarChart',
themeRiver: 'ThemeRiverChart',
sunburst: 'SunburstChart',
custom: 'CustomChart'
} as const;
const componetsMissingLogPrinted: Record<string, boolean> = {};
class GlobalModel extends Model<ECUnitOption> {
// @readonly
option: ECUnitOption;
......@@ -250,6 +308,16 @@ class GlobalModel extends Model<ECUnitOption> {
}
if (!ComponentModel.hasClass(mainType)) {
if (__DEV__) {
const componentImportName = BUITIN_COMPONENTS_MAP[mainType as keyof typeof BUITIN_COMPONENTS_MAP];
if (componentImportName && !componetsMissingLogPrinted[componentImportName]) {
error(`Component ${mainType} is used but not imported.
import { ${componentImportName} } from 'echarts/components';
echarts.use([${componentImportName}]);`);
componetsMissingLogPrinted[componentImportName] = true;
}
}
// globalSettingTask.dirty();
option[mainType] = option[mainType] == null
? clone(componentOption)
......@@ -328,10 +396,31 @@ class GlobalModel extends Model<ECUnitOption> {
// or it has been removed in previous `replaceMerge` and left a "hole" in this component index.
}
else {
const isSeriesType = mainType === 'series';
const ComponentModelClass = (ComponentModel as ComponentModelConstructor).getClass(
mainType, resultItem.keyInfo.subType, true
mainType, resultItem.keyInfo.subType,
!isSeriesType // Give a more detailed warn later if series don't exists
);
if (!ComponentModelClass) {
if (__DEV__) {
const subType = resultItem.keyInfo.subType;
const seriesImportName = BUILTIN_CHARTS_MAP[subType as keyof typeof BUILTIN_CHARTS_MAP];
if (!componetsMissingLogPrinted[subType]) {
componetsMissingLogPrinted[subType] = true;
if (seriesImportName) {
error(`Series ${subType} is used but not imported.
import { ${seriesImportName} } from 'echarts/charts';
echarts.use([${seriesImportName}]);`);
}
else {
error(`Unkown series ${subType}`);
}
}
}
return;
}
if (componentModel && componentModel.constructor === ComponentModelClass) {
componentModel.name = resultItem.keyInfo.name;
// componentModel.settingTask && componentModel.settingTask.dirty();
......
......@@ -292,7 +292,7 @@ export function enableClassManagement(
throw new Error(
!subType
? mainType + '.' + 'type should be specified.'
: 'Component ' + mainType + '.' + (subType || '') + ' not exists. Load it first.'
: 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.'
);
}
......
......@@ -102,7 +102,7 @@ type DepGraph = {[cmptMainType: string]: DepGraphItem};
* Topological travel on Activity Network (Activity On Vertices).
* Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
* If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
* If there is circle dependencey, Error will be thrown.
* If there is circular dependencey, Error will be thrown.
*/
export function enableTopologicalTravel<T>(
entity: TopologicalTravelable<T>,
......@@ -152,7 +152,7 @@ export function enableTopologicalTravel<T>(
zrUtil.each(targetNameSet, function () {
let errMsg = '';
if (__DEV__) {
errMsg = makePrintable('Circle dependency may exists: ', targetNameSet, targetNameList, fullNameList);
errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList);
}
throw new Error(errMsg);
});
......
......@@ -922,7 +922,7 @@ export interface RoamOptionMixin {
export type SymbolSizeCallback<T> = (rawValue: any, params: T) => number | number[];
export type SymbolCallback<T> = (rawValue: any, params: T) => string;
export type SymbolRotateCallback<T> = (rawValue: any, params: T) => number;
// export type SymbolOffsetCallback<T> = (rawValue: any, params: T) => (string | number)[];
export type SymbolOffsetCallback<T> = (rawValue: any, params: T) => (string | number)[];
/**
* Mixin of option set to control the element symbol.
* Include type of symbol, and size of symbol.
......@@ -941,7 +941,7 @@ export interface SymbolOptionMixin<T = unknown> {
symbolKeepAspect?: boolean
symbolOffset?: (string | number)[]
symbolOffset?: (string | number)[] | (unknown extends T ? never : SymbolOffsetCallback<T>)
}
/**
......
......@@ -22,9 +22,13 @@ import { DefaultDataVisual } from '../data/List';
export interface LineDataVisual extends DefaultDataVisual {
fromSymbol: string
toSymbol: string
fromSymbolSize: number
toSymbolSize: number
fromSymbolSize: number | number[]
toSymbolSize: number | number[]
fromSymbolRotate: number
toSymbolRotate: number
fromSymbolOffset: string | number | (string | number)[]
toSymbolOffset: string | number | (string | number)[]
fromSymbolKeepAspect: boolean
toSymbolKeepAspect: boolean
}
......@@ -25,7 +25,8 @@ import {
SymbolSizeCallback,
SymbolCallback,
CallbackDataParams,
SymbolRotateCallback
SymbolRotateCallback,
SymbolOffsetCallback
} from '../util/types';
import List from '../data/List';
import SeriesModel from '../model/Series';
......@@ -57,14 +58,20 @@ const seriesSymbolTask: StageHandler = {
const symbolSize = seriesModel.get('symbolSize');
const keepAspect = seriesModel.get('symbolKeepAspect');
const symbolRotate = seriesModel.get('symbolRotate');
const symbolOffset = seriesModel.get('symbolOffset');
const hasSymbolTypeCallback = isFunction(symbolType);
const hasSymbolSizeCallback = isFunction(symbolSize);
const hasSymbolRotateCallback = isFunction(symbolRotate);
const hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback || hasSymbolRotateCallback;
const hasSymbolOffsetCallback = isFunction(symbolOffset);
const hasCallback = hasSymbolTypeCallback
|| hasSymbolSizeCallback
|| hasSymbolRotateCallback
|| hasSymbolOffsetCallback;
const seriesSymbol = (!hasSymbolTypeCallback && symbolType) ? symbolType : seriesModel.defaultSymbol;
const seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null;
const seriesSymbolRotate = !hasSymbolRotateCallback ? symbolRotate : null;
const seriesSymbolOffset = !hasSymbolOffsetCallback ? symbolOffset : null;
data.setVisual({
legendSymbol: seriesModel.legendSymbol || seriesSymbol as string,
......@@ -75,7 +82,8 @@ const seriesSymbolTask: StageHandler = {
symbol: seriesSymbol as string,
symbolSize: seriesSymbolSize as number | number[],
symbolKeepAspect: keepAspect,
symbolRotate: seriesSymbolRotate as number
symbolRotate: seriesSymbolRotate as number,
symbolOffset: seriesSymbolOffset as (string | number)[]
});
// Only visible series has each data be visual encoded
......@@ -95,6 +103,9 @@ const seriesSymbolTask: StageHandler = {
hasSymbolRotateCallback && data.setItemVisual(
idx, 'symbolRotate', (symbolRotate as SymbolRotateCallback<CallbackDataParams>)(rawValue, params)
);
hasSymbolOffsetCallback && data.setItemVisual(
idx, 'symbolOffset', (symbolOffset as SymbolOffsetCallback<CallbackDataParams>)(rawValue, params)
);
}
return { dataEach: hasCallback ? dataEach : null };
......@@ -127,6 +138,7 @@ const dataSymbolTask: StageHandler = {
const itemSymbolType = itemModel.getShallow('symbol', true);
const itemSymbolSize = itemModel.getShallow('symbolSize', true);
const itemSymbolRotate = itemModel.getShallow('symbolRotate', true);
const itemSymbolOffset = itemModel.getShallow('symbolOffset', true);
const itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true);
// If has item symbol
......@@ -140,6 +152,9 @@ const dataSymbolTask: StageHandler = {
if (itemSymbolRotate != null) {
data.setItemVisual(idx, 'symbolRotate', itemSymbolRotate);
}
if (itemSymbolOffset != null) {
data.setItemVisual(idx, 'symbolOffset', itemSymbolOffset);
}
if (itemSymbolKeepAspect != null) {
data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
}
......@@ -149,4 +164,4 @@ const dataSymbolTask: StageHandler = {
}
};
export {seriesSymbolTask, dataSymbolTask};
\ No newline at end of file
export {seriesSymbolTask, dataSymbolTask};
......@@ -45,6 +45,8 @@ under the License.
<div id="main5"></div>
<div id="main6"></div>
<div id="main7"></div>
<div id="main8"></div>
<div id="main9"></div>
......@@ -547,6 +549,86 @@ under the License.
date = null;
}, 1000);
var option8 = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
toolbox: {
feature: {
restore: {},
saveAsImage: {}
}
},
series: [
{
name: '业务指标',
type: 'gauge',
anchor: {
show: true,
icon: "image://https://www.apache.org/img/support-apache.jpg",
size: 50,
showAbove: true
},
pointer: {
icon: "image://https://www.apache.org/img/support-apache.jpg",
length: "70%"
},
detail: {formatter: '{value}%'},
data: [{value: 58.46, name: '完成率'}]
}
]
};
var chart8 = testHelper.create(echarts, 'main8', {
title: [
'pointer.icon: "image://url"',
'anchor.icon: "image://url"'
],
option: option8
// height: 1200,
// buttons: [{text: 'btn-txt', onclick: function () {}}],
// recordCanvas: true,
});
var option9 = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
toolbox: {
feature: {
restore: {},
saveAsImage: {}
}
},
series: [
{
name: '业务指标',
type: 'gauge',
pointer: {
icon: 'emptyCircle',
itemStyle: {
borderWidth: 10,
borderColor: '#f00'
},
},
anchor: {
// show: true
},
detail: {formatter: '{value}%'},
data: [{value: 58.46, name: '完成率'}]
}
]
};
var chart9 = testHelper.create(echarts, 'main9', {
title: [
'pointer.icon: emptyCircle',
'anchor.show: false'
],
option: option9
});
});
</script>
......
此差异已折叠。
......@@ -117,6 +117,7 @@ under the License.
markLine: {
silent: true,
// symbol: 'triangle',
symbolRotate: [20, 45],
data: [
[
{name: 'rotation not specified', coord: ['2014-06-20', 300], symbol: 'arrow'},
......@@ -156,10 +157,13 @@ under the License.
[{
symbol: 'rect',
x: '90%',
yAxis: 'average'
yAxis: 'average',
symbolRotate: 0,
symbolOffset: [50, 0]
}, {
symbol: 'triangle',
symbolRotate: 180,
symbolRotate: 130,
// symbolOffset: [-50, 0],
label: {
position: 'start',
formatter: 'Average',
......
<!--
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.
-->
<html>
<head>
<meta charset="utf-8">
<script src="lib/esl.js"></script>
<script src="lib/config.js"></script>
<script src="lib/testHelper.js"></script>
<link rel="stylesheet" href="lib/reset.css">
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<style>
body {
position: absolute;
left: 0;
top: 0;
}
</style>
<div id="main0"></div>
<script>
require([
'echarts'
// 'echarts/chart/pie',
// 'echarts/component/title',
// 'echarts/component/legend',
// 'echarts/component/tooltip'
], function (echarts) {
require([
'echarts'
], function (echarts) {
const option = {
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
left: 'left',
data: ['直接访问','邮件营销','联盟广告','视频广告(value is null)','搜索引擎']
},
series : [
{
name: '访问来源',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
selectedMode: 'single',
data:[
{value:335, name:'直接访问'},
{value:310, name:'邮件营销'},
{value:234, name:'联盟广告'},
{value:null, name:'视频广告(value is null)'},
{value:1548, name:'搜索引擎'}
]
}
]
};
var myChart = testHelper.create(echarts, 'main0', {
width: 600,
height: 400,
title: [
'Resize animation should be configured properly'
],
option: option,
buttons: [{
text: 'Resize without animation by default',
onClick: () => {
myChart.resize({
width: 400,
height: 266
})
}
}, {
text: 'Resize with animaiton',
onClick: () => {
myChart.resize({
width: 300,
height: 200,
animation: {
// Use a long duration so it can be recorded
duration: 2000,
easing: 'cubicInOut'
}
})
}
}]
});
});
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -102,6 +102,7 @@
"line-boldWhenHover": 1,
"line-crash": 1,
"line-endLabel": 1,
"line-extraneous": 2,
"map": 3,
"map-contour": 2,
"map-default": 1,
......@@ -130,6 +131,7 @@
"radar2": 1,
"radar3": 1,
"radar4": 1,
"resize-animation": 1,
"sankey-depth": 1,
"sankey-jump": 1,
"sankey-level": 1,
......
[{"name":"Action 1","ops":[{"type":"mousedown","time":596,"x":28,"y":93},{"type":"mouseup","time":698,"x":28,"y":93},{"time":699,"delay":2000,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1568042380534},{"name":"Action 2","ops":[{"type":"mousedown","time":736,"x":218,"y":184},{"type":"mouseup","time":827,"x":218,"y":184},{"time":828,"delay":400,"type":"screenshot-auto"}],"scrollY":416,"scrollX":0,"timestamp":1617082817083}]
\ No newline at end of file
[{"name":"Action 1","ops":[{"type":"mousemove","time":294,"x":206,"y":78},{"type":"mousedown","time":382,"x":206,"y":78},{"type":"mouseup","time":481,"x":206,"y":78},{"time":482,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":910,"x":207,"y":78},{"type":"mousemove","time":1111,"x":248,"y":78},{"type":"mousedown","time":1201,"x":248,"y":78},{"type":"mouseup","time":1305,"x":248,"y":78},{"time":1306,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":1320,"x":248,"y":78}],"scrollY":0,"scrollX":0,"timestamp":1617085338625}]
\ No newline at end of file
......@@ -34,6 +34,7 @@ under the License.
</head>
<body>
<div id="main0"></div>
<div id="main1"></div>
<script>
require([
......@@ -94,12 +95,55 @@ under the License.
}]
};
var series = {
name: 'Original',
type: 'scatter',
symbol: 'circle',
data: (function() {
function random(max) {
return +(Math.random() * max).toFixed(3);
}
var seriesData = [];
for (var i = 0; i < 20; i++) {
seriesData.push([random(10), random(10), random(20)]);
}
return seriesData;
})()
};
var option2 = {
legend: {},
xAxis: {},
yAxis: {},
tooltip: {
formatter: function(params) {
return params.marker + params.seriesName
+ (params.seriesName === 'Offset' ? '<br/>offset: ' + params.value[2] : '');
}
},
series: [
series,
Object.assign({}, series, {
name: 'Offset',
symbol: 'circle',
// symbolOffset: 20,
symbolOffset: function(data) {
return data[2]
}
})
]
};
var chart = testHelper.create(echarts, 'main0', {
title: 'Rotates the symbol as we need',
option: option
});
var chart2 = testHelper.create(echarts, 'main1', {
title: 'Symbol should have various offset',
option: option2
});
});
</script>
</body>
</html>
\ No newline at end of file
</html>
......@@ -18,7 +18,9 @@
* under the License.
*/
import { isValueFinite } from './utHelper';
function isValueFinite(val: unknown): boolean {
return val != null && val !== '' && isFinite(val as number);
}
// Setup expectes
......
......@@ -46,6 +46,16 @@ export function createChart(params?: {
'bottom:0',
'right:0'
].join(';');
Object.defineProperty(el, 'clientWidth', {
get() {
return params.width || 500;
}
});
Object.defineProperty(el, 'clientHeight', {
get() {
return params.height || 400;
}
});
const chart = init(el, params.theme, params.opts);
return chart;
};
......@@ -80,10 +90,6 @@ 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
......
export {};
declare global {
namespace jest {
interface Matchers<R> {
toBeFinite(): R
// Greater than or equal
toBeGeaterThanOrEqualTo(bound: number): R
// Greater than
toBeGreaterThan(bound: number): R
toBeEmptyArray(): R
}
}
}
\ No newline at end of file
......@@ -21,10 +21,10 @@ import { createChart, getGraphicElements, getECModel } from '../../../core/utHel
// import { imageURI } from './setOptionImageURI';
import { EChartsType } from '../../../../../src/echarts';
import Element from 'zrender/src/Element';
import { EChartsFullOption } from '../../../../../src/option';
import { EChartsOption } from '../../../../../src/export/option';
import {
GraphicComponentOption, GraphicComponentImageOption
} from '../../../../../src/component/graphic';
} from '../../../../../src/component/graphic/install';
import Group from 'zrender/src/graphic/Group';
import { Dictionary } from 'zrender/src/core/types';
......@@ -1049,7 +1049,7 @@ describe('graphic_setOption', function () {
describe('boundingAndRotation', function () {
function getOption(): EChartsFullOption {
function getOption(): EChartsOption {
return {
legend: {
data: ['高度(km)与气温(°C)变化关系']
......
......@@ -20,7 +20,7 @@
import { createChart, getECModel } from '../../../core/utHelper';
import { EChartsType } from '../../../../../src/echarts';
import { EChartsFullOption } from '../../../../../src/option';
import { EChartsOption } from '../../../../../src/export/option';
import { ContinousVisualMapOption } from '../../../../../src/component/visualMap/ContinuousModel';
import { PiecewiseVisualMapOption } from '../../../../../src/component/visualMap/PiecewiseModel';
import VisualMapModel from '../../../../../src/component/visualMap/VisualMapModel';
......@@ -94,15 +94,15 @@ describe('vsiaulMap_setOption', function () {
visualMap: {}
});
expectTheSame(chart.getOption());
expectTheSame(chart.getOption() as EChartsOption);
chart.setOption({
series: [{data: [[44, 55]]}] // visualMap depends series
});
expectTheSame(chart.getOption());
expectTheSame(chart.getOption() as EChartsOption);
function expectTheSame(option: EChartsFullOption) {
function expectTheSame(option: EChartsOption) {
const visualMapOptionGotten = option.visualMap as (ContinousVisualMapOption | PiecewiseVisualMapOption)[];
expect(visualMapOptionGotten.length).toEqual(1);
expect(visualMapOptionGotten[0].inRange.color).toEqual(['red', 'blue', 'yellow']);
......
......@@ -19,7 +19,7 @@
import { EChartsType } from '../../../../src/echarts';
import { createChart, removeChart, getECModel } from '../../core/utHelper';
import { EChartsFullOption } from '../../../../src/option';
import { EChartsOption } from '../../../../src/export/option';
import { retrieveRawValue } from '../../../../src/data/helper/dataProvider';
......@@ -59,7 +59,7 @@ describe('dataTransform', function () {
}
it('forbid_seriesLayoutBy_row', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
dataset: [{
source: makeDatasetSourceDetection(),
// This config should cause error thrown.
......@@ -78,7 +78,7 @@ describe('dataTransform', function () {
});
it('seriesLayoutBy_changed_no_transform', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
dataset: {
source: makeDatasetSourceDetection()
},
......@@ -104,7 +104,7 @@ describe('dataTransform', function () {
]
}].forEach((dataset1, itIdx) => {
it(`seriesLayoutBy_changed_transform_detection_${itIdx}`, function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
dataset: [{
source: makeDatasetSourceDetection()
}, dataset1],
......@@ -136,7 +136,7 @@ describe('dataTransform', function () {
}].forEach((dataset1, itIdx) => {
it(`seriesLayoutBy_changed_transform_non_detection_${itIdx}`, function () {
const sourceWrap = makeDatasetSourceNonDetectionByRow();
const option: EChartsFullOption = {
const option: EChartsOption = {
dataset: [{
dimensions: sourceWrap.dimensions,
source: sourceWrap.source
......@@ -163,7 +163,7 @@ describe('dataTransform', function () {
]
}].forEach((dataset1, itIdx) => {
it(`inherit_detected_dimensions_${itIdx}`, function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
dataset: [{
source: makeDatasetSourceDetection()
}, dataset1],
......
/*
* 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
......@@ -24,7 +24,7 @@ import { ComponentMainType, ParsedValue } from '../../../../src/util/types';
import SeriesModel from '../../../../src/model/Series';
import ComponentModel from '../../../../src/model/Component';
import ChartView from '../../../../src/view/Chart';
import { EChartsFullOption } from '../../../../src/option';
import { EChartsOption } from '../../../../src/export/option';
type OriginModelView = {
model: SeriesModel;
......@@ -119,7 +119,7 @@ describe('modelAndOptionMapping', function () {
describe('idNoNameNo', function () {
it('sameTypeNotMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -239,7 +239,7 @@ describe('modelAndOptionMapping', function () {
describe('idSpecified', function () {
it('sameTypeNotMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -270,7 +270,7 @@ describe('modelAndOptionMapping', function () {
});
it('sameTypeMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -293,7 +293,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeNotMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -307,7 +307,7 @@ describe('modelAndOptionMapping', function () {
chart.setOption(option);
const origins = saveOrigins(chart);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -328,7 +328,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeMergeFull', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -342,7 +342,7 @@ describe('modelAndOptionMapping', function () {
chart.setOption(option);
const origins = saveOrigins(chart);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'line', data: [11]},
{type: 'bar', data: [22], id: 20, name: 'a'},
......@@ -362,7 +362,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeMergePartial1', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -376,7 +376,7 @@ describe('modelAndOptionMapping', function () {
chart.setOption(option);
const origins = saveOrigins(chart);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], id: 40},
{type: 'line', data: [333]},
......@@ -399,7 +399,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeMergePartial2', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -409,7 +409,7 @@ describe('modelAndOptionMapping', function () {
};
chart.setOption(option);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], id: 40},
{type: 'line', data: [333]},
......@@ -429,7 +429,7 @@ describe('modelAndOptionMapping', function () {
it('mergePartialDoNotMapToOtherId', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -439,7 +439,7 @@ describe('modelAndOptionMapping', function () {
};
chart.setOption(option);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], id: 40}
]
......@@ -455,7 +455,7 @@ describe('modelAndOptionMapping', function () {
it('idDuplicate', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -524,7 +524,7 @@ describe('modelAndOptionMapping', function () {
describe('noIdButNameExists', function () {
it('sameTypeNotMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -558,7 +558,7 @@ describe('modelAndOptionMapping', function () {
});
it('sameTypeMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -581,7 +581,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeNotMerge', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -595,7 +595,7 @@ describe('modelAndOptionMapping', function () {
chart.setOption(option);
const origins = saveOrigins(chart);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -616,7 +616,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeMergePartialOneMapTwo', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -630,7 +630,7 @@ describe('modelAndOptionMapping', function () {
chart.setOption(option);
const origins = saveOrigins(chart);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], id: 40},
{type: 'line', data: [333]},
......@@ -654,7 +654,7 @@ describe('modelAndOptionMapping', function () {
});
it('differentTypeMergePartialTwoMapOne', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -664,7 +664,7 @@ describe('modelAndOptionMapping', function () {
};
chart.setOption(option);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], name: 'a'},
{type: 'line', data: [333]},
......@@ -684,7 +684,7 @@ describe('modelAndOptionMapping', function () {
it('mergePartialCanMapToOtherName', function () {
// Consider case: axis.name = 'some label', which can be overwritten.
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
series: [
......@@ -694,7 +694,7 @@ describe('modelAndOptionMapping', function () {
};
chart.setOption(option);
const option2: EChartsFullOption = {
const option2: EChartsOption = {
series: [
{type: 'bar', data: [444], name: 40},
{type: 'bar', data: [999], name: 40},
......@@ -720,7 +720,7 @@ describe('modelAndOptionMapping', function () {
describe('ohters', function () {
it('aBugCase', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
series: [
{
type: 'pie',
......@@ -790,7 +790,7 @@ describe('modelAndOptionMapping', function () {
});
it('color', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
backgroundColor: 'rgba(1,1,1,1)',
xAxis: {data: ['a']},
yAxis: {},
......@@ -812,7 +812,7 @@ describe('modelAndOptionMapping', function () {
});
it('innerId', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: {data: ['a']},
yAxis: {},
toolbox: {
......
/*
* 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;
function extendModel(type: string, dependencies?: string[]) {
class SubModel extends ComponentModel {
static type: string = type;
type: string = type;
static dependencies = dependencies || [];
};
ComponentModel.registerClass(SubModel);
return SubModel;
}
describe('componentDependency', 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[]];
it('topologicalTravel_base', function () {
const [m1, a1, a2] = makeTypes(3);
extendModel(m1, [a1, a2]);
extendModel(a1);
extendModel(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);
extendModel(m1, [a1, a2]);
extendModel(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);
extendModel(m1, [a1, a2]);
extendModel(a1);
extendModel(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);
extendModel(a2);
extendModel(a1);
extendModel(m1, [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);
extendModel(a1, []);
extendModel(a2, [a1]);
extendModel(a3, [a1]);
extendModel(m1, [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);
extendModel(m1, [a1, a2]);
extendModel(m2, [m1, a2]);
extendModel(a1, [m2, a2, a3]);
extendModel(a2);
extendModel(a3);
const allList = componentModelConstructor.getAllClassMainTypes();
expect(function () {
componentModelConstructor.topologicalTravel(
[m1, m2, a1],
allList,
() => {}
);
}).toThrowError(/Circular/);
});
it('topologicalTravel_multipleEchartsInstance', function () {
const [m1, m2, a1, a2] = makeTypes(4);
extendModel(m1, [a1, a2]);
extendModel(a1);
extendModel(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 = [];
extendModel(m2, [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);
extendModel(m1, [a1, a2]);
extendModel(a2, [a3]);
extendModel(a3);
extendModel(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);
extendModel(m1, [a1, a2]);
extendModel(a1 + '.aaa', [a2]);
extendModel(a1 + '.bbb', [a3, a4]);
extendModel(a2);
extendModel(a3);
extendModel(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
import { init, use, EChartsType } from '../../../../src/export/core';
import {
PieChart
} from '../../../../src/export/charts';
import {
TitleComponent
} from '../../../../src/export/components';
import {
CanvasRenderer
} from '../../../../src/export/renderers';
use([PieChart, TitleComponent, CanvasRenderer]);
import { EChartsOption } from '../../../../src/export/option';
function createChart(): EChartsType {
const el = document.createElement('div');
Object.defineProperty(el, 'clientWidth', {
get() {
return 500;
}
});
Object.defineProperty(el, 'clientHeight', {
get() {
return 400;
}
});
const chart = init(el);
return chart;
};
function makeComponentError(componentName: string, componentImportName: string) {
return `[ECharts] Component ${componentName} is used but not imported.
import { ${componentImportName} } from 'echarts/components';
echarts.use([${componentImportName}]);`;
}
function makeSerieError(seriesName: string, seriesImportName: string) {
return `[ECharts] Series ${seriesName} is used but not imported.
import { ${seriesImportName} } from 'echarts/charts';
echarts.use([${seriesImportName}]);`;
}
describe('model_componentMissing', function () {
it('Should report grid component missing error', function () {
const chart = createChart();
const oldConsoleErr = console.error;
console.error = jest.fn();
chart.setOption<EChartsOption>({
xAxis: {},
yAxis: {},
series: []
});
expect(console.error).toHaveBeenCalledWith(
makeComponentError('xAxis', 'GridComponent')
);
console.error = oldConsoleErr;
});
it('Should report dataZoom component missing error', function () {
const chart = createChart();
const oldConsoleErr = console.error;
console.error = jest.fn();
chart.setOption<EChartsOption>({
dataZoom: {}
});
expect(console.error).toHaveBeenCalledWith(
makeComponentError('dataZoom', 'DataZoomComponent')
);
console.error = oldConsoleErr;
});
it('Should not report title component missing error', function () {
const chart = createChart();
const oldConsoleErr = console.error;
console.error = jest.fn();
chart.setOption<EChartsOption>({
title: {},
series: []
});
expect(console.error).not.toBeCalled();
console.error = oldConsoleErr;
});
it('Should report funnel series missing error', function () {
const chart = createChart();
const oldConsoleErr = console.error;
console.error = jest.fn();
chart.setOption<EChartsOption>({
series: [{
type: 'funnel'
}]
});
expect(console.error).toHaveBeenCalledWith(
makeSerieError('funnel', 'FunnelChart')
);
console.error = oldConsoleErr;
});
it('Should not report pie series missing error', function () {
const chart = createChart();
const oldConsoleErr = console.error;
console.error = jest.fn();
chart.setOption<EChartsOption>({
series: [{
type: 'pie'
}]
});
expect(console.error).not.toBeCalled();
console.error = oldConsoleErr;
});
});
\ No newline at end of file
......@@ -24,7 +24,7 @@ import { ParsedValue } from '../../../../src/util/types';
import { LegendOption } from '../../../../src/component/legend/LegendModel';
import TimelineModel from '../../../../src/component/timeline/TimelineModel';
import { createChart, getECModel } from '../../core/utHelper';
import { EChartsFullOption } from '../../../../src/option';
import { EChartsOption } from '../../../../src/export/option';
describe('timelineMediaOptions', function () {
......@@ -36,7 +36,7 @@ describe('timelineMediaOptions', function () {
return getECModel(chart).getComponent('series', seriesIndex) as SeriesModel;
}
function getLegendOption(chart: EChartsType): LegendOption {
return getECModel(chart).getComponent('legend', 0).option;
return getECModel(chart).getComponent('legend', 0).option as LegendOption;
}
function getTimelineComponent(chart: EChartsType): TimelineModel {
return getECModel(chart).getComponent('timeline', 0) as TimelineModel;
......@@ -60,7 +60,7 @@ describe('timelineMediaOptions', function () {
describe('parse_timeline_media_option', function () {
it('parse_media_has_baseOption_has_default', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
baseOption: {
xAxis: { data: ['a'] },
yAxis: {},
......@@ -88,7 +88,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_media_no_baseOption_has_default', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: { data: ['a'] },
yAxis: {},
legend: { left: 10 },
......@@ -112,7 +112,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_media_no_baseOption_no_default', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
xAxis: { data: ['a'] },
yAxis: {},
legend: { left: 10 },
......@@ -132,7 +132,7 @@ describe('timelineMediaOptions', function () {
});
it('parse_timeline_media_has_baseOption', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
baseOption: {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
......@@ -166,13 +166,13 @@ describe('timelineMediaOptions', function () {
expect(getData0(chart, 0)).toEqual(88);
expect(getLegendOption(chart).left).toEqual(50);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
expect(getLegendOption(chart).left).toEqual(50);
});
it('parse_timeline_media_no_baseOption', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
yAxis: {},
......@@ -202,13 +202,13 @@ describe('timelineMediaOptions', function () {
expect(getData0(chart, 0)).toEqual(88);
expect(getLegendOption(chart).left).toEqual(50);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
expect(getLegendOption(chart).left).toEqual(50);
});
it('parse_timeline_has_baseOption', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
baseOption: {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
......@@ -227,12 +227,12 @@ describe('timelineMediaOptions', function () {
expect(getLegendOption(chart).right).not.toEqual(123);
expect(getTimelineComponent(chart) != null).toEqual(true);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
});
it('parse_timeline_has_baseOption_compat', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
timeline: { axisType: 'category' },
baseOption: {
xAxis: { data: ['a'] },
......@@ -251,12 +251,12 @@ describe('timelineMediaOptions', function () {
expect(getLegendOption(chart).right).not.toEqual(123);
expect(getTimelineComponent(chart) != null).toEqual(true);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
});
it('parse_timeline_has_baseOption_compat', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
timeline: { axisType: 'category' },
baseOption: {
xAxis: { data: ['a'] },
......@@ -275,12 +275,12 @@ describe('timelineMediaOptions', function () {
expect(getLegendOption(chart).right).not.toEqual(123);
expect(getTimelineComponent(chart) != null).toEqual(true);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
});
it('parse_timeline_no_baseOption', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
timeline: { axisType: 'category' },
xAxis: { data: ['a'] },
yAxis: {},
......@@ -296,7 +296,7 @@ describe('timelineMediaOptions', function () {
expect(getLegendOption(chart).right).not.toEqual(123);
expect(getTimelineComponent(chart) != null).toEqual(true);
chart.setOption({ timeline: { currentIndex: 1 } });
chart.setOption<EChartsOption>({ timeline: { currentIndex: 1 } });
expect(getData0(chart, 0)).toEqual(99);
});
......@@ -310,7 +310,7 @@ describe('timelineMediaOptions', function () {
describe('timeline_onceMore', function () {
it('timeline_setOptionOnceMore_baseOption', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
baseOption: {
timeline: {
axisType: 'category',
......@@ -344,7 +344,7 @@ describe('timelineMediaOptions', function () {
expect(getData0(chart, 0)).toEqual(11);
expect(getData0(chart, 1)).toEqual(22);
chart.setOption({
chart.setOption<EChartsOption>({
xAxis: {data: ['c']},
timeline: {
currentIndex: 1
......@@ -358,7 +358,7 @@ describe('timelineMediaOptions', function () {
it('timeline_setOptionOnceMore_substitudeTimelineOptions', function () {
const option: EChartsFullOption = {
const option: EChartsOption = {
baseOption: {
timeline: {
axisType: 'category',
......@@ -416,7 +416,7 @@ describe('timelineMediaOptions', function () {
expect(getData0(chart, 0)).toEqual(1111);
expect(getData0(chart, 1)).toEqual(2222);
chart.setOption({
chart.setOption<EChartsOption>({
timeline: {
currentIndex: 0
}
......@@ -425,7 +425,7 @@ describe('timelineMediaOptions', function () {
expect(getData0(chart, 0)).toEqual(55);
expect(getData0(chart, 1)).toEqual(66);
chart.setOption({
chart.setOption<EChartsOption>({
timeline: {
currentIndex: 2
}
......
......@@ -18,7 +18,7 @@
* under the License.
*/
import { createChart, isValueFinite, getECModel } from '../../core/utHelper';
import { createChart, getECModel } from '../../core/utHelper';
import { EChartsType } from '../../../../src/echarts';
import CartesianAxisModel from '../../../../src/coord/cartesian/AxisModel';
import IntervalScale from '../../../../src/scale/Interval';
......@@ -124,10 +124,10 @@ describe('scale_interval', function () {
const resultInterval = result.interval;
const niceTickExtent = result.niceTickExtent;
expect(isValueFinite(resultInterval)).toEqual(true);
expect(isValueFinite(intervalPrecision)).toEqual(true);
expect(isValueFinite(niceTickExtent[0])).toEqual(true);
expect(isValueFinite(niceTickExtent[1])).toEqual(true);
expect(resultInterval).toBeFinite();
expect(intervalPrecision).toBeFinite();
expect(niceTickExtent[0]).toBeFinite();
expect(niceTickExtent[1]).toBeFinite();
expect(niceTickExtent[0]).toBeGreaterThanOrEqual(extent[0]);
expect(niceTickExtent[1]).not.toBeGreaterThan(extent[1]);
......
......@@ -20,7 +20,7 @@
import { EChartsType } from '../../../../src/echarts';
import { createChart } from '../../core/utHelper';
import { ZRColor } from '../../../../src/util/types';
import { CustomSeriesRenderItemAPI, CustomSeriesRenderItemParams } from '../../../../src/chart/custom';
import { CustomSeriesRenderItemAPI, CustomSeriesRenderItemParams } from '../../../../src/chart/custom/install';
describe('custom_series', function () {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册