pieLayout.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. var _number = require("../../util/number");
  2. var parsePercent = _number.parsePercent;
  3. var linearMap = _number.linearMap;
  4. var labelLayout = require("./labelLayout");
  5. var zrUtil = require("zrender/lib/core/util");
  6. var PI2 = Math.PI * 2;
  7. var RADIAN = Math.PI / 180;
  8. function _default(seriesType, ecModel, api, payload) {
  9. ecModel.eachSeriesByType(seriesType, function (seriesModel) {
  10. var center = seriesModel.get('center');
  11. var radius = seriesModel.get('radius');
  12. if (!zrUtil.isArray(radius)) {
  13. radius = [0, radius];
  14. }
  15. if (!zrUtil.isArray(center)) {
  16. center = [center, center];
  17. }
  18. var width = api.getWidth();
  19. var height = api.getHeight();
  20. var size = Math.min(width, height);
  21. var cx = parsePercent(center[0], width);
  22. var cy = parsePercent(center[1], height);
  23. var r0 = parsePercent(radius[0], size / 2);
  24. var r = parsePercent(radius[1], size / 2);
  25. var data = seriesModel.getData();
  26. var startAngle = -seriesModel.get('startAngle') * RADIAN;
  27. var minAngle = seriesModel.get('minAngle') * RADIAN;
  28. var validDataCount = 0;
  29. data.each('value', function (value) {
  30. !isNaN(value) && validDataCount++;
  31. });
  32. var sum = data.getSum('value'); // Sum may be 0
  33. var unitRadian = Math.PI / (sum || validDataCount) * 2;
  34. var clockwise = seriesModel.get('clockwise');
  35. var roseType = seriesModel.get('roseType');
  36. var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // [0...max]
  37. var extent = data.getDataExtent('value');
  38. extent[0] = 0; // In the case some sector angle is smaller than minAngle
  39. var restAngle = PI2;
  40. var valueSumLargerThanMinAngle = 0;
  41. var currentAngle = startAngle;
  42. var dir = clockwise ? 1 : -1;
  43. data.each('value', function (value, idx) {
  44. var angle;
  45. if (isNaN(value)) {
  46. data.setItemLayout(idx, {
  47. angle: NaN,
  48. startAngle: NaN,
  49. endAngle: NaN,
  50. clockwise: clockwise,
  51. cx: cx,
  52. cy: cy,
  53. r0: r0,
  54. r: roseType ? NaN : r
  55. });
  56. return;
  57. } // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样?
  58. if (roseType !== 'area') {
  59. angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
  60. } else {
  61. angle = PI2 / validDataCount;
  62. }
  63. if (angle < minAngle) {
  64. angle = minAngle;
  65. restAngle -= minAngle;
  66. } else {
  67. valueSumLargerThanMinAngle += value;
  68. }
  69. var endAngle = currentAngle + dir * angle;
  70. data.setItemLayout(idx, {
  71. angle: angle,
  72. startAngle: currentAngle,
  73. endAngle: endAngle,
  74. clockwise: clockwise,
  75. cx: cx,
  76. cy: cy,
  77. r0: r0,
  78. r: roseType ? linearMap(value, extent, [r0, r]) : r
  79. });
  80. currentAngle = endAngle;
  81. }, true); // Some sector is constrained by minAngle
  82. // Rest sectors needs recalculate angle
  83. if (restAngle < PI2 && validDataCount) {
  84. // Average the angle if rest angle is not enough after all angles is
  85. // Constrained by minAngle
  86. if (restAngle <= 1e-3) {
  87. var angle = PI2 / validDataCount;
  88. data.each('value', function (value, idx) {
  89. if (!isNaN(value)) {
  90. var layout = data.getItemLayout(idx);
  91. layout.angle = angle;
  92. layout.startAngle = startAngle + dir * idx * angle;
  93. layout.endAngle = startAngle + dir * (idx + 1) * angle;
  94. }
  95. });
  96. } else {
  97. unitRadian = restAngle / valueSumLargerThanMinAngle;
  98. currentAngle = startAngle;
  99. data.each('value', function (value, idx) {
  100. if (!isNaN(value)) {
  101. var layout = data.getItemLayout(idx);
  102. var angle = layout.angle === minAngle ? minAngle : value * unitRadian;
  103. layout.startAngle = currentAngle;
  104. layout.endAngle = currentAngle + dir * angle;
  105. currentAngle += dir * angle;
  106. }
  107. });
  108. }
  109. }
  110. labelLayout(seriesModel, r, width, height);
  111. });
  112. }
  113. module.exports = _default;