123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /*
- * 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 { VISUAL_DIMENSIONS } from '../../util/types.js';
- import SeriesDimensionDefine from '../SeriesDimensionDefine.js';
- import { createHashMap, defaults, each, extend, isObject, isString } from 'zrender/lib/core/util.js';
- import { createSourceFromSeriesDataOption, isSourceInstance } from '../Source.js';
- import { CtorInt32Array } from '../DataStore.js';
- import { normalizeToArray } from '../../util/model.js';
- import { BE_ORDINAL, guessOrdinal } from './sourceHelper.js';
- import { createDimNameMap, ensureSourceDimNameMap, SeriesDataSchema, shouldOmitUnusedDimensions } from './SeriesDataSchema.js';
- /**
- * For outside usage compat (like echarts-gl are using it).
- */
- export function createDimensions(source, opt) {
- return prepareSeriesDataSchema(source, opt).dimensions;
- }
- /**
- * This method builds the relationship between:
- * + "what the coord sys or series requires (see `coordDimensions`)",
- * + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)"
- * + "what the data source provids (see `source`)".
- *
- * Some guess strategy will be adapted if user does not define something.
- * If no 'value' dimension specified, the first no-named dimension will be
- * named as 'value'.
- *
- * @return The results are always sorted by `storeDimIndex` asc.
- */
- export default function prepareSeriesDataSchema(
- // TODO: TYPE completeDimensions type
- source, opt) {
- if (!isSourceInstance(source)) {
- source = createSourceFromSeriesDataOption(source);
- }
- opt = opt || {};
- var sysDims = opt.coordDimensions || [];
- var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || [];
- var coordDimNameMap = createHashMap();
- var resultList = [];
- var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount);
- // Try to ignore unused dimensions if sharing a high dimension datastore
- // 30 is an experience value.
- var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount);
- var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine;
- var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef);
- var encodeDef = opt.encodeDefine;
- if (!encodeDef && opt.encodeDefaulter) {
- encodeDef = opt.encodeDefaulter(source, dimCount);
- }
- var encodeDefMap = createHashMap(encodeDef);
- var indicesMap = new CtorInt32Array(dimCount);
- for (var i = 0; i < indicesMap.length; i++) {
- indicesMap[i] = -1;
- }
- function getResultItem(dimIdx) {
- var idx = indicesMap[dimIdx];
- if (idx < 0) {
- var dimDefItemRaw = dimsDef[dimIdx];
- var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : {
- name: dimDefItemRaw
- };
- var resultItem = new SeriesDimensionDefine();
- var userDimName = dimDefItem.name;
- if (userDimName != null && dataDimNameMap.get(userDimName) != null) {
- // Only if `series.dimensions` is defined in option
- // displayName, will be set, and dimension will be displayed vertically in
- // tooltip by default.
- resultItem.name = resultItem.displayName = userDimName;
- }
- dimDefItem.type != null && (resultItem.type = dimDefItem.type);
- dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
- var newIdx = resultList.length;
- indicesMap[dimIdx] = newIdx;
- resultItem.storeDimIndex = dimIdx;
- resultList.push(resultItem);
- return resultItem;
- }
- return resultList[idx];
- }
- if (!omitUnusedDimensions) {
- for (var i = 0; i < dimCount; i++) {
- getResultItem(i);
- }
- }
- // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`.
- encodeDefMap.each(function (dataDimsRaw, coordDim) {
- var dataDims = normalizeToArray(dataDimsRaw).slice();
- // Note: It is allowed that `dataDims.length` is `0`, e.g., options is
- // `{encode: {x: -1, y: 1}}`. Should not filter anything in
- // this case.
- if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) {
- encodeDefMap.set(coordDim, false);
- return;
- }
- var validDataDims = encodeDefMap.set(coordDim, []);
- each(dataDims, function (resultDimIdxOrName, idx) {
- // The input resultDimIdx can be dim name or index.
- var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName;
- if (resultDimIdx != null && resultDimIdx < dimCount) {
- validDataDims[idx] = resultDimIdx;
- applyDim(getResultItem(resultDimIdx), coordDim, idx);
- }
- });
- });
- // Apply templates and default order from `sysDims`.
- var availDimIdx = 0;
- each(sysDims, function (sysDimItemRaw) {
- var coordDim;
- var sysDimItemDimsDef;
- var sysDimItemOtherDims;
- var sysDimItem;
- if (isString(sysDimItemRaw)) {
- coordDim = sysDimItemRaw;
- sysDimItem = {};
- } else {
- sysDimItem = sysDimItemRaw;
- coordDim = sysDimItem.name;
- var ordinalMeta = sysDimItem.ordinalMeta;
- sysDimItem.ordinalMeta = null;
- sysDimItem = extend({}, sysDimItem);
- sysDimItem.ordinalMeta = ordinalMeta;
- // `coordDimIndex` should not be set directly.
- sysDimItemDimsDef = sysDimItem.dimsDef;
- sysDimItemOtherDims = sysDimItem.otherDims;
- sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null;
- }
- var dataDims = encodeDefMap.get(coordDim);
- // negative resultDimIdx means no need to mapping.
- if (dataDims === false) {
- return;
- }
- dataDims = normalizeToArray(dataDims);
- // dimensions provides default dim sequences.
- if (!dataDims.length) {
- for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
- while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) {
- availDimIdx++;
- }
- availDimIdx < dimCount && dataDims.push(availDimIdx++);
- }
- }
- // Apply templates.
- each(dataDims, function (resultDimIdx, coordDimIndex) {
- var resultItem = getResultItem(resultDimIdx);
- // Coordinate system has a higher priority on dim type than source.
- if (isUsingSourceDimensionsDef && sysDimItem.type != null) {
- resultItem.type = sysDimItem.type;
- }
- applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
- if (resultItem.name == null && sysDimItemDimsDef) {
- var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
- !isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = {
- name: sysDimItemDimsDefItem
- });
- resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name;
- resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip;
- }
- // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}
- sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
- });
- });
- function applyDim(resultItem, coordDim, coordDimIndex) {
- if (VISUAL_DIMENSIONS.get(coordDim) != null) {
- resultItem.otherDims[coordDim] = coordDimIndex;
- } else {
- resultItem.coordDim = coordDim;
- resultItem.coordDimIndex = coordDimIndex;
- coordDimNameMap.set(coordDim, true);
- }
- }
- // Make sure the first extra dim is 'value'.
- var generateCoord = opt.generateCoord;
- var generateCoordCount = opt.generateCoordCount;
- var fromZero = generateCoordCount != null;
- generateCoordCount = generateCoord ? generateCoordCount || 1 : 0;
- var extra = generateCoord || 'value';
- function ifNoNameFillWithCoordName(resultItem) {
- if (resultItem.name == null) {
- // Duplication will be removed in the next step.
- resultItem.name = resultItem.coordDim;
- }
- }
- // Set dim `name` and other `coordDim` and other props.
- if (!omitUnusedDimensions) {
- for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
- var resultItem = getResultItem(resultDimIdx);
- var coordDim = resultItem.coordDim;
- if (coordDim == null) {
- // TODO no need to generate coordDim for isExtraCoord?
- resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero);
- resultItem.coordDimIndex = 0;
- // Series specified generateCoord is using out.
- if (!generateCoord || generateCoordCount <= 0) {
- resultItem.isExtraCoord = true;
- }
- generateCoordCount--;
- }
- ifNoNameFillWithCoordName(resultItem);
- if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must
- // Consider the case:
- // {
- // dataset: {source: [
- // ['2001', 123],
- // ['2002', 456],
- // ...
- // ['The others', 987],
- // ]},
- // series: {type: 'pie'}
- // }
- // The first column should better be treated as a "ordinal" although it
- // might not be detected as an "ordinal" by `guessOrdinal`.
- || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {
- resultItem.type = 'ordinal';
- }
- }
- } else {
- each(resultList, function (resultItem) {
- // PENDING: guessOrdinal or let user specify type: 'ordinal' manually?
- ifNoNameFillWithCoordName(resultItem);
- });
- // Sort dimensions: there are some rule that use the last dim as label,
- // and for some latter travel process easier.
- resultList.sort(function (item0, item1) {
- return item0.storeDimIndex - item1.storeDimIndex;
- });
- }
- removeDuplication(resultList);
- return new SeriesDataSchema({
- source: source,
- dimensions: resultList,
- fullDimensionCount: dimCount,
- dimensionOmitted: omitUnusedDimensions
- });
- }
- function removeDuplication(result) {
- var duplicationMap = createHashMap();
- for (var i = 0; i < result.length; i++) {
- var dim = result[i];
- var dimOriginalName = dim.name;
- var count = duplicationMap.get(dimOriginalName) || 0;
- if (count > 0) {
- // Starts from 0.
- dim.name = dimOriginalName + (count - 1);
- }
- count++;
- duplicationMap.set(dimOriginalName, count);
- }
- }
- // ??? TODO
- // Originally detect dimCount by data[0]. Should we
- // optimize it to only by sysDims and dimensions and encode.
- // So only necessary dims will be initialized.
- // But
- // (1) custom series should be considered. where other dims
- // may be visited.
- // (2) sometimes user need to calculate bubble size or use visualMap
- // on other dimensions besides coordSys needed.
- // So, dims that is not used by system, should be shared in data store?
- function getDimCount(source, sysDims, dimsDef, optDimCount) {
- // Note that the result dimCount should not small than columns count
- // of data, otherwise `dataDimNameMap` checking will be incorrect.
- var dimCount = Math.max(source.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);
- each(sysDims, function (sysDimItem) {
- var sysDimItemDimsDef;
- if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) {
- dimCount = Math.max(dimCount, sysDimItemDimsDef.length);
- }
- });
- return dimCount;
- }
- function genCoordDimName(name, map, fromZero) {
- if (fromZero || map.hasKey(name)) {
- var i = 0;
- while (map.hasKey(name + i)) {
- i++;
- }
- name += i;
- }
- map.set(name, true);
- return name;
- }
|