| 
/* 
 | 
* 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; 
 | 
} 
 |