/* * 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. */ /** * AUTO-GENERATED FILE. DO NOT MODIFY. */ /* * 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 { isTypedArray, clone, createHashMap, isArray, isObject, isArrayLike, hasOwn, assert, each, map, isNumber, isString, keys } from 'zrender/lib/core/util.js'; import { SOURCE_FORMAT_ORIGINAL, SERIES_LAYOUT_BY_COLUMN, SOURCE_FORMAT_UNKNOWN, SOURCE_FORMAT_KEYED_COLUMNS, SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ARRAY_ROWS, SOURCE_FORMAT_OBJECT_ROWS, SERIES_LAYOUT_BY_ROW } from '../util/types.js'; import { getDataItemValue } from '../util/model.js'; import { BE_ORDINAL, guessOrdinal } from './helper/sourceHelper.js'; ; // @inner var SourceImpl = /** @class */ function () { function SourceImpl(fields) { this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []); this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; // Visit config this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN; this.startIndex = fields.startIndex || 0; this.dimensionsDetectedCount = fields.dimensionsDetectedCount; this.metaRawOption = fields.metaRawOption; var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine; if (dimensionsDefine) { for (var i = 0; i < dimensionsDefine.length; i++) { var dim = dimensionsDefine[i]; if (dim.type == null) { if (guessOrdinal(this, i) === BE_ORDINAL.Must) { dim.type = 'ordinal'; } } } } } return SourceImpl; }(); export function isSourceInstance(val) { return val instanceof SourceImpl; } /** * Create a source from option. * NOTE: Created source is immutable. Don't change any properties in it. */ export function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`. sourceFormat) { sourceFormat = sourceFormat || detectSourceFormat(sourceData); var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy; var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions); var source = new SourceImpl({ data: sourceData, sourceFormat: sourceFormat, seriesLayoutBy: seriesLayoutBy, dimensionsDefine: determined.dimensionsDefine, startIndex: determined.startIndex, dimensionsDetectedCount: determined.dimensionsDetectedCount, metaRawOption: clone(thisMetaRawOption) }); return source; } /** * Wrap original series data for some compatibility cases. */ export function createSourceFromSeriesDataOption(data) { return new SourceImpl({ data: data, sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL }); } /** * Clone source but excludes source data. */ export function cloneSourceShallow(source) { return new SourceImpl({ data: source.data, sourceFormat: source.sourceFormat, seriesLayoutBy: source.seriesLayoutBy, dimensionsDefine: clone(source.dimensionsDefine), startIndex: source.startIndex, dimensionsDetectedCount: source.dimensionsDetectedCount }); } /** * Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`. */ export function detectSourceFormat(data) { var sourceFormat = SOURCE_FORMAT_UNKNOWN; if (isTypedArray(data)) { sourceFormat = SOURCE_FORMAT_TYPED_ARRAY; } else if (isArray(data)) { // FIXME Whether tolerate null in top level array? if (data.length === 0) { sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; } for (var i = 0, len = data.length; i < len; i++) { var item = data[i]; if (item == null) { continue; } else if (isArray(item)) { sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; break; } else if (isObject(item)) { sourceFormat = SOURCE_FORMAT_OBJECT_ROWS; break; } } } else if (isObject(data)) { for (var key in data) { if (hasOwn(data, key) && isArrayLike(data[key])) { sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS; break; } } } return sourceFormat; } /** * Determine the source definitions from data standalone dimensions definitions * are not specified. */ function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, // standalone raw dimensions definition, like: // { // dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }] // } // in `dataset` or `series` dimensionsDefine) { var dimensionsDetectedCount; var startIndex; // PENDING: Could data be null/undefined here? // currently, if `dataset.source` not specified, error thrown. // if `series.data` not specified, nothing rendered without error thrown. // Should test these cases. if (!data) { return { dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), startIndex: startIndex, dimensionsDetectedCount: dimensionsDetectedCount }; } if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { var dataArrayRows = data; // Rule: Most of the first line are string: it is header. // Caution: consider a line with 5 string and 1 number, // it still can not be sure it is a head, because the // 5 string may be 5 values of category columns. if (sourceHeader === 'auto' || sourceHeader == null) { arrayRowsTravelFirst(function (val) { // '-' is regarded as null/undefined. if (val != null && val !== '-') { if (isString(val)) { startIndex == null && (startIndex = 1); } else { startIndex = 0; } } // 10 is an experience number, avoid long loop. }, seriesLayoutBy, dataArrayRows, 10); } else { startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0; } if (!dimensionsDefine && startIndex === 1) { dimensionsDefine = []; arrayRowsTravelFirst(function (val, index) { dimensionsDefine[index] = val != null ? val + '' : ''; }, seriesLayoutBy, dataArrayRows, Infinity); } dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null; } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { if (!dimensionsDefine) { dimensionsDefine = objectRowsCollectDimensions(data); } } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { if (!dimensionsDefine) { dimensionsDefine = []; each(data, function (colArr, key) { dimensionsDefine.push(key); }); } } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { var value0 = getDataItemValue(data[0]); dimensionsDetectedCount = isArray(value0) && value0.length || 1; } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { if (process.env.NODE_ENV !== 'production') { assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.'); } } return { startIndex: startIndex, dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), dimensionsDetectedCount: dimensionsDetectedCount }; } function objectRowsCollectDimensions(data) { var firstIndex = 0; var obj; while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line if (obj) { return keys(obj); } } // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'], // which is reasonable. But dimension name is duplicated. // Returns undefined or an array contains only object without null/undefined or string. function normalizeDimensionsOption(dimensionsDefine) { if (!dimensionsDefine) { // The meaning of null/undefined is different from empty array. return; } var nameMap = createHashMap(); return map(dimensionsDefine, function (rawItem, index) { rawItem = isObject(rawItem) ? rawItem : { name: rawItem }; // Other fields will be discarded. var item = { name: rawItem.name, displayName: rawItem.displayName, type: rawItem.type }; // User can set null in dimensions. // We don't auto specify name, otherwise a given name may // cause it to be referred unexpectedly. if (item.name == null) { return item; } // Also consider number form like 2012. item.name += ''; // User may also specify displayName. // displayName will always exists except user not // specified or dim name is not specified or detected. // (A auto generated dim name will not be used as // displayName). if (item.displayName == null) { item.displayName = item.name; } var exist = nameMap.get(item.name); if (!exist) { nameMap.set(item.name, { count: 1 }); } else { item.name += '-' + exist.count++; } return item; }); } function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) { if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { for (var i = 0; i < data.length && i < maxLoop; i++) { cb(data[i] ? data[i][0] : null, i); } } else { var value0 = data[0] || []; for (var i = 0; i < value0.length && i < maxLoop; i++) { cb(value0[i], i); } } } export function shouldRetrieveDataByName(source) { var sourceFormat = source.sourceFormat; return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS; }