|   | 
| /* | 
| * 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. | 
| */ | 
| /** | 
|  * Parallel Coordinates | 
|  * <https://en.wikipedia.org/wiki/Parallel_coordinates> | 
|  */ | 
| import * as zrUtil from 'zrender/lib/core/util.js'; | 
| import * as matrix from 'zrender/lib/core/matrix.js'; | 
| import * as layoutUtil from '../../util/layout.js'; | 
| import * as axisHelper from '../../coord/axisHelper.js'; | 
| import ParallelAxis from './ParallelAxis.js'; | 
| import * as graphic from '../../util/graphic.js'; | 
| import * as numberUtil from '../../util/number.js'; | 
| import sliderMove from '../../component/helper/sliderMove.js'; | 
| var each = zrUtil.each; | 
| var mathMin = Math.min; | 
| var mathMax = Math.max; | 
| var mathFloor = Math.floor; | 
| var mathCeil = Math.ceil; | 
| var round = numberUtil.round; | 
| var PI = Math.PI; | 
| var Parallel = /** @class */function () { | 
|   function Parallel(parallelModel, ecModel, api) { | 
|     this.type = 'parallel'; | 
|     /** | 
|      * key: dimension | 
|      */ | 
|     this._axesMap = zrUtil.createHashMap(); | 
|     /** | 
|      * key: dimension | 
|      * value: {position: [], rotation, } | 
|      */ | 
|     this._axesLayout = {}; | 
|     this.dimensions = parallelModel.dimensions; | 
|     this._model = parallelModel; | 
|     this._init(parallelModel, ecModel, api); | 
|   } | 
|   Parallel.prototype._init = function (parallelModel, ecModel, api) { | 
|     var dimensions = parallelModel.dimensions; | 
|     var parallelAxisIndex = parallelModel.parallelAxisIndex; | 
|     each(dimensions, function (dim, idx) { | 
|       var axisIndex = parallelAxisIndex[idx]; | 
|       var axisModel = ecModel.getComponent('parallelAxis', axisIndex); | 
|       var axis = this._axesMap.set(dim, new ParallelAxis(dim, axisHelper.createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisIndex)); | 
|       var isCategory = axis.type === 'category'; | 
|       axis.onBand = isCategory && axisModel.get('boundaryGap'); | 
|       axis.inverse = axisModel.get('inverse'); | 
|       // Injection | 
|       axisModel.axis = axis; | 
|       axis.model = axisModel; | 
|       axis.coordinateSystem = axisModel.coordinateSystem = this; | 
|     }, this); | 
|   }; | 
|   /** | 
|    * Update axis scale after data processed | 
|    */ | 
|   Parallel.prototype.update = function (ecModel, api) { | 
|     this._updateAxesFromSeries(this._model, ecModel); | 
|   }; | 
|   Parallel.prototype.containPoint = function (point) { | 
|     var layoutInfo = this._makeLayoutInfo(); | 
|     var axisBase = layoutInfo.axisBase; | 
|     var layoutBase = layoutInfo.layoutBase; | 
|     var pixelDimIndex = layoutInfo.pixelDimIndex; | 
|     var pAxis = point[1 - pixelDimIndex]; | 
|     var pLayout = point[pixelDimIndex]; | 
|     return pAxis >= axisBase && pAxis <= axisBase + layoutInfo.axisLength && pLayout >= layoutBase && pLayout <= layoutBase + layoutInfo.layoutLength; | 
|   }; | 
|   Parallel.prototype.getModel = function () { | 
|     return this._model; | 
|   }; | 
|   /** | 
|    * Update properties from series | 
|    */ | 
|   Parallel.prototype._updateAxesFromSeries = function (parallelModel, ecModel) { | 
|     ecModel.eachSeries(function (seriesModel) { | 
|       if (!parallelModel.contains(seriesModel, ecModel)) { | 
|         return; | 
|       } | 
|       var data = seriesModel.getData(); | 
|       each(this.dimensions, function (dim) { | 
|         var axis = this._axesMap.get(dim); | 
|         axis.scale.unionExtentFromData(data, data.mapDimension(dim)); | 
|         axisHelper.niceScaleExtent(axis.scale, axis.model); | 
|       }, this); | 
|     }, this); | 
|   }; | 
|   /** | 
|    * Resize the parallel coordinate system. | 
|    */ | 
|   Parallel.prototype.resize = function (parallelModel, api) { | 
|     this._rect = layoutUtil.getLayoutRect(parallelModel.getBoxLayoutParams(), { | 
|       width: api.getWidth(), | 
|       height: api.getHeight() | 
|     }); | 
|     this._layoutAxes(); | 
|   }; | 
|   Parallel.prototype.getRect = function () { | 
|     return this._rect; | 
|   }; | 
|   Parallel.prototype._makeLayoutInfo = function () { | 
|     var parallelModel = this._model; | 
|     var rect = this._rect; | 
|     var xy = ['x', 'y']; | 
|     var wh = ['width', 'height']; | 
|     var layout = parallelModel.get('layout'); | 
|     var pixelDimIndex = layout === 'horizontal' ? 0 : 1; | 
|     var layoutLength = rect[wh[pixelDimIndex]]; | 
|     var layoutExtent = [0, layoutLength]; | 
|     var axisCount = this.dimensions.length; | 
|     var axisExpandWidth = restrict(parallelModel.get('axisExpandWidth'), layoutExtent); | 
|     var axisExpandCount = restrict(parallelModel.get('axisExpandCount') || 0, [0, axisCount]); | 
|     var axisExpandable = parallelModel.get('axisExpandable') && axisCount > 3 && axisCount > axisExpandCount && axisExpandCount > 1 && axisExpandWidth > 0 && layoutLength > 0; | 
|     // `axisExpandWindow` is According to the coordinates of [0, axisExpandLength], | 
|     // for sake of consider the case that axisCollapseWidth is 0 (when screen is narrow), | 
|     // where collapsed axes should be overlapped. | 
|     var axisExpandWindow = parallelModel.get('axisExpandWindow'); | 
|     var winSize; | 
|     if (!axisExpandWindow) { | 
|       winSize = restrict(axisExpandWidth * (axisExpandCount - 1), layoutExtent); | 
|       var axisExpandCenter = parallelModel.get('axisExpandCenter') || mathFloor(axisCount / 2); | 
|       axisExpandWindow = [axisExpandWidth * axisExpandCenter - winSize / 2]; | 
|       axisExpandWindow[1] = axisExpandWindow[0] + winSize; | 
|     } else { | 
|       winSize = restrict(axisExpandWindow[1] - axisExpandWindow[0], layoutExtent); | 
|       axisExpandWindow[1] = axisExpandWindow[0] + winSize; | 
|     } | 
|     var axisCollapseWidth = (layoutLength - winSize) / (axisCount - axisExpandCount); | 
|     // Avoid axisCollapseWidth is too small. | 
|     axisCollapseWidth < 3 && (axisCollapseWidth = 0); | 
|     // Find the first and last indices > ewin[0] and < ewin[1]. | 
|     var winInnerIndices = [mathFloor(round(axisExpandWindow[0] / axisExpandWidth, 1)) + 1, mathCeil(round(axisExpandWindow[1] / axisExpandWidth, 1)) - 1]; | 
|     // Pos in ec coordinates. | 
|     var axisExpandWindow0Pos = axisCollapseWidth / axisExpandWidth * axisExpandWindow[0]; | 
|     return { | 
|       layout: layout, | 
|       pixelDimIndex: pixelDimIndex, | 
|       layoutBase: rect[xy[pixelDimIndex]], | 
|       layoutLength: layoutLength, | 
|       axisBase: rect[xy[1 - pixelDimIndex]], | 
|       axisLength: rect[wh[1 - pixelDimIndex]], | 
|       axisExpandable: axisExpandable, | 
|       axisExpandWidth: axisExpandWidth, | 
|       axisCollapseWidth: axisCollapseWidth, | 
|       axisExpandWindow: axisExpandWindow, | 
|       axisCount: axisCount, | 
|       winInnerIndices: winInnerIndices, | 
|       axisExpandWindow0Pos: axisExpandWindow0Pos | 
|     }; | 
|   }; | 
|   Parallel.prototype._layoutAxes = function () { | 
|     var rect = this._rect; | 
|     var axes = this._axesMap; | 
|     var dimensions = this.dimensions; | 
|     var layoutInfo = this._makeLayoutInfo(); | 
|     var layout = layoutInfo.layout; | 
|     axes.each(function (axis) { | 
|       var axisExtent = [0, layoutInfo.axisLength]; | 
|       var idx = axis.inverse ? 1 : 0; | 
|       axis.setExtent(axisExtent[idx], axisExtent[1 - idx]); | 
|     }); | 
|     each(dimensions, function (dim, idx) { | 
|       var posInfo = (layoutInfo.axisExpandable ? layoutAxisWithExpand : layoutAxisWithoutExpand)(idx, layoutInfo); | 
|       var positionTable = { | 
|         horizontal: { | 
|           x: posInfo.position, | 
|           y: layoutInfo.axisLength | 
|         }, | 
|         vertical: { | 
|           x: 0, | 
|           y: posInfo.position | 
|         } | 
|       }; | 
|       var rotationTable = { | 
|         horizontal: PI / 2, | 
|         vertical: 0 | 
|       }; | 
|       var position = [positionTable[layout].x + rect.x, positionTable[layout].y + rect.y]; | 
|       var rotation = rotationTable[layout]; | 
|       var transform = matrix.create(); | 
|       matrix.rotate(transform, transform, rotation); | 
|       matrix.translate(transform, transform, position); | 
|       // TODO | 
|       // tick layout info | 
|       // TODO | 
|       // update dimensions info based on axis order. | 
|       this._axesLayout[dim] = { | 
|         position: position, | 
|         rotation: rotation, | 
|         transform: transform, | 
|         axisNameAvailableWidth: posInfo.axisNameAvailableWidth, | 
|         axisLabelShow: posInfo.axisLabelShow, | 
|         nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth, | 
|         tickDirection: 1, | 
|         labelDirection: 1 | 
|       }; | 
|     }, this); | 
|   }; | 
|   /** | 
|    * Get axis by dim. | 
|    */ | 
|   Parallel.prototype.getAxis = function (dim) { | 
|     return this._axesMap.get(dim); | 
|   }; | 
|   /** | 
|    * Convert a dim value of a single item of series data to Point. | 
|    */ | 
|   Parallel.prototype.dataToPoint = function (value, dim) { | 
|     return this.axisCoordToPoint(this._axesMap.get(dim).dataToCoord(value), dim); | 
|   }; | 
|   /** | 
|    * Travel data for one time, get activeState of each data item. | 
|    * @param start the start dataIndex that travel from. | 
|    * @param end the next dataIndex of the last dataIndex will be travel. | 
|    */ | 
|   Parallel.prototype.eachActiveState = function (data, callback, start, end) { | 
|     start == null && (start = 0); | 
|     end == null && (end = data.count()); | 
|     var axesMap = this._axesMap; | 
|     var dimensions = this.dimensions; | 
|     var dataDimensions = []; | 
|     var axisModels = []; | 
|     zrUtil.each(dimensions, function (axisDim) { | 
|       dataDimensions.push(data.mapDimension(axisDim)); | 
|       axisModels.push(axesMap.get(axisDim).model); | 
|     }); | 
|     var hasActiveSet = this.hasAxisBrushed(); | 
|     for (var dataIndex = start; dataIndex < end; dataIndex++) { | 
|       var activeState = void 0; | 
|       if (!hasActiveSet) { | 
|         activeState = 'normal'; | 
|       } else { | 
|         activeState = 'active'; | 
|         var values = data.getValues(dataDimensions, dataIndex); | 
|         for (var j = 0, lenj = dimensions.length; j < lenj; j++) { | 
|           var state = axisModels[j].getActiveState(values[j]); | 
|           if (state === 'inactive') { | 
|             activeState = 'inactive'; | 
|             break; | 
|           } | 
|         } | 
|       } | 
|       callback(activeState, dataIndex); | 
|     } | 
|   }; | 
|   /** | 
|    * Whether has any activeSet. | 
|    */ | 
|   Parallel.prototype.hasAxisBrushed = function () { | 
|     var dimensions = this.dimensions; | 
|     var axesMap = this._axesMap; | 
|     var hasActiveSet = false; | 
|     for (var j = 0, lenj = dimensions.length; j < lenj; j++) { | 
|       if (axesMap.get(dimensions[j]).model.getActiveState() !== 'normal') { | 
|         hasActiveSet = true; | 
|       } | 
|     } | 
|     return hasActiveSet; | 
|   }; | 
|   /** | 
|    * Convert coords of each axis to Point. | 
|    *  Return point. For example: [10, 20] | 
|    */ | 
|   Parallel.prototype.axisCoordToPoint = function (coord, dim) { | 
|     var axisLayout = this._axesLayout[dim]; | 
|     return graphic.applyTransform([coord, 0], axisLayout.transform); | 
|   }; | 
|   /** | 
|    * Get axis layout. | 
|    */ | 
|   Parallel.prototype.getAxisLayout = function (dim) { | 
|     return zrUtil.clone(this._axesLayout[dim]); | 
|   }; | 
|   /** | 
|    * @return {Object} {axisExpandWindow, delta, behavior: 'jump' | 'slide' | 'none'}. | 
|    */ | 
|   Parallel.prototype.getSlidedAxisExpandWindow = function (point) { | 
|     var layoutInfo = this._makeLayoutInfo(); | 
|     var pixelDimIndex = layoutInfo.pixelDimIndex; | 
|     var axisExpandWindow = layoutInfo.axisExpandWindow.slice(); | 
|     var winSize = axisExpandWindow[1] - axisExpandWindow[0]; | 
|     var extent = [0, layoutInfo.axisExpandWidth * (layoutInfo.axisCount - 1)]; | 
|     // Out of the area of coordinate system. | 
|     if (!this.containPoint(point)) { | 
|       return { | 
|         behavior: 'none', | 
|         axisExpandWindow: axisExpandWindow | 
|       }; | 
|     } | 
|     // Convert the point from global to expand coordinates. | 
|     var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos; | 
|     // For dragging operation convenience, the window should not be | 
|     // slided when mouse is the center area of the window. | 
|     var delta; | 
|     var behavior = 'slide'; | 
|     var axisCollapseWidth = layoutInfo.axisCollapseWidth; | 
|     var triggerArea = this._model.get('axisExpandSlideTriggerArea'); | 
|     // But consider touch device, jump is necessary. | 
|     var useJump = triggerArea[0] != null; | 
|     if (axisCollapseWidth) { | 
|       if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) { | 
|         behavior = 'jump'; | 
|         delta = pointCoord - winSize * triggerArea[2]; | 
|       } else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) { | 
|         behavior = 'jump'; | 
|         delta = pointCoord - winSize * (1 - triggerArea[2]); | 
|       } else { | 
|         (delta = pointCoord - winSize * triggerArea[1]) >= 0 && (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0 && (delta = 0); | 
|       } | 
|       delta *= layoutInfo.axisExpandWidth / axisCollapseWidth; | 
|       delta ? sliderMove(delta, axisExpandWindow, extent, 'all') | 
|       // Avoid nonsense triger on mousemove. | 
|       : behavior = 'none'; | 
|     } | 
|     // When screen is too narrow, make it visible and slidable, although it is hard to interact. | 
|     else { | 
|       var winSize2 = axisExpandWindow[1] - axisExpandWindow[0]; | 
|       var pos = extent[1] * pointCoord / winSize2; | 
|       axisExpandWindow = [mathMax(0, pos - winSize2 / 2)]; | 
|       axisExpandWindow[1] = mathMin(extent[1], axisExpandWindow[0] + winSize2); | 
|       axisExpandWindow[0] = axisExpandWindow[1] - winSize2; | 
|     } | 
|     return { | 
|       axisExpandWindow: axisExpandWindow, | 
|       behavior: behavior | 
|     }; | 
|   }; | 
|   return Parallel; | 
| }(); | 
| function restrict(len, extent) { | 
|   return mathMin(mathMax(len, extent[0]), extent[1]); | 
| } | 
| function layoutAxisWithoutExpand(axisIndex, layoutInfo) { | 
|   var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1); | 
|   return { | 
|     position: step * axisIndex, | 
|     axisNameAvailableWidth: step, | 
|     axisLabelShow: true | 
|   }; | 
| } | 
| function layoutAxisWithExpand(axisIndex, layoutInfo) { | 
|   var layoutLength = layoutInfo.layoutLength; | 
|   var axisExpandWidth = layoutInfo.axisExpandWidth; | 
|   var axisCount = layoutInfo.axisCount; | 
|   var axisCollapseWidth = layoutInfo.axisCollapseWidth; | 
|   var winInnerIndices = layoutInfo.winInnerIndices; | 
|   var position; | 
|   var axisNameAvailableWidth = axisCollapseWidth; | 
|   var axisLabelShow = false; | 
|   var nameTruncateMaxWidth; | 
|   if (axisIndex < winInnerIndices[0]) { | 
|     position = axisIndex * axisCollapseWidth; | 
|     nameTruncateMaxWidth = axisCollapseWidth; | 
|   } else if (axisIndex <= winInnerIndices[1]) { | 
|     position = layoutInfo.axisExpandWindow0Pos + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0]; | 
|     axisNameAvailableWidth = axisExpandWidth; | 
|     axisLabelShow = true; | 
|   } else { | 
|     position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth; | 
|     nameTruncateMaxWidth = axisCollapseWidth; | 
|   } | 
|   return { | 
|     position: position, | 
|     axisNameAvailableWidth: axisNameAvailableWidth, | 
|     axisLabelShow: axisLabelShow, | 
|     nameTruncateMaxWidth: nameTruncateMaxWidth | 
|   }; | 
| } | 
| export default Parallel; |