pieLayout.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. /*
  23. * Licensed to the Apache Software Foundation (ASF) under one
  24. * or more contributor license agreements. See the NOTICE file
  25. * distributed with this work for additional information
  26. * regarding copyright ownership. The ASF licenses this file
  27. * to you under the Apache License, Version 2.0 (the
  28. * "License"); you may not use this file except in compliance
  29. * with the License. You may obtain a copy of the License at
  30. *
  31. * http://www.apache.org/licenses/LICENSE-2.0
  32. *
  33. * Unless required by applicable law or agreed to in writing,
  34. * software distributed under the License is distributed on an
  35. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  36. * KIND, either express or implied. See the License for the
  37. * specific language governing permissions and limitations
  38. * under the License.
  39. */
  40. import { linearMap } from '../../util/number.js';
  41. import { SERIES_TYPE_PIE } from './PieSeries.js';
  42. import { normalizeArcAngles } from 'zrender/lib/core/PathProxy.js';
  43. import { createSimpleOverallStageHandler, makeInner } from '../../util/model.js';
  44. import { getCircleLayout } from '../../util/layout.js';
  45. var PI2 = Math.PI * 2;
  46. var RADIAN = Math.PI / 180;
  47. export var pieLayoutStageHandler = createSimpleOverallStageHandler(SERIES_TYPE_PIE, pieLayout);
  48. function pieLayout(ecModel, api) {
  49. ecModel.eachSeriesByType(SERIES_TYPE_PIE, function (seriesModel) {
  50. var data = seriesModel.getData();
  51. var valueDim = data.mapDimension('value');
  52. var _a = getCircleLayout(seriesModel, api),
  53. cx = _a.cx,
  54. cy = _a.cy,
  55. r = _a.r,
  56. r0 = _a.r0,
  57. viewRect = _a.viewRect;
  58. var startAngle = -seriesModel.get('startAngle') * RADIAN;
  59. var endAngle = seriesModel.get('endAngle');
  60. var padAngle = seriesModel.get('padAngle') * RADIAN;
  61. endAngle = endAngle === 'auto' ? startAngle - PI2 : -endAngle * RADIAN;
  62. var minAngle = seriesModel.get('minAngle') * RADIAN;
  63. var minAndPadAngle = minAngle + padAngle;
  64. var validDataCount = 0;
  65. data.each(valueDim, function (value) {
  66. !isNaN(value) && validDataCount++;
  67. });
  68. var sum = data.getSum(valueDim);
  69. // Sum may be 0
  70. var unitRadian = Math.PI / (sum || validDataCount) * 2;
  71. var clockwise = seriesModel.get('clockwise');
  72. var roseType = seriesModel.get('roseType');
  73. var stillShowZeroSum = seriesModel.get('stillShowZeroSum');
  74. // [0...max]
  75. var extent = data.getDataExtent(valueDim);
  76. extent[0] = 0;
  77. var dir = clockwise ? 1 : -1;
  78. var angles = [startAngle, endAngle];
  79. var halfPadAngle = dir * padAngle / 2;
  80. normalizeArcAngles(angles, !clockwise);
  81. startAngle = angles[0], endAngle = angles[1];
  82. var layoutData = getSeriesLayoutData(seriesModel);
  83. layoutData.startAngle = startAngle;
  84. layoutData.endAngle = endAngle;
  85. layoutData.clockwise = clockwise;
  86. layoutData.cx = cx;
  87. layoutData.cy = cy;
  88. layoutData.r = r;
  89. layoutData.r0 = r0;
  90. var angleRange = Math.abs(endAngle - startAngle);
  91. // In the case some sector angle is smaller than minAngle
  92. var restAngle = angleRange;
  93. var valueSumLargerThanMinAngle = 0;
  94. var currentAngle = startAngle;
  95. // Requird by `pieLabelLayout`.
  96. data.setLayout({
  97. viewRect: viewRect,
  98. r: r
  99. });
  100. data.each(valueDim, function (value, idx) {
  101. var angle;
  102. if (isNaN(value)) {
  103. data.setItemLayout(idx, {
  104. angle: NaN,
  105. startAngle: NaN,
  106. endAngle: NaN,
  107. clockwise: clockwise,
  108. cx: cx,
  109. cy: cy,
  110. r0: r0,
  111. r: roseType ? NaN : r
  112. });
  113. return;
  114. }
  115. // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样?
  116. if (roseType !== 'area') {
  117. angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
  118. } else {
  119. angle = angleRange / validDataCount;
  120. }
  121. if (angle < minAndPadAngle) {
  122. angle = minAndPadAngle;
  123. restAngle -= minAndPadAngle;
  124. } else {
  125. valueSumLargerThanMinAngle += value;
  126. }
  127. var endAngle = currentAngle + dir * angle;
  128. // calculate display angle
  129. var actualStartAngle = 0;
  130. var actualEndAngle = 0;
  131. if (padAngle > angle) {
  132. actualStartAngle = currentAngle + dir * angle / 2;
  133. actualEndAngle = actualStartAngle;
  134. } else {
  135. actualStartAngle = currentAngle + halfPadAngle;
  136. actualEndAngle = endAngle - halfPadAngle;
  137. }
  138. data.setItemLayout(idx, {
  139. angle: angle,
  140. startAngle: actualStartAngle,
  141. endAngle: actualEndAngle,
  142. clockwise: clockwise,
  143. cx: cx,
  144. cy: cy,
  145. r0: r0,
  146. r: roseType ? linearMap(value, extent, [r0, r]) : r
  147. });
  148. currentAngle = endAngle;
  149. });
  150. // Some sector is constrained by minAngle and padAngle
  151. // Rest sectors needs recalculate angle
  152. if (restAngle < PI2 && validDataCount) {
  153. // Average the angle if rest angle is not enough after all angles is
  154. // Constrained by minAngle and padAngle
  155. if (restAngle <= 1e-3) {
  156. var angle_1 = angleRange / validDataCount;
  157. data.each(valueDim, function (value, idx) {
  158. if (!isNaN(value)) {
  159. var layout = data.getItemLayout(idx);
  160. layout.angle = angle_1;
  161. var actualStartAngle = 0;
  162. var actualEndAngle = 0;
  163. if (angle_1 < padAngle) {
  164. actualStartAngle = startAngle + dir * (idx + 1 / 2) * angle_1;
  165. actualEndAngle = actualStartAngle;
  166. } else {
  167. actualStartAngle = startAngle + dir * idx * angle_1 + halfPadAngle;
  168. actualEndAngle = startAngle + dir * (idx + 1) * angle_1 - halfPadAngle;
  169. }
  170. layout.startAngle = actualStartAngle;
  171. layout.endAngle = actualEndAngle;
  172. }
  173. });
  174. } else {
  175. unitRadian = restAngle / valueSumLargerThanMinAngle;
  176. currentAngle = startAngle;
  177. data.each(valueDim, function (value, idx) {
  178. if (!isNaN(value)) {
  179. var layout = data.getItemLayout(idx);
  180. var angle = layout.angle === minAndPadAngle ? minAndPadAngle : value * unitRadian;
  181. var actualStartAngle = 0;
  182. var actualEndAngle = 0;
  183. if (angle < padAngle) {
  184. actualStartAngle = currentAngle + dir * angle / 2;
  185. actualEndAngle = actualStartAngle;
  186. } else {
  187. actualStartAngle = currentAngle + halfPadAngle;
  188. actualEndAngle = currentAngle + dir * angle - halfPadAngle;
  189. }
  190. layout.startAngle = actualStartAngle;
  191. layout.endAngle = actualEndAngle;
  192. currentAngle += dir * angle;
  193. }
  194. });
  195. }
  196. }
  197. });
  198. }
  199. export var getSeriesLayoutData = makeInner();