| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 | 
/** 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.*/var _util = require("zrender/lib/core/util");var createHashMap = _util.createHashMap;var each = _util.each;var isString = _util.isString;var defaults = _util.defaults;var extend = _util.extend;var isObject = _util.isObject;var clone = _util.clone;var _model = require("../../util/model");var normalizeToArray = _model.normalizeToArray;var _sourceHelper = require("./sourceHelper");var guessOrdinal = _sourceHelper.guessOrdinal;var BE_ORDINAL = _sourceHelper.BE_ORDINAL;var Source = require("../Source");var _dimensionHelper = require("./dimensionHelper");var OTHER_DIMENSIONS = _dimensionHelper.OTHER_DIMENSIONS;var DataDimensionInfo = require("../DataDimensionInfo");/** 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.*//** * @deprecated * Use `echarts/data/helper/createDimensions` instead. *//** * @see {module:echarts/test/ut/spec/data/completeDimensions} * * This method builds the relationship between: * + "what the coord sys or series requires (see `sysDims`)", * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)" * + "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'. * * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which *      provides not only dim template, but also default order. *      properties: 'name', 'type', 'displayName'. *      `name` of each item provides default coord name. *      [{dimsDef: [string|Object, ...]}, ...] dimsDef of sysDim item provides default dim name, and *                                    provide dims count that the sysDim required. *      [{ordinalMeta}] can be specified. * @param {module:echarts/data/Source|Array|Object} source or data (for compatibal with pervious) * @param {Object} [opt] * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions *      For example: ['asdf', {name, type}, ...]. * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3} * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists. *      If not specified, auto find the next available data dim. *      param source {module:data/Source} *      param dimCount {number} *      return {Object} encode Never be `null/undefined`. * @param {string} [opt.generateCoord] Generate coord dim with the given name. *      If not specified, extra dim names will be: *      'value', 'value0', 'value1', ... * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`. *      If `generateCoordCount` specified, the generated dim names will be: *      `generateCoord` + 0, `generateCoord` + 1, ... *      can be Infinity, indicate that use all of the remain columns. * @param {number} [opt.dimCount] If not specified, guess by the first data item. * @return {Array.<module:data/DataDimensionInfo>} */function completeDimensions(sysDims, source, opt) {  if (!Source.isInstance(source)) {    source = Source.seriesDataToSource(source);  }  opt = opt || {};  sysDims = (sysDims || []).slice();  var dimsDef = (opt.dimsDef || []).slice();  var dataDimNameMap = createHashMap();  var coordDimNameMap = createHashMap(); // var valueCandidate;  var result = [];  var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimCount); // Apply user defined dims (`name` and `type`) and init result.  for (var i = 0; i < dimCount; i++) {    var dimDefItem = dimsDef[i] = extend({}, isObject(dimsDef[i]) ? dimsDef[i] : {      name: dimsDef[i]    });    var userDimName = dimDefItem.name;    var resultItem = result[i] = new DataDimensionInfo(); // Name will be applied later for avoiding duplication.    if (userDimName != null && dataDimNameMap.get(userDimName) == null) {      // Only if `series.dimensions` is defined in option      // displayName, will be set, and dimension will be diplayed vertically in      // tooltip by default.      resultItem.name = resultItem.displayName = userDimName;      dataDimNameMap.set(userDimName, i);    }    dimDefItem.type != null && (resultItem.type = dimDefItem.type);    dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);  }  var encodeDef = opt.encodeDef;  if (!encodeDef && opt.encodeDefaulter) {    encodeDef = opt.encodeDefaulter(source, dimCount);  }  encodeDef = createHashMap(encodeDef); // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.  encodeDef.each(function (dataDims, coordDim) {    dataDims = normalizeToArray(dataDims).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) {      encodeDef.set(coordDim, false);      return;    }    var validDataDims = encodeDef.set(coordDim, []);    each(dataDims, function (resultDimIdx, idx) {      // The input resultDimIdx can be dim name or index.      isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));      if (resultDimIdx != null && resultDimIdx < dimCount) {        validDataDims[idx] = resultDimIdx;        applyDim(result[resultDimIdx], coordDim, idx);      }    });  }); // Apply templetes and default order from `sysDims`.  var availDimIdx = 0;  each(sysDims, function (sysDimItem, sysDimIndex) {    var coordDim;    var sysDimItem;    var sysDimItemDimsDef;    var sysDimItemOtherDims;    if (isString(sysDimItem)) {      coordDim = sysDimItem;      sysDimItem = {};    } else {      coordDim = sysDimItem.name;      var ordinalMeta = sysDimItem.ordinalMeta;      sysDimItem.ordinalMeta = null;      sysDimItem = clone(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 = encodeDef.get(coordDim); // negative resultDimIdx means no need to mapping.    if (dataDims === false) {      return;    }    var dataDims = normalizeToArray(dataDims); // dimensions provides default dim sequences.    if (!dataDims.length) {      for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {        while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {          availDimIdx++;        }        availDimIdx < result.length && dataDims.push(availDimIdx++);      }    } // Apply templates.    each(dataDims, function (resultDimIdx, coordDimIndex) {      var resultItem = result[resultDimIdx];      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 (OTHER_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'; // Set dim `name` and other `coordDim` and other props.  for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {    var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();    var coordDim = resultItem.coordDim;    if (coordDim == null) {      resultItem.coordDim = genName(extra, coordDimNameMap, fromZero);      resultItem.coordDimIndex = 0;      if (!generateCoord || generateCoordCount <= 0) {        resultItem.isExtraCoord = true;      }      generateCoordCount--;    }    resultItem.name == null && (resultItem.name = genName(resultItem.coordDim, dataDimNameMap));    if (resultItem.type == null && (guessOrdinal(source, resultDimIdx, resultItem.name) === BE_ORDINAL.Must // Consider the case:    // {    //    dataset: {source: [    //        ['2001', 123],    //        ['2002', 456],    //        ...    //        ['The others', 987],    //    ]},    //    series: {type: 'pie'}    // }    // The first colum should better be treated as a "ordinal" although it    // might not able to be detected as an "ordinal" by `guessOrdinal`.    || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {      resultItem.type = 'ordinal';    }  }  return result;} // ??? 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 calcualte bubble size or use visualMap// on other dimensions besides coordSys needed.// So, dims that is not used by system, should be shared in storage?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.dimensionsDetectCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);  each(sysDims, function (sysDimItem) {    var sysDimItemDimsDef = sysDimItem.dimsDef;    sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));  });  return dimCount;}function genName(name, map, fromZero) {  if (fromZero || map.get(name) != null) {    var i = 0;    while (map.get(name + i) != null) {      i++;    }    name += i;  }  map.set(name, true);  return name;}var _default = completeDimensions;module.exports = _default;
 |