pie_series.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * DevExtreme (viz/series/pie_series.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var noop = require("../../core/utils/common").noop;
  11. var each = require("../../core/utils/iterator").each;
  12. var scatterSeries = require("./scatter_series");
  13. var vizUtils = require("../core/utils");
  14. var extend = require("../../core/utils/extend").extend;
  15. var chartScatterSeries = scatterSeries.chart;
  16. var barSeries = require("./bar_series").chart.bar;
  17. var _extend = extend;
  18. var _each = each;
  19. var _noop = noop;
  20. var _map = vizUtils.map;
  21. var _isFinite = isFinite;
  22. var _max = Math.max;
  23. var ANIMATION_DURATION = .7;
  24. var INSIDE = "inside";
  25. exports.pie = _extend({}, barSeries, {
  26. _setGroupsSettings: function() {
  27. chartScatterSeries._setGroupsSettings.apply(this, arguments);
  28. this._labelsGroup.attr({
  29. "pointer-events": null
  30. })
  31. },
  32. _createErrorBarGroup: _noop,
  33. _drawPoint: function(options) {
  34. var point = options.point;
  35. var legendCallback = this._legendCallback;
  36. chartScatterSeries._drawPoint.call(this, options);
  37. !point.isVisible() && point.setInvisibility();
  38. point.isSelected() && legendCallback()
  39. },
  40. _getOldPoint: function(data, oldPointsByArgument, index) {
  41. var point = (this._points || [])[index];
  42. if (point) {
  43. oldPointsByArgument[point.argument.valueOf()] = oldPointsByArgument[point.argument.valueOf()].filter(function(p) {
  44. return p !== point
  45. })
  46. }
  47. return point
  48. },
  49. adjustLabels: function(moveLabelsFromCenter) {
  50. return (this._points || []).reduce(function(r, p) {
  51. if (p._label.isVisible()) {
  52. p.setLabelTrackerData();
  53. r = p.applyWordWrap(moveLabelsFromCenter) || r;
  54. p.updateLabelCoord(moveLabelsFromCenter);
  55. return r
  56. }
  57. }, false)
  58. },
  59. _applyElementsClipRect: _noop,
  60. getColor: _noop,
  61. areErrorBarsVisible: _noop,
  62. drawLabelsWOPoints: function() {
  63. var that = this;
  64. if (that._options.label.position === INSIDE) {
  65. return false
  66. }
  67. that._labelsGroup.append(that._extGroups.labelsGroup);
  68. (that._points || []).forEach(function(point) {
  69. point.drawLabel()
  70. });
  71. return true
  72. },
  73. getPointsCount: function() {
  74. var _this = this;
  75. return this._data.filter(function(d) {
  76. return _this._checkData(d)
  77. }).length
  78. },
  79. setMaxPointsCount: function(count) {
  80. this._pointsCount = count
  81. },
  82. _getCreatingPointOptions: function(data, dataIndex) {
  83. return this._getPointOptions(data, dataIndex)
  84. },
  85. _updateOptions: function(options) {
  86. this.labelSpace = 0;
  87. this.innerRadius = "pie" === this.type ? 0 : options.innerRadius
  88. },
  89. _checkData: function(data, skippedFields) {
  90. var base = barSeries._checkData.call(this, data, skippedFields, {
  91. value: this.getValueFields()[0]
  92. });
  93. return this._options.paintNullPoints ? base : base && null !== data.value
  94. },
  95. _createGroups: chartScatterSeries._createGroups,
  96. _setMarkerGroupSettings: function() {
  97. this._markersGroup.attr({
  98. "class": "dxc-markers"
  99. })
  100. },
  101. _getMainColor: function(data, point) {
  102. var pointsByArg = this.getPointsByArg(data.argument);
  103. var argumentIndex = point ? pointsByArg.indexOf(point) : pointsByArg.length;
  104. return this._options.mainSeriesColor(data.argument, argumentIndex, this._pointsCount)
  105. },
  106. _getPointOptions: function(data) {
  107. return this._parsePointOptions(this._preparePointOptions(), this._options.label, data)
  108. },
  109. _getRangeData: function() {
  110. return this._rangeData
  111. },
  112. _createPointStyles: function(pointOptions, data, point) {
  113. var that = this;
  114. var mainColor = pointOptions.color || that._getMainColor(data, point);
  115. return {
  116. normal: that._parsePointStyle(pointOptions, mainColor, mainColor),
  117. hover: that._parsePointStyle(pointOptions.hoverStyle, mainColor, mainColor),
  118. selection: that._parsePointStyle(pointOptions.selectionStyle, mainColor, mainColor),
  119. legendStyles: {
  120. normal: that._createLegendState(pointOptions, mainColor),
  121. hover: that._createLegendState(pointOptions.hoverStyle, mainColor),
  122. selection: that._createLegendState(pointOptions.selectionStyle, mainColor)
  123. }
  124. }
  125. },
  126. _getArrangeMinShownValue: function(points, total) {
  127. var minSegmentSize = this._options.minSegmentSize;
  128. var totalMinSegmentSize = 0;
  129. var totalNotMinValues = 0;
  130. total = total || points.length;
  131. _each(points, function(_, point) {
  132. if (point.isVisible()) {
  133. if (point.normalInitialValue < minSegmentSize * total / 360) {
  134. totalMinSegmentSize += minSegmentSize
  135. } else {
  136. totalNotMinValues += point.normalInitialValue
  137. }
  138. }
  139. });
  140. return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0
  141. },
  142. _applyArrangeCorrection: function(points, minShownValue, total) {
  143. var options = this._options;
  144. var isClockWise = "anticlockwise" !== options.segmentsDirection;
  145. var shiftedAngle = _isFinite(options.startAngle) ? vizUtils.normalizeAngle(options.startAngle) : 0;
  146. var minSegmentSize = options.minSegmentSize;
  147. var percent;
  148. var correction = 0;
  149. var zeroTotalCorrection = 0;
  150. if (0 === total) {
  151. total = points.filter(function(el) {
  152. return el.isVisible()
  153. }).length;
  154. zeroTotalCorrection = 1
  155. }
  156. _each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {
  157. var val = point.isVisible() ? zeroTotalCorrection || point.normalInitialValue : 0;
  158. var updatedZeroValue;
  159. if (minSegmentSize && point.isVisible() && val < minShownValue) {
  160. updatedZeroValue = minShownValue
  161. }
  162. percent = val / total;
  163. point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));
  164. point.shiftedAngle = shiftedAngle;
  165. correction += updatedZeroValue || val
  166. });
  167. this._rangeData = {
  168. val: {
  169. min: 0,
  170. max: correction
  171. }
  172. }
  173. },
  174. _removePoint: function(point) {
  175. var points = this.getPointsByArg(point.argument);
  176. points.splice(points.indexOf(point), 1);
  177. point.dispose()
  178. },
  179. arrangePoints: function() {
  180. var that = this;
  181. var originalPoints = that._points || [];
  182. var minSegmentSize = that._options.minSegmentSize;
  183. var minShownValue;
  184. var isAllPointsNegative = true;
  185. var i = 0;
  186. var len = originalPoints.length;
  187. while (i < len && isAllPointsNegative) {
  188. isAllPointsNegative = originalPoints[i].value <= 0;
  189. i++
  190. }
  191. var points = that._points = _map(originalPoints, function(point) {
  192. if (null === point.value || !isAllPointsNegative && point.value < 0) {
  193. that._removePoint(point);
  194. return null
  195. } else {
  196. return point
  197. }
  198. });
  199. var maxValue = points.reduce(function(max, p) {
  200. return _max(max, Math.abs(p.initialValue))
  201. }, 0);
  202. points.forEach(function(p) {
  203. p.normalInitialValue = p.initialValue / (0 !== maxValue ? maxValue : 1)
  204. });
  205. var total = points.reduce(function(total, point) {
  206. return total + (point.isVisible() ? point.normalInitialValue : 0)
  207. }, 0);
  208. if (minSegmentSize) {
  209. minShownValue = this._getArrangeMinShownValue(points, total)
  210. }
  211. that._applyArrangeCorrection(points, minShownValue, total)
  212. },
  213. correctPosition: function(correction, canvas) {
  214. _each(this._points, function(_, point) {
  215. point.correctPosition(correction)
  216. });
  217. this.setVisibleArea(canvas)
  218. },
  219. correctRadius: function(correction) {
  220. this._points.forEach(function(point) {
  221. point.correctRadius(correction)
  222. })
  223. },
  224. correctLabelRadius: function(labelRadius) {
  225. this._points.forEach(function(point) {
  226. point.correctLabelRadius(labelRadius)
  227. })
  228. },
  229. setVisibleArea: function(canvas) {
  230. this._visibleArea = {
  231. minX: canvas.left,
  232. maxX: canvas.width - canvas.right,
  233. minY: canvas.top,
  234. maxY: canvas.height - canvas.bottom
  235. }
  236. },
  237. _applyVisibleArea: _noop,
  238. _animate: function(firstDrawing) {
  239. var that = this;
  240. var points = that._points;
  241. var pointsCount = points && points.length;
  242. var completeFunc = function() {
  243. that._animateComplete()
  244. };
  245. var animatePoint;
  246. if (firstDrawing) {
  247. animatePoint = function(p, i) {
  248. p.animate(i === pointsCount - 1 ? completeFunc : void 0, ANIMATION_DURATION, (1 - ANIMATION_DURATION) * i / (pointsCount - 1))
  249. }
  250. } else {
  251. animatePoint = function(p, i) {
  252. p.animate(i === pointsCount - 1 ? completeFunc : void 0)
  253. }
  254. }
  255. points.forEach(animatePoint)
  256. },
  257. getVisiblePoints: function() {
  258. return _map(this._points, function(p) {
  259. return p.isVisible() ? p : null
  260. })
  261. },
  262. getPointsByKeys: function(arg, argumentIndex) {
  263. var pointsByArg = this.getPointsByArg(arg);
  264. return pointsByArg[argumentIndex] && [pointsByArg[argumentIndex]] || []
  265. }
  266. });
  267. exports.doughnut = exports.donut = exports.pie;