提交 469fd041 编写于 作者: P pissang

Merge branch 'master' into treeshakable-exports

......@@ -112,13 +112,13 @@ class CandlestickSeriesModel extends SeriesModel<CandlestickSeriesOption> {
clip: true,
itemStyle: {
color: '#c23531', // 阳线 positive
color0: '#314656', // 阴线 negative '#c23531', '#314656'
borderWidth: 1,
// FIXME
// ec2中使用的是lineStyle.color 和 lineStyle.color0
borderColor: '#c23531',
borderColor0: '#314656'
color: '#eb5454', // positive
color0: '#47b262', // negative
borderColor: '#eb5454',
borderColor0: '#47b262',
// borderColor: '#d24040',
// borderColor0: '#398f4f',
borderWidth: 1
},
emphasis: {
......
......@@ -17,8 +17,10 @@
* under the License.
*/
import { DataTransformOption, ExternalDataTransform } from '../../data/helper/transform';
import { DimensionIndex, OptionDataItem } from '../../util/types';
import {
DataTransformOption, ExternalDataTransform, DataTransformDataItem, ExternalDataTransformResultItem
} from '../../data/helper/transform';
import { DimensionIndex } from '../../util/types';
import { parseConditionalExpression, ConditionalExpressionOption } from '../../util/conditionalExpression';
import { hasOwn, createHashMap } from 'zrender/src/core/util';
import { makePrintable, throwError } from '../../util/log';
......@@ -41,7 +43,7 @@ export const filterTransform: ExternalDataTransform<FilterTransformOption> = {
// is better than return the entire raw soruce for user to find the mistake.
const upstream = params.upstream;
let rawItem: OptionDataItem;
let rawItem: DataTransformDataItem;
const condition = parseConditionalExpression<{ dimIdx: DimensionIndex }>(params.config, {
......@@ -84,12 +86,12 @@ export const filterTransform: ExternalDataTransform<FilterTransformOption> = {
for (let i = 0, len = upstream.count(); i < len; i++) {
rawItem = upstream.getRawDataItem(i);
if (condition.evaluate()) {
resultData.push(rawItem);
resultData.push(rawItem as any);
}
}
return {
data: resultData
data: resultData as ExternalDataTransformResultItem['data']
};
}
};
......@@ -17,7 +17,9 @@
* under the License.
*/
import { DataTransformOption, ExternalDataTransform } from '../../data/helper/transform';
import {
DataTransformOption, ExternalDataTransform, ExternalDataTransformResultItem
} from '../../data/helper/transform';
import {
DimensionLoose, DimensionIndex, OptionDataValue, SOURCE_FORMAT_ARRAY_ROWS, SOURCE_FORMAT_OBJECT_ROWS
} from '../../util/types';
......@@ -199,7 +201,7 @@ export const sortTransform: ExternalDataTransform<SortTransformOption> = {
});
return {
data: resultData
data: resultData as ExternalDataTransformResultItem['data']
};
}
};
......
......@@ -221,7 +221,7 @@ class List<
// We have an extra array store here. It's faster to be acessed than KV structured `_storage`.
// We profile the code `storage[dim]` and it seems to be KeyedLoadIC_Megamorphic instead of fast property access.
// Not sure why this happens. But using an extra array seems leads to faster `initData`
// See https://github.com/apache/incubator-echarts/pull/13314 for more explaination.
// See https://github.com/apache/incubator-echarts/pull/13314 for more explanation.
private _storageArr: DataValueChunk[] = [];
private _nameList: string[] = [];
private _idList: string[] = [];
......
......@@ -287,7 +287,10 @@ function makeEncodeDefine(
: null;
}
function detectSourceFormat(data: DatasetOption['source']): SourceFormat {
/**
* Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`.
*/
export function detectSourceFormat(data: DatasetOption['source']): SourceFormat {
let sourceFormat: SourceFormat = SOURCE_FORMAT_UNKNOWN;
if (isTypedArray(data)) {
......@@ -323,9 +326,6 @@ function detectSourceFormat(data: DatasetOption['source']): SourceFormat {
}
}
}
else if (data != null) {
throw new Error('Invalid data');
}
return sourceFormat;
}
......
......@@ -82,31 +82,6 @@ export function resetSourceDefaulter(ecModel: GlobalModel): void {
innerGlobalModel(ecModel).datasetMap = createHashMap();
}
// See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
export function inheritSourceMetaRawOption(
upstream: Source, // Can be null/undefined
newMetaRawOption: SourceMetaRawOption // Can NOT be null/undefined
): SourceMetaRawOption {
const parentMetaRawOption = upstream ? upstream.metaRawOption : null;
const seriesLayoutBy = retrieve2(
newMetaRawOption.seriesLayoutBy,
parentMetaRawOption ? parentMetaRawOption.seriesLayoutBy : null
);
// sourceHeader and dimensions should use the "detected result" rather than "meta raw".
// Consider the case: transform return only "data" but no "dimensions", that should means inherit
// dimensions definition from upstream. But the returned data does not contain header line and can not
// be used as dimension-detection. In this case we should use "detected dimensions" of upstream directly.
const sourceHeader = retrieve2(
newMetaRawOption.sourceHeader,
upstream ? upstream.startIndex : null
);
const dimensions = retrieve2(
newMetaRawOption.dimensions,
upstream ? upstream.dimensionsDefine : null
);
return { seriesLayoutBy, sourceHeader, dimensions };
}
/**
* [The strategy of the arrengment of data dimensions for dataset]:
* "value way": all axes are non-category axes. So series one by one take
......
......@@ -19,7 +19,7 @@
import { DatasetModel } from '../../component/dataset/install';
import SeriesModel from '../../model/Series';
import { setAsPrimitive, map, isTypedArray, assert, each } from 'zrender/src/core/util';
import { setAsPrimitive, map, isTypedArray, assert, each, retrieve2 } from 'zrender/src/core/util';
import { SourceMetaRawOption, Source, createSource, cloneSourceShallow } from '../Source';
import {
SeriesEncodableModel, OptionSourceData,
......@@ -27,8 +27,7 @@ import {
SourceFormat, SeriesLayoutBy, OptionSourceHeader, DimensionDefinitionLoose
} from '../../util/types';
import {
querySeriesUpstreamDatasetModel, queryDatasetUpstreamDatasetModels,
inheritSourceMetaRawOption
querySeriesUpstreamDatasetModel, queryDatasetUpstreamDatasetModels
} from './sourceHelper';
import { applyDataTransform } from './transform';
......@@ -192,7 +191,7 @@ export class SourceManager {
const seriesModel = sourceHost as SeriesEncodableModel;
let data;
let sourceFormat: SourceFormat;
let upSource;
let upSource: Source;
// Has upstream dataset
if (hasUpstream) {
......@@ -212,14 +211,27 @@ export class SourceManager {
}
// See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root.
const thisMetaRawOption = inheritSourceMetaRawOption(
upSource,
this._getSourceMetaRawOption()
const newMetaRawOption = this._getSourceMetaRawOption();
const upMetaRawOption = upSource ? upSource.metaRawOption : null;
const seriesLayoutBy = retrieve2(
newMetaRawOption.seriesLayoutBy,
upMetaRawOption ? upMetaRawOption.seriesLayoutBy : null
);
const sourceHeader = retrieve2(
newMetaRawOption.sourceHeader,
upMetaRawOption ? upMetaRawOption.sourceHeader : null
);
// Note here we should not use `upSource.dimensionsDefine`. Consider the case:
// `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`,
// but series need `seriesLayoutBy: 'row'`.
const dimensions = retrieve2(
newMetaRawOption.dimensions,
upMetaRawOption ? upMetaRawOption.dimensions : null
);
resultSourceList = [createSource(
data,
thisMetaRawOption,
{ seriesLayoutBy, sourceHeader, dimensions },
sourceFormat,
seriesModel.get('encode', true)
)];
......
......@@ -18,26 +18,22 @@
*/
import {
Dictionary, OptionSourceData, DimensionDefinitionLoose,
SourceFormat, DimensionDefinition, OptionDataItem, DimensionIndex,
Dictionary, DimensionDefinitionLoose,
SourceFormat, DimensionDefinition, DimensionIndex,
OptionDataValue, DimensionLoose, DimensionName, ParsedValue,
SERIES_LAYOUT_BY_COLUMN, SOURCE_FORMAT_OBJECT_ROWS, SOURCE_FORMAT_ARRAY_ROWS,
OptionSourceDataObjectRows, OptionSourceDataArrayRows
} from '../../util/types';
import { normalizeToArray } from '../../util/model';
import {
createHashMap, bind, each, hasOwn, map, clone, isObject,
isArrayLike,
extend,
isArray
createHashMap, bind, each, hasOwn, map, clone, isObject, extend
} from 'zrender/src/core/util';
import {
getRawSourceItemGetter, getRawSourceDataCounter, getRawSourceValueGetter
} from './dataProvider';
import { parseDataValue } from './dataValueHelper';
import { inheritSourceMetaRawOption } from './sourceHelper';
import { consoleLog, makePrintable, throwError } from '../../util/log';
import { createSource, Source } from '../Source';
import { createSource, Source, SourceMetaRawOption, detectSourceFormat } from '../Source';
export type PipedDataTransformOption = DataTransformOption[];
......@@ -71,7 +67,7 @@ export interface ExternalDataTransformResultItem {
/**
* If `data` is null/undefined, inherit upstream data.
*/
data: OptionSourceData;
data: OptionSourceDataArrayRows | OptionSourceDataObjectRows;
/**
* A `transform` can optionally return a dimensions definition.
* The rule:
......@@ -83,6 +79,7 @@ export interface ExternalDataTransformResultItem {
*/
dimensions?: DimensionDefinitionLoose[];
}
export type DataTransformDataItem = ExternalDataTransformResultItem['data'][number];
export interface ExternalDimensionDefinition extends Partial<DimensionDefinition> {
// Mandatory
index: DimensionIndex;
......@@ -110,7 +107,7 @@ export class ExternalSource {
throw new Error('not supported');
}
getRawDataItem(dataIndex: number): OptionDataItem {
getRawDataItem(dataIndex: number): DataTransformDataItem {
// Only built-in transform available.
throw new Error('not supported');
}
......@@ -152,7 +149,7 @@ export class ExternalSource {
return;
}
retrieveValueFromItem(dataItem: OptionDataItem, dimIndex: DimensionIndex): OptionDataValue {
retrieveValueFromItem(dataItem: DataTransformDataItem, dimIndex: DimensionIndex): OptionDataValue {
return;
}
......@@ -169,6 +166,17 @@ function createExternalSource(internalSource: Source, externalTransform: Externa
const sourceFormat = extSource.sourceFormat = internalSource.sourceFormat;
const sourceHeaderCount = internalSource.startIndex;
let errMsg = '';
if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) {
// For the logic simplicity in transformer, only 'culumn' is
// supported in data transform. Otherwise, the `dimensionsDefine`
// might be detected by 'row', which probably confuses users.
if (__DEV__) {
errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.';
}
throwError(errMsg);
}
// [MEMO]
// Create a new dimensions structure for exposing.
// Do not expose all dimension info to users directly.
......@@ -219,7 +227,7 @@ function createExternalSource(internalSource: Source, externalTransform: Externa
const rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);
if (externalTransform.__isBuiltIn) {
extSource.getRawDataItem = function (dataIndex) {
return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex) as DataTransformDataItem;
};
extSource.getRawData = bind(getRawData, null, internalSource);
}
......@@ -231,7 +239,7 @@ function createExternalSource(internalSource: Source, externalTransform: Externa
const rawValueGetter = getRawSourceValueGetter(sourceFormat);
extSource.retrieveValue = function (dataIndex, dimIndex) {
const rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
const rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex) as DataTransformDataItem;
return retrieveValueFromItem(rawItem, dimIndex);
};
const retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) {
......@@ -253,34 +261,31 @@ function createExternalSource(internalSource: Source, externalTransform: Externa
function getRawData(upstream: Source): Source['data'] {
const sourceFormat = upstream.sourceFormat;
const data = upstream.data;
if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS
|| sourceFormat === SOURCE_FORMAT_OBJECT_ROWS
|| !data
|| (isArray(data) && !data.length)
) {
return upstream.data;
if (!isSupportedSourceFormat(sourceFormat)) {
let errMsg = '';
if (__DEV__) {
errMsg = '`getRawData` is not supported in source format ' + sourceFormat;
}
throwError(errMsg);
}
let errMsg = '';
if (__DEV__) {
errMsg = '`getRawData` is not supported in source format ' + sourceFormat;
}
throwError(errMsg);
return upstream.data;
}
function cloneRawData(upstream: Source): Source['data'] {
const sourceFormat = upstream.sourceFormat;
const data = upstream.data;
if (!data) {
return data;
}
else if (isArray(data) && !data.length) {
return [];
if (!isSupportedSourceFormat(sourceFormat)) {
let errMsg = '';
if (__DEV__) {
errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat;
}
throwError(errMsg);
}
else if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
const result = [];
for (let i = 0, len = data.length; i < len; i++) {
// Not strictly clone for performance
......@@ -442,39 +447,91 @@ function applySingleDataTransform(
}
}
return map(resultList, function (result) {
return map(resultList, function (result, resultIndex) {
let errMsg = '';
if (!isObject(result)) {
if (__DEV__) {
errMsg = 'A transform should not return some empty results.';
}
throwError(errMsg);
}
let resultData = result.data;
if (resultData != null) {
if (!isObject(resultData) && !isArrayLike(resultData)) {
if (__DEV__) {
errMsg = 'Result data should be object or array in data transform.';
}
throwError(errMsg);
if (!result.data) {
if (__DEV__) {
errMsg = 'Transform result data should be not be null or undefined';
}
throwError(errMsg);
}
else {
// Inherit from upstream[0]
resultData = upSourceList[0].data;
const sourceFormat = detectSourceFormat(result.data);
if (!isSupportedSourceFormat(sourceFormat)) {
if (__DEV__) {
errMsg = 'Transform result data should be array rows or object rows.';
}
throwError(errMsg);
}
const resultMetaRawOption = inheritSourceMetaRawOption(
upSourceList[0],
{
let resultMetaRawOption: SourceMetaRawOption;
const firstUpSource = upSourceList[0];
/**
* Intuitively, the end users known the content of the original `dataset.source`,
* calucating the transform result in mind.
* Suppose the original `dataset.source` is:
* ```js
* [
* ['product', '2012', '2013', '2014', '2015'],
* ['AAA', 41.1, 30.4, 65.1, 53.3],
* ['BBB', 86.5, 92.1, 85.7, 83.1],
* ['CCC', 24.1, 67.2, 79.5, 86.4]
* ]
* ```
* The dimension info have to be detected from the source data.
* Some of the transformers (like filter, sort) will follow the dimension info
* of upstream, while others use new dimensions (like aggregate).
* Transformer can output a field `dimensions` to define the its own output dimensions.
* We also allow transformers to ignore the output `dimensions` field, and
* inherit the upstream dimensions definition. It can reduce the burden of handling
* dimensions in transformers.
*
* See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
*/
if (
firstUpSource
&& resultIndex === 0
// If transformer returns `dimensions`, it means that the transformer has different
// dimensions definitions. We do not inherit anything from upstream.
&& !result.dimensions
) {
const startIndex = firstUpSource.startIndex;
// We copy the header of upstream to the result becuase:
// (1) The returned data always does not contain header line and can not be used
// as dimension-detection. In this case we can not use "detected dimensions" of
// upstream directly, because it might be detected based on different `seriesLayoutBy`.
// (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`.
// So the original detected header should be add to the result, otherwise they can not be read.
if (startIndex) {
result.data = (firstUpSource.data as []).slice(0, startIndex)
.concat(result.data as []);
}
resultMetaRawOption = {
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
sourceHeader: startIndex,
dimensions: firstUpSource.metaRawOption.dimensions
};
}
else {
resultMetaRawOption = {
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
sourceHeader: 0,
dimensions: result.dimensions
}
);
};
}
return createSource(
resultData,
result.data,
resultMetaRawOption,
null,
null
......@@ -482,3 +539,6 @@ function applySingleDataTransform(
});
}
function isSupportedSourceFormat(sourceFormat: SourceFormat): boolean {
return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS;
}
......@@ -198,10 +198,12 @@ const theme = {
},
candlestick: {
itemStyle: {
color: '#FD1050',
color0: '#0CF49B',
borderColor: '#FD1050',
borderColor0: '#0CF49B'
color: '#f64e56',
color0: '#54ea92',
borderColor: '#f64e56',
borderColor0: '#54ea92'
// borderColor: '#ca2824',
// borderColor0: '#09a443'
}
}
};
......
<!DOCTYPE html>
<!--
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">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="lib/esl.js"></script>
<script src="lib/config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<!-- <script src="ut/lib/canteen.js"></script> -->
<link rel="stylesheet" href="lib/reset.css" />
</head>
<body>
<style>
</style>
<div id="main0"></div>
<script>
require(['echarts'/*, 'map/js/china' */], function (echarts) {
option = {
legend: {},
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['AAA', 41.1, 30.4, 65.1, 53.3],
['BBB', 86.5, 92.1, 85.7, 83.1],
['CCC', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0},
{type: 'category', gridIndex: 1}
],
yAxis: [
{gridIndex: 0},
{gridIndex: 1}
],
grid: [
{bottom: '55%'},
{top: '55%'}
],
series: [
// These series are in the first grid.
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// These series are in the second grid.
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
};
var chart = testHelper.create(echarts, 'main0', {
title: [
'The legend should be: ',
'"AAA", "BBB", "2012", "2013", "2014"'
],
option: option
// height: 300,
// buttons: [{text: 'btn-txt', onclick: function () {}}],
// recordCanvas: true,
});
});
</script>
</body>
</html>
......@@ -27,6 +27,7 @@ import {
import { ComponentMainType } from '../../../src/util/types';
import Group from 'zrender/src/graphic/Group';
import Element from 'zrender/src/Element';
import GlobalModel from '../../../src/model/Global';
export function createChart(params?: {
......@@ -137,9 +138,13 @@ export function getViewGroup(
mainType: ComponentMainType,
index?: number
): Group {
const component = chart.getModel().getComponent(mainType, index);
const component = getECModel(chart).getComponent(mainType, index);
return component ? chart[
mainType === 'series' ? '_chartsMap' : '_componentsMap'
][component.__viewId].group : null;
}
export function getECModel(chart: EChartsType): GlobalModel {
// @ts-ignore
return chart.getModel();
}
......@@ -19,7 +19,7 @@
*/
import { findEffectedDataZooms } from '../../../../../src/component/dataZoom/helper';
import { createChart } from '../../../core/utHelper';
import { createChart, getECModel } from '../../../core/utHelper';
import { EChartsType } from '../../../../../src/echarts';
......@@ -50,12 +50,12 @@ describe('dataZoom/helper', function () {
});
const payload = { type: 'dataZoom', dataZoomIndex: 0 };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
const dzModels = findEffectedDataZooms(getECModel(chart), 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);
expect(dzModels[0] === getECModel(chart).getComponent('dataZoom', 0)).toEqual(true);
expect(dzModels[1] === getECModel(chart).getComponent('dataZoom', 3)).toEqual(true);
expect(dzModels[2] === getECModel(chart).getComponent('dataZoom', 2)).toEqual(true);
});
it('findLinkedNodes_crossXY', function () {
......@@ -72,13 +72,13 @@ describe('dataZoom/helper', function () {
});
const payload = { type: 'dataZoom', dataZoomIndex: 0 };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
const dzModels = findEffectedDataZooms(getECModel(chart), 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);
expect(dzModels[0] === getECModel(chart).getComponent('dataZoom', 0)).toEqual(true);
expect(dzModels[1] === getECModel(chart).getComponent('dataZoom', 1)).toEqual(true);
expect(dzModels[2] === getECModel(chart).getComponent('dataZoom', 2)).toEqual(true);
expect(dzModels[3] === getECModel(chart).getComponent('dataZoom', 3)).toEqual(true);
});
it('findLinkedNodes_emptySourceModel', function () {
......@@ -95,7 +95,7 @@ describe('dataZoom/helper', function () {
});
const payload = { type: 'other' };
const dzModels = findEffectedDataZooms(chart.getModel(), payload);
const dzModels = findEffectedDataZooms(getECModel(chart), payload);
expect(dzModels.length === 0);
});
......
......@@ -17,7 +17,7 @@
* under the License.
*/
import { createChart, getGraphicElements } from '../../../core/utHelper';
import { createChart, getGraphicElements, getECModel } from '../../../core/utHelper';
// import { imageURI } from './setOptionImageURI';
import { EChartsType } from '../../../../../src/echarts';
import Element from 'zrender/src/Element';
......@@ -338,8 +338,8 @@ describe('graphic_setOption', function () {
]
});
expect(!!chart.getModel().getComponent('graphic')).toEqual(true);
expect(chart.getModel().getComponent('graphic', 1) == null).toEqual(true);
expect(!!getECModel(chart).getComponent('graphic')).toEqual(true);
expect(getECModel(chart).getComponent('graphic', 1) == null).toEqual(true);
});
......
......@@ -18,7 +18,7 @@
* under the License.
*/
import { createChart } from '../../../core/utHelper';
import { createChart, getECModel } from '../../../core/utHelper';
import { EChartsType } from '../../../../../src/echarts';
import { EChartsFullOption } from '../../../../../src/option';
import { ContinousVisualMapOption } from '../../../../../src/component/visualMap/ContinuousModel';
......@@ -256,7 +256,7 @@ describe('vsiaulMap_setOption', function () {
]
});
const ecModel = chart.getModel();
const ecModel = getECModel(chart);
function getVisual(idx: number, visualType: 'color' | 'opacity' | 'symbol') {
return (ecModel.getComponent('visualMap', idx) as VisualMapModel)
......
/*
* 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 { EChartsType } from '../../../../src/echarts';
import { createChart, removeChart, getECModel } from '../../core/utHelper';
import { EChartsFullOption } from '../../../../src/option';
import { retrieveRawValue } from '../../../../src/data/helper/dataProvider';
describe('dataTransform', function () {
let chart: EChartsType;
beforeEach(function () {
chart = createChart({
width: 200,
height: 150
});
});
afterEach(function () {
removeChart(chart);
});
function makeDatasetSourceDetection() {
return [
['product', '2012', '2013', '2014', '2015'],
['AAA', 41.1, 30.4, 65.1, 53.3],
['BBB', 86.5, 92.1, 85.7, 83.1],
['CCC', 24.1, 67.2, 79.5, 86.4]
];
}
function makeDatasetSourceNonDetectionByRow() {
return {
dimensions: ['2012', '2013', '2014', '2015'],
source: [
[41.1, 30.4, 65.1, 53.3],
[86.5, 92.1, 85.7, 83.1],
[24.1, 67.2, 79.5, 86.4]
]
};
}
it('forbid_seriesLayoutBy_row', function () {
const option: EChartsFullOption = {
dataset: [{
source: makeDatasetSourceDetection(),
// This config should cause error thrown.
seriesLayoutBy: 'row'
}, {
transform: { type: 'filter', config: { dimension: 0, ne: '' } }
}],
xAxis: { type: 'category' },
yAxis: {},
series: { type: 'bar', datasetIndex: 1 }
};
expect(() => {
chart.setOption(option);
}).toThrowError(/column/);
});
it('seriesLayoutBy_changed_no_transform', function () {
const option: EChartsFullOption = {
dataset: {
source: makeDatasetSourceDetection()
},
xAxis: { type: 'category' },
yAxis: {},
series: { type: 'bar', seriesLayoutBy: 'row' }
};
chart.setOption(option);
const listData = getECModel(chart).getSeries()[0].getData();
expect(listData.getDimension(1)).toEqual('AAA');
expect(listData.getDimension(2)).toEqual('BBB');
expect(listData.getDimension(3)).toEqual('CCC');
});
[{
transform:
{ type: 'filter', config: { dimension: 'product', '!=': 'XXX' } }
}, {
transform: [
{ type: 'filter', config: { dimension: 'product', '!=': 'XXX' } },
{ type: 'filter', config: { dimension: 'product', '!=': 'XXX' } }
]
}].forEach((dataset1, itIdx) => {
it(`seriesLayoutBy_changed_transform_detection_${itIdx}`, function () {
const option: EChartsFullOption = {
dataset: [{
source: makeDatasetSourceDetection()
}, dataset1],
xAxis: { type: 'category' },
yAxis: {},
series: { type: 'bar', datasetIndex: 1, seriesLayoutBy: 'row' }
};
chart.setOption(option);
const listData = getECModel(chart).getSeries()[0].getData();
expect(listData.getDimension(1)).toEqual('AAA');
expect(listData.getDimension(2)).toEqual('BBB');
expect(listData.getDimension(3)).toEqual('CCC');
expect(listData.get('product', 0)).toEqual(0);
expect(retrieveRawValue(listData, 0, 'product')).toEqual('2012');
expect(listData.get('product', 1)).toEqual(1);
expect(retrieveRawValue(listData, 1, 'product')).toEqual('2013');
});
});
[{
transform:
{ type: 'filter', config: { dimension: 0, '!=': 'XXX' } }
}, {
transform: [
{ type: 'filter', config: { dimension: 0, '!=': 'XXX' } },
{ type: 'filter', config: { dimension: 0, '!=': 'XXX' } }
]
}].forEach((dataset1, itIdx) => {
it(`seriesLayoutBy_changed_transform_non_detection_${itIdx}`, function () {
const sourceWrap = makeDatasetSourceNonDetectionByRow();
const option: EChartsFullOption = {
dataset: [{
dimensions: sourceWrap.dimensions,
source: sourceWrap.source
}, dataset1],
xAxis: {},
yAxis: {},
series: { type: 'bar', datasetIndex: 1, seriesLayoutBy: 'row' }
};
chart.setOption(option);
const listData = getECModel(chart).getSeries()[0].getData();
expect(listData.get(listData.getDimension(0), 0)).toEqual(41.1);
expect(listData.get(listData.getDimension(0), 1)).toEqual(30.4);
});
});
[{
transform:
{ type: 'filter', config: { dimension: '2012', '!=': 'XXX' } }
}, {
transform: [
{ type: 'filter', config: { dimension: '2012', '!=': 'XXX' } },
{ type: 'filter', config: { dimension: '2012', '!=': 'XXX' } }
]
}].forEach((dataset1, itIdx) => {
it(`inherit_detected_dimensions_${itIdx}`, function () {
const option: EChartsFullOption = {
dataset: [{
source: makeDatasetSourceDetection()
}, dataset1],
xAxis: { type: 'category' },
yAxis: {},
series: { type: 'bar', datasetIndex: 1 }
};
chart.setOption(option);
const listData = getECModel(chart).getSeries()[0].getData();
expect(listData.getDimension(0)).toEqual('product');
expect(listData.getDimension(1)).toEqual('2012');
expect(listData.getDimension(2)).toEqual('2013');
});
});
});
......@@ -19,7 +19,7 @@
*/
import { EChartsType } from '../../../../src/echarts';
import { createChart } from '../../core/utHelper';
import { createChart, getECModel } from '../../core/utHelper';
import { ComponentMainType, ParsedValue } from '../../../../src/util/types';
import SeriesModel from '../../../../src/model/Series';
import ComponentModel from '../../../../src/model/Component';
......@@ -39,11 +39,11 @@ describe('modelAndOptionMapping', function () {
}
function getSeries(chart: EChartsType, seriesIndex: number): SeriesModel {
return chart.getModel().getComponent('series', seriesIndex) as SeriesModel;
return getECModel(chart).getComponent('series', seriesIndex) as SeriesModel;
}
function getModel(chart: EChartsType, type: ComponentMainType, index: number): ComponentModel {
return chart.getModel().getComponent(type, index);
return getECModel(chart).getComponent(type, index);
}
function countSeries(chart: EChartsType): number {
......@@ -54,7 +54,7 @@ describe('modelAndOptionMapping', function () {
// FIXME
// access private
// @ts-ignore
return chart.getModel()._componentsMap.get(type).length;
return getECModel(chart)._componentsMap.get(type).length;
}
function getChartView(chart: EChartsType, series: SeriesModel): ChartView {
......@@ -801,14 +801,14 @@ describe('modelAndOptionMapping', function () {
]
};
chart.setOption(option);
expect(chart.getModel().option.backgroundColor).toEqual('rgba(1,1,1,1)');
expect(getECModel(chart).option.backgroundColor).toEqual('rgba(1,1,1,1)');
// Not merge
chart.setOption({
backgroundColor: '#fff'
}, true);
expect(chart.getModel().option.backgroundColor).toEqual('#fff');
expect(getECModel(chart).option.backgroundColor).toEqual('#fff');
});
it('innerId', function () {
......
......@@ -23,7 +23,7 @@ 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 { createChart, getECModel } from '../../core/utHelper';
import { EChartsFullOption } from '../../../../src/option';
......@@ -33,13 +33,13 @@ describe('timelineMediaOptions', function () {
return getSeries(chart, seriesIndex).getData().get('y', 0);
}
function getSeries(chart: EChartsType, seriesIndex: number): SeriesModel {
return chart.getModel().getComponent('series', seriesIndex) as SeriesModel;
return getECModel(chart).getComponent('series', seriesIndex) as SeriesModel;
}
function getLegendOption(chart: EChartsType): LegendOption {
return chart.getModel().getComponent('legend', 0).option;
return getECModel(chart).getComponent('legend', 0).option;
}
function getTimelineComponent(chart: EChartsType): TimelineModel {
return chart.getModel().getComponent('timeline', 0) as TimelineModel;
return getECModel(chart).getComponent('timeline', 0) as TimelineModel;
}
let chart: EChartsType;
......@@ -388,7 +388,7 @@ describe('timelineMediaOptions', function () {
};
chart.setOption(option);
let ecModel = chart.getModel();
let ecModel = getECModel(chart);
expect(getData0(chart, 0)).toEqual(1111);
expect(getData0(chart, 1)).toEqual(2222);
......@@ -410,7 +410,7 @@ describe('timelineMediaOptions', function () {
}]
});
ecModel = chart.getModel();
ecModel = getECModel(chart);
const optionGotten = ecModel.getOption();
expect(optionGotten.backgroundColor).toEqual('#987654');
expect(getData0(chart, 0)).toEqual(1111);
......
......@@ -18,7 +18,7 @@
* under the License.
*/
import { createChart, isValueFinite } from '../../core/utHelper';
import { createChart, isValueFinite, getECModel } from '../../core/utHelper';
import { EChartsType } from '../../../../src/echarts';
import CartesianAxisModel from '../../../../src/coord/cartesian/AxisModel';
import IntervalScale from '../../../../src/scale/Interval';
......@@ -57,7 +57,7 @@ describe('scale_interval', function () {
series: [{type: 'line', data: []}]
});
const yAxis = chart.getModel().getComponent('yAxis', 0) as CartesianAxisModel;
const yAxis = getECModel(chart).getComponent('yAxis', 0) as CartesianAxisModel;
const scale = yAxis.axis.scale;
const ticks = scale.getTicks();
......@@ -91,7 +91,7 @@ describe('scale_interval', function () {
]
});
const yAxis = chart.getModel().getComponent('yAxis', 0) as CartesianAxisModel;
const yAxis = getECModel(chart).getComponent('yAxis', 0) as CartesianAxisModel;
const scale = yAxis.axis.scale as IntervalScale;
const ticks = scale.getTicks();
const labels = yAxis.axis.getViewLabels().map(function (item) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册