define(function (require) { var zrUtil = require('zrender/core/util'); var numberUtil = require('../../util/number'); var indexOf = zrUtil.indexOf; function getPrecision(data, valueAxisDim, dataIndex) { var precision = -1; do { precision = Math.max( numberUtil.getPrecision(data.get( valueAxisDim, dataIndex )), precision ); data = data.stackedOn; } while (data); return precision; } function markerTypeCalculatorWithExtent( mlType, data, baseDataDim, valueDataDim, baseCoordIndex, valueCoordIndex ) { var coordArr = []; var value = numCalculate(data, valueDataDim, mlType); var dataIndex = data.indexOfNearest(valueDataDim, value, true); coordArr[baseCoordIndex] = data.get(baseDataDim, dataIndex, true); coordArr[valueCoordIndex] = data.get(valueDataDim, dataIndex, true); var precision = getPrecision(data, valueDataDim, dataIndex); if (precision >= 0) { coordArr[valueCoordIndex] = +coordArr[valueCoordIndex].toFixed(precision); } return coordArr; } var curry = zrUtil.curry; // TODO Specified percent var markerTypeCalculator = { /** * @method * @param {module:echarts/data/List} data * @param {string} baseAxisDim * @param {string} valueAxisDim */ min: curry(markerTypeCalculatorWithExtent, 'min'), /** * @method * @param {module:echarts/data/List} data * @param {string} baseAxisDim * @param {string} valueAxisDim */ max: curry(markerTypeCalculatorWithExtent, 'max'), /** * @method * @param {module:echarts/data/List} data * @param {string} baseAxisDim * @param {string} valueAxisDim */ average: curry(markerTypeCalculatorWithExtent, 'average') }; /** * Transform markPoint data item to format used in List by do the following * 1. Calculate statistic like `max`, `min`, `average` * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array * @param {module:echarts/model/Series} seriesModel * @param {module:echarts/coord/*} [coordSys] * @param {Object} item * @return {Object} */ var dataTransform = function (seriesModel, item) { var data = seriesModel.getData(); var coordSys = seriesModel.coordinateSystem; // 1. If not specify the position with pixel directly // 2. If `coord` is not a data array. Which uses `xAxis`, // `yAxis` to specify the coord on each dimension // parseFloat first because item.x and item.y can be percent string like '20%' if (item && (isNaN(parseFloat(item.x)) || isNaN(parseFloat(item.y))) && !zrUtil.isArray(item.coord) && coordSys ) { var axisInfo = getAxisInfo(item, data, coordSys, seriesModel); // Clone the option // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value item = zrUtil.clone(item); if (item.type && markerTypeCalculator[item.type] && axisInfo.baseAxis && axisInfo.valueAxis ) { var dims = coordSys.dimensions; var baseCoordIndex = indexOf(dims, axisInfo.baseAxis.dim); var valueCoordIndex = indexOf(dims, axisInfo.valueAxis.dim); item.coord = markerTypeCalculator[item.type]( data, axisInfo.baseDataDim, axisInfo.valueDataDim, baseCoordIndex, valueCoordIndex ); // Force to use the value of calculated value. item.value = item.coord[valueCoordIndex]; } else { // FIXME Only has one of xAxis and yAxis. item.coord = [ item.xAxis != null ? item.xAxis : item.radiusAxis, item.yAxis != null ? item.yAxis : item.angleAxis ]; } } return item; }; var getAxisInfo = function (item, data, coordSys, seriesModel) { var ret = {}; if (item.valueIndex != null || item.valueDim != null) { ret.valueDataDim = item.valueIndex != null ? data.getDimension(item.valueIndex) : item.valueDim; ret.valueAxis = coordSys.getAxis(seriesModel.dataDimToCoordDim(ret.valueDataDim)); ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis); ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0]; } else { ret.baseAxis = seriesModel.getBaseAxis(); ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis); ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0]; ret.valueDataDim = seriesModel.coordDimToDataDim(ret.valueAxis.dim)[0]; } return ret; }; /** * Filter data which is out of coordinateSystem range * [dataFilter description] * @param {module:echarts/coord/*} [coordSys] * @param {Object} item * @return {boolean} */ var dataFilter = function (coordSys, item) { // Alwalys return true if there is no coordSys return (coordSys && coordSys.containData && item.coord && (item.x == null || item.y == null)) ? coordSys.containData(item.coord) : true; }; var dimValueGetter = function (item, dimName, dataIndex, dimIndex) { // x, y, radius, angle if (dimIndex < 2) { return item.coord && item.coord[dimIndex]; } return item.value; }; var numCalculate = function (data, valueDataDim, mlType) { return mlType === 'average' ? data.getSum(valueDataDim, true) / data.count() : data.getDataExtent(valueDataDim, true)[mlType === 'max' ? 1 : 0]; }; return { dataTransform: dataTransform, dataFilter: dataFilter, dimValueGetter: dimValueGetter, getAxisInfo: getAxisInfo, numCalculate: numCalculate }; });