PieSeries.js 46 KB

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