|   | 
| /* | 
| * 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 * as zrUtil from 'zrender/lib/core/util.js'; | 
| import * as numberUtil from '../../util/number.js'; | 
| export default function themeRiverLayout(ecModel, api) { | 
|   ecModel.eachSeriesByType('themeRiver', function (seriesModel) { | 
|     var data = seriesModel.getData(); | 
|     var single = seriesModel.coordinateSystem; | 
|     var layoutInfo = {}; // use the axis boundingRect for view | 
|   | 
|     var rect = single.getRect(); | 
|     layoutInfo.rect = rect; | 
|     var boundaryGap = seriesModel.get('boundaryGap'); | 
|     var axis = single.getAxis(); | 
|     layoutInfo.boundaryGap = boundaryGap; | 
|   | 
|     if (axis.orient === 'horizontal') { | 
|       boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], rect.height); | 
|       boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], rect.height); | 
|       var height = rect.height - boundaryGap[0] - boundaryGap[1]; | 
|       doThemeRiverLayout(data, seriesModel, height); | 
|     } else { | 
|       boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], rect.width); | 
|       boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], rect.width); | 
|       var width = rect.width - boundaryGap[0] - boundaryGap[1]; | 
|       doThemeRiverLayout(data, seriesModel, width); | 
|     } | 
|   | 
|     data.setLayout('layoutInfo', layoutInfo); | 
|   }); | 
| } | 
| /** | 
|  * The layout information about themeriver | 
|  * | 
|  * @param data  data in the series | 
|  * @param seriesModel  the model object of themeRiver series | 
|  * @param height  value used to compute every series height | 
|  */ | 
|   | 
| function doThemeRiverLayout(data, seriesModel, height) { | 
|   if (!data.count()) { | 
|     return; | 
|   } | 
|   | 
|   var coordSys = seriesModel.coordinateSystem; // the data in each layer are organized into a series. | 
|   | 
|   var layerSeries = seriesModel.getLayerSeries(); // the points in each layer. | 
|   | 
|   var timeDim = data.mapDimension('single'); | 
|   var valueDim = data.mapDimension('value'); | 
|   var layerPoints = zrUtil.map(layerSeries, function (singleLayer) { | 
|     return zrUtil.map(singleLayer.indices, function (idx) { | 
|       var pt = coordSys.dataToPoint(data.get(timeDim, idx)); | 
|       pt[1] = data.get(valueDim, idx); | 
|       return pt; | 
|     }); | 
|   }); | 
|   var base = computeBaseline(layerPoints); | 
|   var baseLine = base.y0; | 
|   var ky = height / base.max; // set layout information for each item. | 
|   | 
|   var n = layerSeries.length; | 
|   var m = layerSeries[0].indices.length; | 
|   var baseY0; | 
|   | 
|   for (var j = 0; j < m; ++j) { | 
|     baseY0 = baseLine[j] * ky; | 
|     data.setItemLayout(layerSeries[0].indices[j], { | 
|       layerIndex: 0, | 
|       x: layerPoints[0][j][0], | 
|       y0: baseY0, | 
|       y: layerPoints[0][j][1] * ky | 
|     }); | 
|   | 
|     for (var i = 1; i < n; ++i) { | 
|       baseY0 += layerPoints[i - 1][j][1] * ky; | 
|       data.setItemLayout(layerSeries[i].indices[j], { | 
|         layerIndex: i, | 
|         x: layerPoints[i][j][0], | 
|         y0: baseY0, | 
|         y: layerPoints[i][j][1] * ky | 
|       }); | 
|     } | 
|   } | 
| } | 
| /** | 
|  * Compute the baseLine of the rawdata | 
|  * Inspired by Lee Byron's paper Stacked Graphs - Geometry & Aesthetics | 
|  * | 
|  * @param  data  the points in each layer | 
|  */ | 
|   | 
|   | 
| function computeBaseline(data) { | 
|   var layerNum = data.length; | 
|   var pointNum = data[0].length; | 
|   var sums = []; | 
|   var y0 = []; | 
|   var max = 0; | 
|   | 
|   for (var i = 0; i < pointNum; ++i) { | 
|     var temp = 0; | 
|   | 
|     for (var j = 0; j < layerNum; ++j) { | 
|       temp += data[j][i][1]; | 
|     } | 
|   | 
|     if (temp > max) { | 
|       max = temp; | 
|     } | 
|   | 
|     sums.push(temp); | 
|   } | 
|   | 
|   for (var k = 0; k < pointNum; ++k) { | 
|     y0[k] = (max - sums[k]) / 2; | 
|   } | 
|   | 
|   max = 0; | 
|   | 
|   for (var l = 0; l < pointNum; ++l) { | 
|     var sum = sums[l] + y0[l]; | 
|   | 
|     if (sum > max) { | 
|       max = sum; | 
|     } | 
|   } | 
|   | 
|   return { | 
|     y0: y0, | 
|     max: max | 
|   }; | 
| } |