pieLayout.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. var _number = require("../../util/number");
  20. var parsePercent = _number.parsePercent;
  21. var linearMap = _number.linearMap;
  22. var layout = require("../../util/layout");
  23. var labelLayout = require("./labelLayout");
  24. var zrUtil = require("zrender/lib/core/util");
  25. /*
  26. * Licensed to the Apache Software Foundation (ASF) under one
  27. * or more contributor license agreements. See the NOTICE file
  28. * distributed with this work for additional information
  29. * regarding copyright ownership. The ASF licenses this file
  30. * to you under the Apache License, Version 2.0 (the
  31. * "License"); you may not use this file except in compliance
  32. * with the License. You may obtain a copy of the License at
  33. *
  34. * http://www.apache.org/licenses/LICENSE-2.0
  35. *
  36. * Unless required by applicable law or agreed to in writing,
  37. * software distributed under the License is distributed on an
  38. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  39. * KIND, either express or implied. See the License for the
  40. * specific language governing permissions and limitations
  41. * under the License.
  42. */
  43. var PI2 = Math.PI * 2;
  44. var RADIAN = Math.PI / 180;
  45. function getViewRect(seriesModel, api) {
  46. return layout.getLayoutRect(seriesModel.getBoxLayoutParams(), {
  47. width: api.getWidth(),
  48. height: api.getHeight()
  49. });
  50. }
  51. function _default(seriesType, ecModel, api, payload) {
  52. ecModel.eachSeriesByType(seriesType, function (seriesModel) {
  53. var data = seriesModel.getData();
  54. var valueDim = data.mapDimension('value');
  55. var viewRect = getViewRect(seriesModel, api);
  56. var center = seriesModel.get('center');
  57. var radius = seriesModel.get('radius');
  58. if (!zrUtil.isArray(radius)) {
  59. radius = [0, radius];
  60. }
  61. if (!zrUtil.isArray(center)) {
  62. center = [center, center];
  63. }
  64. var width = parsePercent(viewRect.width, api.getWidth());
  65. var height = parsePercent(viewRect.height, api.getHeight());
  66. var size = Math.min(width, height);
  67. var cx = parsePercent(center[0], width) + viewRect.x;
  68. var cy = parsePercent(center[1], height) + viewRect.y;
  69. var r0 = parsePercent(radius[0], size / 2);
  70. var r = parsePercent(radius[1], size / 2);
  71. var startAngle = -seriesModel.get('startAngle') * RADIAN;
  72. var minAngle = seriesModel.get('minAngle') * RADIAN;
  73. var validDataCount = 0;
  74. data.each(valueDim, function (value) {
  75. !isNaN(value) && validDataCount++;
  76. });
  77. var sum = data.getSum(valueDim); // Sum may be 0
  78. var unitRadian = Math.PI / (sum || validDataCount) * 2;
  79. var clockwise = seriesModel.get('clockwise');
  80. var roseType = seriesModel.get('roseType');
  81. var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // [0...max]
  82. var extent = data.getDataExtent(valueDim);
  83. extent[0] = 0; // In the case some sector angle is smaller than minAngle
  84. var restAngle = PI2;
  85. var valueSumLargerThanMinAngle = 0;
  86. var currentAngle = startAngle;
  87. var dir = clockwise ? 1 : -1;
  88. data.each(valueDim, function (value, idx) {
  89. var angle;
  90. if (isNaN(value)) {
  91. data.setItemLayout(idx, {
  92. angle: NaN,
  93. startAngle: NaN,
  94. endAngle: NaN,
  95. clockwise: clockwise,
  96. cx: cx,
  97. cy: cy,
  98. r0: r0,
  99. r: roseType ? NaN : r,
  100. viewRect: viewRect
  101. });
  102. return;
  103. } // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样?
  104. if (roseType !== 'area') {
  105. angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
  106. } else {
  107. angle = PI2 / validDataCount;
  108. }
  109. if (angle < minAngle) {
  110. angle = minAngle;
  111. restAngle -= minAngle;
  112. } else {
  113. valueSumLargerThanMinAngle += value;
  114. }
  115. var endAngle = currentAngle + dir * angle;
  116. data.setItemLayout(idx, {
  117. angle: angle,
  118. startAngle: currentAngle,
  119. endAngle: endAngle,
  120. clockwise: clockwise,
  121. cx: cx,
  122. cy: cy,
  123. r0: r0,
  124. r: roseType ? linearMap(value, extent, [r0, r]) : r,
  125. viewRect: viewRect
  126. });
  127. currentAngle = endAngle;
  128. }); // Some sector is constrained by minAngle
  129. // Rest sectors needs recalculate angle
  130. if (restAngle < PI2 && validDataCount) {
  131. // Average the angle if rest angle is not enough after all angles is
  132. // Constrained by minAngle
  133. if (restAngle <= 1e-3) {
  134. var angle = PI2 / validDataCount;
  135. data.each(valueDim, function (value, idx) {
  136. if (!isNaN(value)) {
  137. var layout = data.getItemLayout(idx);
  138. layout.angle = angle;
  139. layout.startAngle = startAngle + dir * idx * angle;
  140. layout.endAngle = startAngle + dir * (idx + 1) * angle;
  141. }
  142. });
  143. } else {
  144. unitRadian = restAngle / valueSumLargerThanMinAngle;
  145. currentAngle = startAngle;
  146. data.each(valueDim, function (value, idx) {
  147. if (!isNaN(value)) {
  148. var layout = data.getItemLayout(idx);
  149. var angle = layout.angle === minAngle ? minAngle : value * unitRadian;
  150. layout.startAngle = currentAngle;
  151. layout.endAngle = currentAngle + dir * angle;
  152. currentAngle += dir * angle;
  153. }
  154. });
  155. }
  156. }
  157. labelLayout(seriesModel, r, viewRect.width, viewRect.height, viewRect.x, viewRect.y);
  158. });
  159. }
  160. module.exports = _default;