interval.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import Vector2 from '../../graphic/util/vector2';
  2. import Global from '../../global';
  3. import Shape from './shape';
  4. import { mix, isArray } from '../../util/common';
  5. function getRectPoints(cfg) {
  6. var {
  7. x,
  8. y,
  9. y0,
  10. size
  11. } = cfg;
  12. var ymin = y0;
  13. var ymax = y;
  14. if (isArray(y)) {
  15. ymax = y[1];
  16. ymin = y[0];
  17. }
  18. var xmin;
  19. var xmax;
  20. if (isArray(x)) {
  21. xmin = x[0];
  22. xmax = x[1];
  23. } else {
  24. xmin = x - size / 2;
  25. xmax = x + size / 2;
  26. }
  27. return [{
  28. x: xmin,
  29. y: ymin
  30. }, {
  31. x: xmin,
  32. y: ymax
  33. }, {
  34. x: xmax,
  35. y: ymax
  36. }, {
  37. x: xmax,
  38. y: ymin
  39. }];
  40. }
  41. function getRectRange(points) {
  42. var xValues = [];
  43. var yValues = [];
  44. for (var i = 0, len = points.length; i < len; i++) {
  45. var point = points[i];
  46. xValues.push(point.x);
  47. yValues.push(point.y);
  48. }
  49. var xMin = Math.min.apply(null, xValues);
  50. var yMin = Math.min.apply(null, yValues);
  51. var xMax = Math.max.apply(null, xValues);
  52. var yMax = Math.max.apply(null, yValues);
  53. return {
  54. x: xMin,
  55. y: yMin,
  56. width: xMax - xMin,
  57. height: yMax - yMin
  58. };
  59. }
  60. function getMiddlePoint(a, b) {
  61. var x = (a.x - b.x) / 2 + b.x;
  62. var y = (a.y - b.y) / 2 + b.y;
  63. return {
  64. x,
  65. y
  66. };
  67. }
  68. var Interval = Shape.registerFactory('interval', {
  69. defaultShapeType: 'rect',
  70. getDefaultPoints(cfg) {
  71. return getRectPoints(cfg);
  72. }
  73. });
  74. Shape.registerShape('interval', 'rect', {
  75. draw(cfg, container) {
  76. var points = this.parsePoints(cfg.points);
  77. var style = mix({
  78. fill: cfg.color
  79. }, Global.shape.interval, cfg.style);
  80. if (cfg.isInCircle) {
  81. var newPoints = points.slice(0);
  82. if (this._coord.transposed) {
  83. newPoints = [points[0], points[3], points[2], points[1]];
  84. }
  85. var {
  86. x,
  87. y
  88. } = cfg.center;
  89. var v = [1, 0];
  90. var v0 = [newPoints[0].x - x, newPoints[0].y - y];
  91. var v1 = [newPoints[1].x - x, newPoints[1].y - y];
  92. var v2 = [newPoints[2].x - x, newPoints[2].y - y];
  93. var startAngle = Vector2.angleTo(v, v1);
  94. var endAngle = Vector2.angleTo(v, v2);
  95. var r0 = Vector2.length(v0);
  96. var r = Vector2.length(v1);
  97. if (startAngle >= 1.5 * Math.PI) {
  98. startAngle = startAngle - 2 * Math.PI;
  99. }
  100. if (endAngle >= 1.5 * Math.PI) {
  101. endAngle = endAngle - 2 * Math.PI;
  102. }
  103. return container.addShape('Sector', {
  104. className: 'interval',
  105. attrs: mix({
  106. x,
  107. y,
  108. r,
  109. r0,
  110. startAngle,
  111. endAngle
  112. }, style)
  113. });
  114. }
  115. var rectCfg = getRectRange(points);
  116. return container.addShape('rect', {
  117. className: 'interval',
  118. attrs: mix(rectCfg, style)
  119. });
  120. }
  121. }); // 金字塔 和 漏斗图
  122. ['pyramid', 'funnel'].forEach(function (shapeType) {
  123. Shape.registerShape('interval', shapeType, {
  124. getPoints(cfg) {
  125. cfg.size = cfg.size * 2; // 漏斗图的 size 是柱状图的两倍
  126. return getRectPoints(cfg);
  127. },
  128. draw(cfg, container) {
  129. var points = this.parsePoints(cfg.points);
  130. var nextPoints = this.parsePoints(cfg.nextPoints);
  131. var polygonPoints = null;
  132. if (nextPoints) {
  133. polygonPoints = [points[0], points[1], nextPoints[1], nextPoints[0]];
  134. } else {
  135. polygonPoints = [points[0], points[1]]; // pyramid 顶部是三角形,所以取中心点就好了,funnel顶部是长方形
  136. if (shapeType === 'pyramid') {
  137. polygonPoints.push(getMiddlePoint(points[2], points[3]));
  138. } else {
  139. polygonPoints.push(points[2], points[3]);
  140. }
  141. }
  142. var attrs = mix({
  143. fill: cfg.color,
  144. points: polygonPoints
  145. }, Global.shape.interval, cfg.style);
  146. return container.addShape('polygon', {
  147. className: 'interval',
  148. attrs
  149. });
  150. }
  151. });
  152. });
  153. export default Interval;