|   | 
| /* | 
| * 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 { parsePercent, linearMap } from '../../util/number.js'; | 
| import * as layout from '../../util/layout.js'; | 
| import * as zrUtil from 'zrender/lib/core/util.js'; | 
| import { normalizeArcAngles } from 'zrender/lib/core/PathProxy.js'; | 
| import { makeInner } from '../../util/model.js'; | 
| var PI2 = Math.PI * 2; | 
| var RADIAN = Math.PI / 180; | 
| function getViewRect(seriesModel, api) { | 
|   return layout.getLayoutRect(seriesModel.getBoxLayoutParams(), { | 
|     width: api.getWidth(), | 
|     height: api.getHeight() | 
|   }); | 
| } | 
| export function getBasicPieLayout(seriesModel, api) { | 
|   var viewRect = getViewRect(seriesModel, api); | 
|   // center can be string or number when coordinateSystem is specified | 
|   var center = seriesModel.get('center'); | 
|   var radius = seriesModel.get('radius'); | 
|   if (!zrUtil.isArray(radius)) { | 
|     radius = [0, radius]; | 
|   } | 
|   var width = parsePercent(viewRect.width, api.getWidth()); | 
|   var height = parsePercent(viewRect.height, api.getHeight()); | 
|   var size = Math.min(width, height); | 
|   var r0 = parsePercent(radius[0], size / 2); | 
|   var r = parsePercent(radius[1], size / 2); | 
|   var cx; | 
|   var cy; | 
|   var coordSys = seriesModel.coordinateSystem; | 
|   if (coordSys) { | 
|     // percentage is not allowed when coordinate system is specified | 
|     var point = coordSys.dataToPoint(center); | 
|     cx = point[0] || 0; | 
|     cy = point[1] || 0; | 
|   } else { | 
|     if (!zrUtil.isArray(center)) { | 
|       center = [center, center]; | 
|     } | 
|     cx = parsePercent(center[0], width) + viewRect.x; | 
|     cy = parsePercent(center[1], height) + viewRect.y; | 
|   } | 
|   return { | 
|     cx: cx, | 
|     cy: cy, | 
|     r0: r0, | 
|     r: r | 
|   }; | 
| } | 
| export default function pieLayout(seriesType, ecModel, api) { | 
|   ecModel.eachSeriesByType(seriesType, function (seriesModel) { | 
|     var data = seriesModel.getData(); | 
|     var valueDim = data.mapDimension('value'); | 
|     var viewRect = getViewRect(seriesModel, api); | 
|     var _a = getBasicPieLayout(seriesModel, api), | 
|       cx = _a.cx, | 
|       cy = _a.cy, | 
|       r = _a.r, | 
|       r0 = _a.r0; | 
|     var startAngle = -seriesModel.get('startAngle') * RADIAN; | 
|     var endAngle = seriesModel.get('endAngle'); | 
|     var padAngle = seriesModel.get('padAngle') * RADIAN; | 
|     endAngle = endAngle === 'auto' ? startAngle - PI2 : -endAngle * RADIAN; | 
|     var minAngle = seriesModel.get('minAngle') * RADIAN; | 
|     var minAndPadAngle = minAngle + padAngle; | 
|     var validDataCount = 0; | 
|     data.each(valueDim, function (value) { | 
|       !isNaN(value) && validDataCount++; | 
|     }); | 
|     var sum = data.getSum(valueDim); | 
|     // Sum may be 0 | 
|     var unitRadian = Math.PI / (sum || validDataCount) * 2; | 
|     var clockwise = seriesModel.get('clockwise'); | 
|     var roseType = seriesModel.get('roseType'); | 
|     var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); | 
|     // [0...max] | 
|     var extent = data.getDataExtent(valueDim); | 
|     extent[0] = 0; | 
|     var dir = clockwise ? 1 : -1; | 
|     var angles = [startAngle, endAngle]; | 
|     var halfPadAngle = dir * padAngle / 2; | 
|     normalizeArcAngles(angles, !clockwise); | 
|     startAngle = angles[0], endAngle = angles[1]; | 
|     var layoutData = getSeriesLayoutData(seriesModel); | 
|     layoutData.startAngle = startAngle; | 
|     layoutData.endAngle = endAngle; | 
|     layoutData.clockwise = clockwise; | 
|     var angleRange = Math.abs(endAngle - startAngle); | 
|     // In the case some sector angle is smaller than minAngle | 
|     var restAngle = angleRange; | 
|     var valueSumLargerThanMinAngle = 0; | 
|     var currentAngle = startAngle; | 
|     data.setLayout({ | 
|       viewRect: viewRect, | 
|       r: r | 
|     }); | 
|     data.each(valueDim, function (value, idx) { | 
|       var angle; | 
|       if (isNaN(value)) { | 
|         data.setItemLayout(idx, { | 
|           angle: NaN, | 
|           startAngle: NaN, | 
|           endAngle: NaN, | 
|           clockwise: clockwise, | 
|           cx: cx, | 
|           cy: cy, | 
|           r0: r0, | 
|           r: roseType ? NaN : r | 
|         }); | 
|         return; | 
|       } | 
|       // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样? | 
|       if (roseType !== 'area') { | 
|         angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian; | 
|       } else { | 
|         angle = angleRange / validDataCount; | 
|       } | 
|       if (angle < minAndPadAngle) { | 
|         angle = minAndPadAngle; | 
|         restAngle -= minAndPadAngle; | 
|       } else { | 
|         valueSumLargerThanMinAngle += value; | 
|       } | 
|       var endAngle = currentAngle + dir * angle; | 
|       // calculate display angle | 
|       var actualStartAngle = 0; | 
|       var actualEndAngle = 0; | 
|       if (padAngle > angle) { | 
|         actualStartAngle = currentAngle + dir * angle / 2; | 
|         actualEndAngle = actualStartAngle; | 
|       } else { | 
|         actualStartAngle = currentAngle + halfPadAngle; | 
|         actualEndAngle = endAngle - halfPadAngle; | 
|       } | 
|       data.setItemLayout(idx, { | 
|         angle: angle, | 
|         startAngle: actualStartAngle, | 
|         endAngle: actualEndAngle, | 
|         clockwise: clockwise, | 
|         cx: cx, | 
|         cy: cy, | 
|         r0: r0, | 
|         r: roseType ? linearMap(value, extent, [r0, r]) : r | 
|       }); | 
|       currentAngle = endAngle; | 
|     }); | 
|     // Some sector is constrained by minAngle and padAngle | 
|     // Rest sectors needs recalculate angle | 
|     if (restAngle < PI2 && validDataCount) { | 
|       // Average the angle if rest angle is not enough after all angles is | 
|       // Constrained by minAngle and padAngle | 
|       if (restAngle <= 1e-3) { | 
|         var angle_1 = angleRange / validDataCount; | 
|         data.each(valueDim, function (value, idx) { | 
|           if (!isNaN(value)) { | 
|             var layout_1 = data.getItemLayout(idx); | 
|             layout_1.angle = angle_1; | 
|             var actualStartAngle = 0; | 
|             var actualEndAngle = 0; | 
|             if (angle_1 < padAngle) { | 
|               actualStartAngle = startAngle + dir * (idx + 1 / 2) * angle_1; | 
|               actualEndAngle = actualStartAngle; | 
|             } else { | 
|               actualStartAngle = startAngle + dir * idx * angle_1 + halfPadAngle; | 
|               actualEndAngle = startAngle + dir * (idx + 1) * angle_1 - halfPadAngle; | 
|             } | 
|             layout_1.startAngle = actualStartAngle; | 
|             layout_1.endAngle = actualEndAngle; | 
|           } | 
|         }); | 
|       } else { | 
|         unitRadian = restAngle / valueSumLargerThanMinAngle; | 
|         currentAngle = startAngle; | 
|         data.each(valueDim, function (value, idx) { | 
|           if (!isNaN(value)) { | 
|             var layout_2 = data.getItemLayout(idx); | 
|             var angle = layout_2.angle === minAndPadAngle ? minAndPadAngle : value * unitRadian; | 
|             var actualStartAngle = 0; | 
|             var actualEndAngle = 0; | 
|             if (angle < padAngle) { | 
|               actualStartAngle = currentAngle + dir * angle / 2; | 
|               actualEndAngle = actualStartAngle; | 
|             } else { | 
|               actualStartAngle = currentAngle + halfPadAngle; | 
|               actualEndAngle = currentAngle + dir * angle - halfPadAngle; | 
|             } | 
|             layout_2.startAngle = actualStartAngle; | 
|             layout_2.endAngle = actualEndAngle; | 
|             currentAngle += dir * angle; | 
|           } | 
|         }); | 
|       } | 
|     } | 
|   }); | 
| } | 
| export var getSeriesLayoutData = makeInner(); |