PieSeries.js 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. /* *
  2. *
  3. * (c) 2010-2021 Torstein Honsi
  4. *
  5. * License: www.highcharts.com/license
  6. *
  7. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8. *
  9. * */
  10. 'use strict';
  11. var __extends = (this && this.__extends) || (function () {
  12. var extendStatics = function (d, b) {
  13. extendStatics = Object.setPrototypeOf ||
  14. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  15. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  16. return extendStatics(d, b);
  17. };
  18. return function (d, b) {
  19. extendStatics(d, b);
  20. function __() { this.constructor = d; }
  21. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  22. };
  23. })();
  24. import CenteredSeriesMixin from '../../Mixins/CenteredSeries.js';
  25. var getStartAndEndRadians = CenteredSeriesMixin.getStartAndEndRadians;
  26. import ColumnSeries from '../Column/ColumnSeries.js';
  27. import H from '../../Core/Globals.js';
  28. var noop = H.noop;
  29. import LegendSymbolMixin from '../../Mixins/LegendSymbol.js';
  30. import palette from '../../Core/Color/Palette.js';
  31. import PiePoint from './PiePoint.js';
  32. import Series from '../../Core/Series/Series.js';
  33. import SeriesRegistry from '../../Core/Series/SeriesRegistry.js';
  34. import SVGRenderer from '../../Core/Renderer/SVG/SVGRenderer.js';
  35. import U from '../../Core/Utilities.js';
  36. var clamp = U.clamp, extend = U.extend, fireEvent = U.fireEvent, merge = U.merge, pick = U.pick, relativeLength = U.relativeLength;
  37. import '../../Core/Options.js';
  38. /* *
  39. *
  40. * Class
  41. *
  42. * */
  43. /**
  44. * Pie series type.
  45. *
  46. * @private
  47. * @class
  48. * @name Highcharts.seriesTypes.pie
  49. *
  50. * @augments Highcharts.Series
  51. */
  52. var PieSeries = /** @class */ (function (_super) {
  53. __extends(PieSeries, _super);
  54. function PieSeries() {
  55. /* *
  56. *
  57. * Static Properties
  58. *
  59. * */
  60. var _this = _super !== null && _super.apply(this, arguments) || this;
  61. /* *
  62. *
  63. * Properties
  64. *
  65. * */
  66. _this.center = void 0;
  67. _this.data = void 0;
  68. _this.maxLabelDistance = void 0;
  69. _this.options = void 0;
  70. _this.points = void 0;
  71. return _this;
  72. /* eslint-enable valid-jsdoc */
  73. }
  74. /* *
  75. *
  76. * Functions
  77. *
  78. * */
  79. /* eslint-disable valid-jsdoc */
  80. /**
  81. * Animates the pies in.
  82. * @private
  83. */
  84. PieSeries.prototype.animate = function (init) {
  85. var series = this, points = series.points, startAngleRad = series.startAngleRad;
  86. if (!init) {
  87. points.forEach(function (point) {
  88. var graphic = point.graphic, args = point.shapeArgs;
  89. if (graphic && args) {
  90. // start values
  91. graphic.attr({
  92. // animate from inner radius (#779)
  93. r: pick(point.startR, (series.center && series.center[3] / 2)),
  94. start: startAngleRad,
  95. end: startAngleRad
  96. });
  97. // animate
  98. graphic.animate({
  99. r: args.r,
  100. start: args.start,
  101. end: args.end
  102. }, series.options.animation);
  103. }
  104. });
  105. }
  106. };
  107. /**
  108. * Called internally to draw auxiliary graph in pie-like series in
  109. * situtation when the default graph is not sufficient enough to present
  110. * the data well. Auxiliary graph is saved in the same object as
  111. * regular graph.
  112. * @private
  113. */
  114. PieSeries.prototype.drawEmpty = function () {
  115. var centerX, centerY, start = this.startAngleRad, end = this.endAngleRad, options = this.options;
  116. // Draw auxiliary graph if there're no visible points.
  117. if (this.total === 0 && this.center) {
  118. centerX = this.center[0];
  119. centerY = this.center[1];
  120. if (!this.graph) {
  121. this.graph = this.chart.renderer
  122. .arc(centerX, centerY, this.center[1] / 2, 0, start, end)
  123. .addClass('highcharts-empty-series')
  124. .add(this.group);
  125. }
  126. this.graph.attr({
  127. d: SVGRenderer.prototype.symbols.arc(centerX, centerY, this.center[2] / 2, 0, {
  128. start: start,
  129. end: end,
  130. innerR: this.center[3] / 2
  131. })
  132. });
  133. if (!this.chart.styledMode) {
  134. this.graph.attr({
  135. 'stroke-width': options.borderWidth,
  136. fill: options.fillColor || 'none',
  137. stroke: options.color || palette.neutralColor20
  138. });
  139. }
  140. }
  141. else if (this.graph) { // Destroy the graph object.
  142. this.graph = this.graph.destroy();
  143. }
  144. };
  145. /**
  146. * Slices in pie chart are initialized in DOM, but it's shapes and
  147. * animations are normally run in `drawPoints()`.
  148. * @private
  149. */
  150. PieSeries.prototype.drawPoints = function () {
  151. var renderer = this.chart.renderer;
  152. this.points.forEach(function (point) {
  153. // When updating a series between 2d and 3d or cartesian and
  154. // polar, the shape type changes.
  155. if (point.graphic && point.hasNewShapeType()) {
  156. point.graphic = point.graphic.destroy();
  157. }
  158. if (!point.graphic) {
  159. point.graphic = renderer[point.shapeType](point.shapeArgs)
  160. .add(point.series.group);
  161. point.delayedRendering = true;
  162. }
  163. });
  164. };
  165. /**
  166. * Extend the generatePoints method by adding total and percentage
  167. * properties to each point
  168. * @private
  169. */
  170. PieSeries.prototype.generatePoints = function () {
  171. _super.prototype.generatePoints.call(this);
  172. this.updateTotals();
  173. };
  174. /**
  175. * Utility for getting the x value from a given y, used for
  176. * anticollision logic in data labels. Added point for using specific
  177. * points' label distance.
  178. * @private
  179. */
  180. PieSeries.prototype.getX = function (y, left, point) {
  181. var center = this.center,
  182. // Variable pie has individual radius
  183. radius = this.radii ?
  184. this.radii[point.index] || 0 :
  185. center[2] / 2, angle, x;
  186. angle = Math.asin(clamp((y - center[1]) / (radius + point.labelDistance), -1, 1));
  187. x = center[0] +
  188. (left ? -1 : 1) *
  189. (Math.cos(angle) * (radius + point.labelDistance)) +
  190. (point.labelDistance > 0 ?
  191. (left ? -1 : 1) * this.options.dataLabels.padding :
  192. 0);
  193. return x;
  194. };
  195. /**
  196. * Define hasData function for non-cartesian series. Returns true if the
  197. * series has points at all.
  198. * @private
  199. */
  200. PieSeries.prototype.hasData = function () {
  201. return !!this.processedXData.length; // != 0
  202. };
  203. /**
  204. * Draw the data points
  205. * @private
  206. */
  207. PieSeries.prototype.redrawPoints = function () {
  208. var series = this, chart = series.chart, renderer = chart.renderer, groupTranslation, graphic, pointAttr, shapeArgs, shadow = series.options.shadow;
  209. this.drawEmpty();
  210. if (shadow && !series.shadowGroup && !chart.styledMode) {
  211. series.shadowGroup = renderer
  212. .g('shadow')
  213. .attr({ zIndex: -1 })
  214. .add(series.group);
  215. }
  216. // draw the slices
  217. series.points.forEach(function (point) {
  218. var animateTo = {};
  219. graphic = point.graphic;
  220. if (!point.isNull && graphic) {
  221. var shadowGroup = void 0;
  222. shapeArgs = point.shapeArgs;
  223. // If the point is sliced, use special translation, else use
  224. // plot area translation
  225. groupTranslation = point.getTranslate();
  226. if (!chart.styledMode) {
  227. // Put the shadow behind all points
  228. shadowGroup = point.shadowGroup;
  229. if (shadow && !shadowGroup) {
  230. shadowGroup = point.shadowGroup = renderer
  231. .g('shadow')
  232. .add(series.shadowGroup);
  233. }
  234. if (shadowGroup) {
  235. shadowGroup.attr(groupTranslation);
  236. }
  237. pointAttr = series.pointAttribs(point, (point.selected && 'select'));
  238. }
  239. // Draw the slice
  240. if (!point.delayedRendering) {
  241. graphic
  242. .setRadialReference(series.center);
  243. if (!chart.styledMode) {
  244. merge(true, animateTo, pointAttr);
  245. }
  246. merge(true, animateTo, shapeArgs, groupTranslation);
  247. graphic.animate(animateTo);
  248. }
  249. else {
  250. graphic
  251. .setRadialReference(series.center)
  252. .attr(shapeArgs)
  253. .attr(groupTranslation);
  254. if (!chart.styledMode) {
  255. graphic
  256. .attr(pointAttr)
  257. .attr({ 'stroke-linejoin': 'round' })
  258. .shadow(shadow, shadowGroup);
  259. }
  260. point.delayedRendering = false;
  261. }
  262. graphic.attr({
  263. visibility: point.visible ? 'inherit' : 'hidden'
  264. });
  265. graphic.addClass(point.getClassName(), true);
  266. }
  267. else if (graphic) {
  268. point.graphic = graphic.destroy();
  269. }
  270. });
  271. };
  272. /**
  273. * Utility for sorting data labels.
  274. * @private
  275. */
  276. PieSeries.prototype.sortByAngle = function (points, sign) {
  277. points.sort(function (a, b) {
  278. return ((typeof a.angle !== 'undefined') &&
  279. (b.angle - a.angle) * sign);
  280. });
  281. };
  282. /**
  283. * Do translation for pie slices
  284. * @private
  285. */
  286. PieSeries.prototype.translate = function (positions) {
  287. this.generatePoints();
  288. var series = this, cumulative = 0, precision = 1000, // issue #172
  289. options = series.options, slicedOffset = options.slicedOffset, connectorOffset = slicedOffset + (options.borderWidth || 0), finalConnectorOffset, start, end, angle, radians = getStartAndEndRadians(options.startAngle, options.endAngle), startAngleRad = series.startAngleRad = radians.start, endAngleRad = series.endAngleRad = radians.end, circ = endAngleRad - startAngleRad, // 2 * Math.PI,
  290. points = series.points,
  291. // the x component of the radius vector for a given point
  292. radiusX, radiusY, labelDistance = options.dataLabels.distance, ignoreHiddenPoint = options.ignoreHiddenPoint, i, len = points.length, point;
  293. // Get positions - either an integer or a percentage string must be
  294. // given. If positions are passed as a parameter, we're in a
  295. // recursive loop for adjusting space for data labels.
  296. if (!positions) {
  297. series.center = positions = series.getCenter();
  298. }
  299. // Calculate the geometry for each point
  300. for (i = 0; i < len; i++) {
  301. point = points[i];
  302. // set start and end angle
  303. start = startAngleRad + (cumulative * circ);
  304. if (point.isValid() &&
  305. (!ignoreHiddenPoint || point.visible)) {
  306. cumulative += point.percentage / 100;
  307. }
  308. end = startAngleRad + (cumulative * circ);
  309. // set the shape
  310. var shapeArgs = {
  311. x: positions[0],
  312. y: positions[1],
  313. r: positions[2] / 2,
  314. innerR: positions[3] / 2,
  315. start: Math.round(start * precision) / precision,
  316. end: Math.round(end * precision) / precision
  317. };
  318. point.shapeType = 'arc';
  319. point.shapeArgs = shapeArgs;
  320. // Used for distance calculation for specific point.
  321. point.labelDistance = pick((point.options.dataLabels &&
  322. point.options.dataLabels.distance), labelDistance);
  323. // Compute point.labelDistance if it's defined as percentage
  324. // of slice radius (#8854)
  325. point.labelDistance = relativeLength(point.labelDistance, shapeArgs.r);
  326. // Saved for later dataLabels distance calculation.
  327. series.maxLabelDistance = Math.max(series.maxLabelDistance || 0, point.labelDistance);
  328. // The angle must stay within -90 and 270 (#2645)
  329. angle = (end + start) / 2;
  330. if (angle > 1.5 * Math.PI) {
  331. angle -= 2 * Math.PI;
  332. }
  333. else if (angle < -Math.PI / 2) {
  334. angle += 2 * Math.PI;
  335. }
  336. // Center for the sliced out slice
  337. point.slicedTranslation = {
  338. translateX: Math.round(Math.cos(angle) * slicedOffset),
  339. translateY: Math.round(Math.sin(angle) * slicedOffset)
  340. };
  341. // set the anchor point for tooltips
  342. radiusX = Math.cos(angle) * positions[2] / 2;
  343. radiusY = Math.sin(angle) * positions[2] / 2;
  344. point.tooltipPos = [
  345. positions[0] + radiusX * 0.7,
  346. positions[1] + radiusY * 0.7
  347. ];
  348. point.half = angle < -Math.PI / 2 || angle > Math.PI / 2 ?
  349. 1 :
  350. 0;
  351. point.angle = angle;
  352. // Set the anchor point for data labels. Use point.labelDistance
  353. // instead of labelDistance // #1174
  354. // finalConnectorOffset - not override connectorOffset value.
  355. finalConnectorOffset = Math.min(connectorOffset, point.labelDistance / 5); // #1678
  356. point.labelPosition = {
  357. natural: {
  358. // initial position of the data label - it's utilized for
  359. // finding the final position for the label
  360. x: positions[0] + radiusX + Math.cos(angle) *
  361. point.labelDistance,
  362. y: positions[1] + radiusY + Math.sin(angle) *
  363. point.labelDistance
  364. },
  365. 'final': {
  366. // used for generating connector path -
  367. // initialized later in drawDataLabels function
  368. // x: undefined,
  369. // y: undefined
  370. },
  371. // left - pie on the left side of the data label
  372. // right - pie on the right side of the data label
  373. // center - data label overlaps the pie
  374. alignment: point.labelDistance < 0 ?
  375. 'center' : point.half ? 'right' : 'left',
  376. connectorPosition: {
  377. breakAt: {
  378. x: positions[0] + radiusX + Math.cos(angle) *
  379. finalConnectorOffset,
  380. y: positions[1] + radiusY + Math.sin(angle) *
  381. finalConnectorOffset
  382. },
  383. touchingSliceAt: {
  384. x: positions[0] + radiusX,
  385. y: positions[1] + radiusY
  386. }
  387. }
  388. };
  389. }
  390. fireEvent(series, 'afterTranslate');
  391. };
  392. /**
  393. * Recompute total chart sum and update percentages of points.
  394. * @private
  395. */
  396. PieSeries.prototype.updateTotals = function () {
  397. var i, total = 0, points = this.points, len = points.length, point, ignoreHiddenPoint = this.options.ignoreHiddenPoint;
  398. // Get the total sum
  399. for (i = 0; i < len; i++) {
  400. point = points[i];
  401. if (point.isValid() &&
  402. (!ignoreHiddenPoint || point.visible)) {
  403. total += point.y;
  404. }
  405. }
  406. this.total = total;
  407. // Set each point's properties
  408. for (i = 0; i < len; i++) {
  409. point = points[i];
  410. point.percentage =
  411. (total > 0 && (point.visible || !ignoreHiddenPoint)) ?
  412. point.y / total * 100 :
  413. 0;
  414. point.total = total;
  415. }
  416. };
  417. /**
  418. * A pie chart is a circular graphic which is divided into slices to
  419. * illustrate numerical proportion.
  420. *
  421. * @sample highcharts/demo/pie-basic/
  422. * Pie chart
  423. *
  424. * @extends plotOptions.line
  425. * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,
  426. * cropThreshold, dashStyle, dataSorting, dragDrop,
  427. * findNearestPointBy, getExtremesFromAll, label, lineWidth,
  428. * marker, negativeColor, pointInterval, pointIntervalUnit,
  429. * pointPlacement, pointStart, softThreshold, stacking, step,
  430. * threshold, turboThreshold, zoneAxis, zones, dataSorting,
  431. * boostBlending
  432. * @product highcharts
  433. * @optionparent plotOptions.pie
  434. */
  435. PieSeries.defaultOptions = merge(Series.defaultOptions, {
  436. /**
  437. * @excluding legendItemClick
  438. * @apioption plotOptions.pie.events
  439. */
  440. /**
  441. * Fires when the checkbox next to the point name in the legend is
  442. * clicked. One parameter, event, is passed to the function. The state
  443. * of the checkbox is found by event.checked. The checked item is found
  444. * by event.item. Return false to prevent the default action which is to
  445. * toggle the select state of the series.
  446. *
  447. * @sample {highcharts} highcharts/plotoptions/series-events-checkboxclick/
  448. * Alert checkbox status
  449. *
  450. * @type {Function}
  451. * @since 1.2.0
  452. * @product highcharts
  453. * @context Highcharts.Point
  454. * @apioption plotOptions.pie.events.checkboxClick
  455. */
  456. /**
  457. * Fires when the legend item belonging to the pie point (slice) is
  458. * clicked. The `this` keyword refers to the point itself. One
  459. * parameter, `event`, is passed to the function, containing common
  460. * event information. The default action is to toggle the visibility of
  461. * the point. This can be prevented by calling `event.preventDefault()`.
  462. *
  463. * @sample {highcharts} highcharts/plotoptions/pie-point-events-legenditemclick/
  464. * Confirm toggle visibility
  465. *
  466. * @type {Highcharts.PointLegendItemClickCallbackFunction}
  467. * @since 1.2.0
  468. * @product highcharts
  469. * @apioption plotOptions.pie.point.events.legendItemClick
  470. */
  471. /**
  472. * The center of the pie chart relative to the plot area. Can be
  473. * percentages or pixel values. The default behaviour (as of 3.0) is to
  474. * center the pie so that all slices and data labels are within the plot
  475. * area. As a consequence, the pie may actually jump around in a chart
  476. * with dynamic values, as the data labels move. In that case, the
  477. * center should be explicitly set, for example to `["50%", "50%"]`.
  478. *
  479. * @sample {highcharts} highcharts/plotoptions/pie-center/
  480. * Centered at 100, 100
  481. *
  482. * @type {Array<(number|string|null),(number|string|null)>}
  483. * @default [null, null]
  484. * @product highcharts
  485. *
  486. * @private
  487. */
  488. center: [null, null],
  489. /**
  490. * The color of the pie series. A pie series is represented as an empty
  491. * circle if the total sum of its values is 0. Use this property to
  492. * define the color of its border.
  493. *
  494. * In styled mode, the color can be defined by the
  495. * [colorIndex](#plotOptions.series.colorIndex) option. Also, the series
  496. * color can be set with the `.highcharts-series`,
  497. * `.highcharts-color-{n}`, `.highcharts-{type}-series` or
  498. * `.highcharts-series-{n}` class, or individual classes given by the
  499. * `className` option.
  500. *
  501. * @sample {highcharts} highcharts/plotoptions/pie-emptyseries/
  502. * Empty pie series
  503. *
  504. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  505. * @default ${palette.neutralColor20}
  506. * @apioption plotOptions.pie.color
  507. */
  508. /**
  509. * @product highcharts
  510. *
  511. * @private
  512. */
  513. clip: false,
  514. /**
  515. * @ignore-option
  516. *
  517. * @private
  518. */
  519. colorByPoint: true,
  520. /**
  521. * A series specific or series type specific color set to use instead
  522. * of the global [colors](#colors).
  523. *
  524. * @sample {highcharts} highcharts/demo/pie-monochrome/
  525. * Set default colors for all pies
  526. *
  527. * @type {Array<Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject>}
  528. * @since 3.0
  529. * @product highcharts
  530. * @apioption plotOptions.pie.colors
  531. */
  532. /**
  533. * @declare Highcharts.SeriesPieDataLabelsOptionsObject
  534. * @extends plotOptions.series.dataLabels
  535. * @excluding align, allowOverlap, inside, staggerLines, step
  536. * @private
  537. */
  538. dataLabels: {
  539. /**
  540. * Alignment method for data labels. Possible values are:
  541. *
  542. * - `toPlotEdges`: Each label touches the nearest vertical edge of
  543. * the plot area.
  544. *
  545. * - `connectors`: Connectors have the same x position and the
  546. * widest label of each half (left & right) touches the nearest
  547. * vertical edge of the plot area.
  548. *
  549. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-alignto-connectors/
  550. * alignTo: connectors
  551. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-alignto-plotedges/
  552. * alignTo: plotEdges
  553. *
  554. * @type {string}
  555. * @since 7.0.0
  556. * @product highcharts
  557. * @apioption plotOptions.pie.dataLabels.alignTo
  558. */
  559. allowOverlap: true,
  560. /**
  561. * The color of the line connecting the data label to the pie slice.
  562. * The default color is the same as the point's color.
  563. *
  564. * In styled mode, the connector stroke is given in the
  565. * `.highcharts-data-label-connector` class.
  566. *
  567. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorcolor/
  568. * Blue connectors
  569. * @sample {highcharts} highcharts/css/pie-point/
  570. * Styled connectors
  571. *
  572. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  573. * @since 2.1
  574. * @product highcharts
  575. * @apioption plotOptions.pie.dataLabels.connectorColor
  576. */
  577. /**
  578. * The distance from the data label to the connector. Note that
  579. * data labels also have a default `padding`, so in order for the
  580. * connector to touch the text, the `padding` must also be 0.
  581. *
  582. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorpadding/
  583. * No padding
  584. *
  585. * @since 2.1
  586. * @product highcharts
  587. */
  588. connectorPadding: 5,
  589. /**
  590. * Specifies the method that is used to generate the connector path.
  591. * Highcharts provides 3 built-in connector shapes: `'fixedOffset'`
  592. * (default), `'straight'` and `'crookedLine'`. Using
  593. * `'crookedLine'` has the most sense (in most of the cases) when
  594. * `'alignTo'` is set.
  595. *
  596. * Users can provide their own method by passing a function instead
  597. * of a String. 3 arguments are passed to the callback:
  598. *
  599. * - Object that holds the information about the coordinates of the
  600. * label (`x` & `y` properties) and how the label is located in
  601. * relation to the pie (`alignment` property). `alignment` can by
  602. * one of the following:
  603. * `'left'` (pie on the left side of the data label),
  604. * `'right'` (pie on the right side of the data label) or
  605. * `'center'` (data label overlaps the pie).
  606. *
  607. * - Object that holds the information about the position of the
  608. * connector. Its `touchingSliceAt` porperty tells the position
  609. * of the place where the connector touches the slice.
  610. *
  611. * - Data label options
  612. *
  613. * The function has to return an SVG path definition in array form
  614. * (see the example).
  615. *
  616. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorshape-string/
  617. * connectorShape is a String
  618. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorshape-function/
  619. * connectorShape is a function
  620. *
  621. * @type {string|Function}
  622. * @since 7.0.0
  623. * @product highcharts
  624. */
  625. connectorShape: 'fixedOffset',
  626. /**
  627. * The width of the line connecting the data label to the pie slice.
  628. *
  629. * In styled mode, the connector stroke width is given in the
  630. * `.highcharts-data-label-connector` class.
  631. *
  632. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorwidth-disabled/
  633. * Disable the connector
  634. * @sample {highcharts} highcharts/css/pie-point/
  635. * Styled connectors
  636. *
  637. * @type {number}
  638. * @default 1
  639. * @since 2.1
  640. * @product highcharts
  641. * @apioption plotOptions.pie.dataLabels.connectorWidth
  642. */
  643. /**
  644. * Works only if `connectorShape` is `'crookedLine'`. It defines how
  645. * far from the vertical plot edge the coonnector path should be
  646. * crooked.
  647. *
  648. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-crookdistance/
  649. * crookDistance set to 90%
  650. *
  651. * @since 7.0.0
  652. * @product highcharts
  653. */
  654. crookDistance: '70%',
  655. /**
  656. * The distance of the data label from the pie's edge. Negative
  657. * numbers put the data label on top of the pie slices. Can also be
  658. * defined as a percentage of pie's radius. Connectors are only
  659. * shown for data labels outside the pie.
  660. *
  661. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-distance/
  662. * Data labels on top of the pie
  663. *
  664. * @type {number|string}
  665. * @since 2.1
  666. * @product highcharts
  667. */
  668. distance: 30,
  669. enabled: true,
  670. /**
  671. * A
  672. * [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  673. * for the data label. Available variables are the same as for
  674. * `formatter`.
  675. *
  676. * @sample {highcharts} highcharts/plotoptions/series-datalabels-format/
  677. * Add a unit
  678. *
  679. * @type {string}
  680. * @default undefined
  681. * @since 3.0
  682. * @apioption plotOptions.pie.dataLabels.format
  683. */
  684. // eslint-disable-next-line valid-jsdoc
  685. /**
  686. * Callback JavaScript function to format the data label. Note that
  687. * if a `format` is defined, the format takes precedence and the
  688. * formatter is ignored.
  689. *
  690. * @type {Highcharts.DataLabelsFormatterCallbackFunction}
  691. * @default function () { return this.point.isNull ? void 0 : this.point.name; }
  692. */
  693. formatter: function () {
  694. return this.point.isNull ? void 0 : this.point.name;
  695. },
  696. /**
  697. * Whether to render the connector as a soft arc or a line with
  698. * sharp break. Works only if `connectorShape` equals to
  699. * `fixedOffset`.
  700. *
  701. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-true/
  702. * Soft
  703. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-false/
  704. * Non soft
  705. *
  706. * @since 2.1.7
  707. * @product highcharts
  708. */
  709. softConnector: true,
  710. /**
  711. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-overflow
  712. * Long labels truncated with an ellipsis
  713. * @sample {highcharts} highcharts/plotoptions/pie-datalabels-overflow-wrap
  714. * Long labels are wrapped
  715. *
  716. * @type {Highcharts.CSSObject}
  717. * @apioption plotOptions.pie.dataLabels.style
  718. */
  719. x: 0
  720. },
  721. /**
  722. * If the total sum of the pie's values is 0, the series is represented
  723. * as an empty circle . The `fillColor` option defines the color of that
  724. * circle. Use [pie.borderWidth](#plotOptions.pie.borderWidth) to set
  725. * the border thickness.
  726. *
  727. * @sample {highcharts} highcharts/plotoptions/pie-emptyseries/
  728. * Empty pie series
  729. *
  730. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  731. * @private
  732. */
  733. fillColor: void 0,
  734. /**
  735. * The end angle of the pie in degrees where 0 is top and 90 is right.
  736. * Defaults to `startAngle` plus 360.
  737. *
  738. * @sample {highcharts} highcharts/demo/pie-semi-circle/
  739. * Semi-circle donut
  740. *
  741. * @type {number}
  742. * @since 1.3.6
  743. * @product highcharts
  744. * @apioption plotOptions.pie.endAngle
  745. */
  746. /**
  747. * Equivalent to [chart.ignoreHiddenSeries](#chart.ignoreHiddenSeries),
  748. * this option tells whether the series shall be redrawn as if the
  749. * hidden point were `null`.
  750. *
  751. * The default value changed from `false` to `true` with Highcharts
  752. * 3.0.
  753. *
  754. * @sample {highcharts} highcharts/plotoptions/pie-ignorehiddenpoint/
  755. * True, the hiddden point is ignored
  756. *
  757. * @since 2.3.0
  758. * @product highcharts
  759. *
  760. * @private
  761. */
  762. ignoreHiddenPoint: true,
  763. /**
  764. * @ignore-option
  765. *
  766. * @private
  767. */
  768. inactiveOtherPoints: true,
  769. /**
  770. * The size of the inner diameter for the pie. A size greater than 0
  771. * renders a donut chart. Can be a percentage or pixel value.
  772. * Percentages are relative to the pie size. Pixel values are given as
  773. * integers.
  774. *
  775. *
  776. * Note: in Highcharts < 4.1.2, the percentage was relative to the plot
  777. * area, not the pie size.
  778. *
  779. * @sample {highcharts} highcharts/plotoptions/pie-innersize-80px/
  780. * 80px inner size
  781. * @sample {highcharts} highcharts/plotoptions/pie-innersize-50percent/
  782. * 50% of the plot area
  783. * @sample {highcharts} highcharts/demo/3d-pie-donut/
  784. * 3D donut
  785. *
  786. * @type {number|string}
  787. * @default 0
  788. * @since 2.0
  789. * @product highcharts
  790. * @apioption plotOptions.pie.innerSize
  791. */
  792. /**
  793. * @ignore-option
  794. *
  795. * @private
  796. */
  797. legendType: 'point',
  798. /**
  799. * @ignore-option
  800. *
  801. * @private
  802. */
  803. marker: null,
  804. /**
  805. * The minimum size for a pie in response to auto margins. The pie will
  806. * try to shrink to make room for data labels in side the plot area,
  807. * but only to this size.
  808. *
  809. * @type {number|string}
  810. * @default 80
  811. * @since 3.0
  812. * @product highcharts
  813. * @apioption plotOptions.pie.minSize
  814. */
  815. /**
  816. * The diameter of the pie relative to the plot area. Can be a
  817. * percentage or pixel value. Pixel values are given as integers. The
  818. * default behaviour (as of 3.0) is to scale to the plot area and give
  819. * room for data labels within the plot area.
  820. * [slicedOffset](#plotOptions.pie.slicedOffset) is also included in the
  821. * default size calculation. As a consequence, the size of the pie may
  822. * vary when points are updated and data labels more around. In that
  823. * case it is best to set a fixed value, for example `"75%"`.
  824. *
  825. * @sample {highcharts} highcharts/plotoptions/pie-size/
  826. * Smaller pie
  827. *
  828. * @type {number|string|null}
  829. * @product highcharts
  830. *
  831. * @private
  832. */
  833. size: null,
  834. /**
  835. * Whether to display this particular series or series type in the
  836. * legend. Since 2.1, pies are not shown in the legend by default.
  837. *
  838. * @sample {highcharts} highcharts/plotoptions/series-showinlegend/
  839. * One series in the legend, one hidden
  840. *
  841. * @product highcharts
  842. *
  843. * @private
  844. */
  845. showInLegend: false,
  846. /**
  847. * If a point is sliced, moved out from the center, how many pixels
  848. * should it be moved?.
  849. *
  850. * @sample {highcharts} highcharts/plotoptions/pie-slicedoffset-20/
  851. * 20px offset
  852. *
  853. * @product highcharts
  854. *
  855. * @private
  856. */
  857. slicedOffset: 10,
  858. /**
  859. * The start angle of the pie slices in degrees where 0 is top and 90
  860. * right.
  861. *
  862. * @sample {highcharts} highcharts/plotoptions/pie-startangle-90/
  863. * Start from right
  864. *
  865. * @type {number}
  866. * @default 0
  867. * @since 2.3.4
  868. * @product highcharts
  869. * @apioption plotOptions.pie.startAngle
  870. */
  871. /**
  872. * Sticky tracking of mouse events. When true, the `mouseOut` event
  873. * on a series isn't triggered until the mouse moves over another
  874. * series, or out of the plot area. When false, the `mouseOut` event on
  875. * a series is triggered when the mouse leaves the area around the
  876. * series' graph or markers. This also implies the tooltip. When
  877. * `stickyTracking` is false and `tooltip.shared` is false, the tooltip
  878. * will be hidden when moving the mouse between series.
  879. *
  880. * @product highcharts
  881. *
  882. * @private
  883. */
  884. stickyTracking: false,
  885. tooltip: {
  886. followPointer: true
  887. },
  888. /**
  889. * The color of the border surrounding each slice. When `null`, the
  890. * border takes the same color as the slice fill. This can be used
  891. * together with a `borderWidth` to fill drawing gaps created by
  892. * antialiazing artefacts in borderless pies.
  893. *
  894. * In styled mode, the border stroke is given in the `.highcharts-point`
  895. * class.
  896. *
  897. * @sample {highcharts} highcharts/plotoptions/pie-bordercolor-black/
  898. * Black border
  899. *
  900. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  901. * @default #ffffff
  902. * @product highcharts
  903. *
  904. * @private
  905. */
  906. borderColor: palette.backgroundColor,
  907. /**
  908. * The width of the border surrounding each slice.
  909. *
  910. * When setting the border width to 0, there may be small gaps between
  911. * the slices due to SVG antialiasing artefacts. To work around this,
  912. * keep the border width at 0.5 or 1, but set the `borderColor` to
  913. * `null` instead.
  914. *
  915. * In styled mode, the border stroke width is given in the
  916. * `.highcharts-point` class.
  917. *
  918. * @sample {highcharts} highcharts/plotoptions/pie-borderwidth/
  919. * 3px border
  920. *
  921. * @product highcharts
  922. *
  923. * @private
  924. */
  925. borderWidth: 1,
  926. /**
  927. * @ignore-options
  928. * @private
  929. */
  930. lineWidth: void 0,
  931. states: {
  932. /**
  933. * @extends plotOptions.series.states.hover
  934. * @excluding marker, lineWidth, lineWidthPlus
  935. * @product highcharts
  936. */
  937. hover: {
  938. /**
  939. * How much to brighten the point on interaction. Requires the
  940. * main color to be defined in hex or rgb(a) format.
  941. *
  942. * In styled mode, the hover brightness is by default replaced
  943. * by a fill-opacity given in the `.highcharts-point-hover`
  944. * class.
  945. *
  946. * @sample {highcharts} highcharts/plotoptions/pie-states-hover-brightness/
  947. * Brightened by 0.5
  948. *
  949. * @product highcharts
  950. */
  951. brightness: 0.1
  952. }
  953. }
  954. });
  955. return PieSeries;
  956. }(Series));
  957. extend(PieSeries.prototype, {
  958. axisTypes: [],
  959. directTouch: true,
  960. drawGraph: void 0,
  961. drawLegendSymbol: LegendSymbolMixin.drawRectangle,
  962. drawTracker: ColumnSeries.prototype.drawTracker,
  963. getCenter: CenteredSeriesMixin.getCenter,
  964. getSymbol: noop,
  965. isCartesian: false,
  966. noSharedTooltip: true,
  967. pointAttribs: ColumnSeries.prototype.pointAttribs,
  968. pointClass: PiePoint,
  969. requireSorting: false,
  970. searchPoint: noop,
  971. trackerGroups: ['group', 'dataLabelsGroup']
  972. });
  973. SeriesRegistry.registerSeriesType('pie', PieSeries);
  974. /* *
  975. *
  976. * Default Export
  977. *
  978. * */
  979. export default PieSeries;
  980. /* *
  981. *
  982. * API Options
  983. *
  984. * */
  985. /**
  986. * A `pie` series. If the [type](#series.pie.type) option is not specified,
  987. * it is inherited from [chart.type](#chart.type).
  988. *
  989. * @extends series,plotOptions.pie
  990. * @excluding cropThreshold, dataParser, dataURL, stack, xAxis, yAxis,
  991. * dataSorting, step, boostThreshold, boostBlending
  992. * @product highcharts
  993. * @apioption series.pie
  994. */
  995. /**
  996. * An array of data points for the series. For the `pie` series type,
  997. * points can be given in the following ways:
  998. *
  999. * 1. An array of numerical values. In this case, the numerical values will be
  1000. * interpreted as `y` options. Example:
  1001. * ```js
  1002. * data: [0, 5, 3, 5]
  1003. * ```
  1004. *
  1005. * 2. An array of objects with named values. The following snippet shows only a
  1006. * few settings, see the complete options set below. If the total number of
  1007. * data points exceeds the series'
  1008. * [turboThreshold](#series.pie.turboThreshold),
  1009. * this option is not available.
  1010. * ```js
  1011. * data: [{
  1012. * y: 1,
  1013. * name: "Point2",
  1014. * color: "#00FF00"
  1015. * }, {
  1016. * y: 7,
  1017. * name: "Point1",
  1018. * color: "#FF00FF"
  1019. * }]
  1020. * ```
  1021. *
  1022. * @sample {highcharts} highcharts/chart/reflow-true/
  1023. * Numerical values
  1024. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  1025. * Arrays of numeric x and y
  1026. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  1027. * Arrays of datetime x and y
  1028. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  1029. * Arrays of point.name and y
  1030. * @sample {highcharts} highcharts/series/data-array-of-objects/
  1031. * Config objects
  1032. *
  1033. * @type {Array<number|Array<string,(number|null)>|null|*>}
  1034. * @extends series.line.data
  1035. * @excluding marker, x
  1036. * @product highcharts
  1037. * @apioption series.pie.data
  1038. */
  1039. /**
  1040. * @type {Highcharts.SeriesPieDataLabelsOptionsObject}
  1041. * @product highcharts
  1042. * @apioption series.pie.data.dataLabels
  1043. */
  1044. /**
  1045. * The sequential index of the data point in the legend.
  1046. *
  1047. * @type {number}
  1048. * @product highcharts
  1049. * @apioption series.pie.data.legendIndex
  1050. */
  1051. /**
  1052. * Whether to display a slice offset from the center.
  1053. *
  1054. * @sample {highcharts} highcharts/point/sliced/
  1055. * One sliced point
  1056. *
  1057. * @type {boolean}
  1058. * @product highcharts
  1059. * @apioption series.pie.data.sliced
  1060. */
  1061. /**
  1062. * @extends plotOptions.pie.dataLabels
  1063. * @excluding align, allowOverlap, inside, staggerLines, step
  1064. * @product highcharts
  1065. * @apioption series.pie.dataLabels
  1066. */
  1067. /**
  1068. * @excluding legendItemClick
  1069. * @product highcharts
  1070. * @apioption series.pie.events
  1071. */
  1072. ''; // placeholder for transpiled doclets above