timeline.src.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. /**
  2. * @license Highcharts JS v7.0.2 (2019-01-17)
  3. * Timeline series
  4. *
  5. * (c) 2010-2019 Highsoft AS
  6. * Author: Daniel Studencki
  7. *
  8. * License: www.highcharts.com/license
  9. */
  10. 'use strict';
  11. (function (factory) {
  12. if (typeof module === 'object' && module.exports) {
  13. factory['default'] = factory;
  14. module.exports = factory;
  15. } else if (typeof define === 'function' && define.amd) {
  16. define(function () {
  17. return factory;
  18. });
  19. } else {
  20. factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
  21. }
  22. }(function (Highcharts) {
  23. (function (H) {
  24. /* *
  25. *
  26. * Experimental Timeline Series.
  27. * Note: This API is in alpha stage and will be changed before final release.
  28. *
  29. * (c) 2010-2019 Highsoft AS
  30. *
  31. * Author: Daniel Studencki
  32. *
  33. * License: www.highcharts.com/license
  34. *
  35. * */
  36. var addEvent = H.addEvent,
  37. extend = H.extend,
  38. defined = H.defined,
  39. LegendSymbolMixin = H.LegendSymbolMixin,
  40. TrackerMixin = H.TrackerMixin,
  41. merge = H.merge,
  42. pick = H.pick,
  43. Point = H.Point,
  44. Series = H.Series,
  45. undocumentedSeriesType = H.seriesType;
  46. /* *
  47. * The timeline series type.
  48. *
  49. * @private
  50. * @class
  51. * @name Highcharts.seriesTypes.timeline
  52. *
  53. * @augments Highcharts.Series
  54. */
  55. undocumentedSeriesType('timeline', 'line'
  56. /* *
  57. * The timeline series presents given events along a drawn line.
  58. *
  59. * @sample highcharts/series-timeline/alternate-labels Timeline series
  60. *
  61. * @extends plotOptions.line
  62. * @since 7.0.0
  63. * @product highcharts
  64. * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,
  65. * cropThreshold, dashStyle, findNearestPointBy,
  66. * getExtremesFromAll, lineWidth, negativeColor, pointInterval,
  67. * pointIntervalUnit, pointPlacement, pointStart, softThreshold,
  68. * stacking, step, threshold, turboThreshold, zoneAxis, zones
  69. * @optionparent plotOptions.timeline
  70. */
  71. , {
  72. colorByPoint: true,
  73. stickyTracking: false,
  74. ignoreHiddenPoint: true,
  75. legendType: 'point',
  76. lineWidth: 0,
  77. tooltip: {
  78. headerFormat: '<span style="color:{point.color}">● </span>' +
  79. '<span style="font-weight: bold;">{point.point.date}</span><br/>',
  80. pointFormat: '{point.description}'
  81. },
  82. states: {
  83. hover: {
  84. lineWidthPlus: 5,
  85. halo: {
  86. size: 0
  87. }
  88. }
  89. },
  90. dataLabels: {
  91. enabled: true,
  92. allowOverlap: true,
  93. /* *
  94. * The width of the line connecting the data label to the point.
  95. *
  96. *
  97. * In styled mode, the connector stroke width is given in the
  98. * `.highcharts-data-label-connector` class.
  99. *
  100. * @type {Number}
  101. * @default 1
  102. * @sample {highcharts} highcharts/series-timeline/connector-styles
  103. * Custom connector width and color
  104. */
  105. connectorWidth: 1,
  106. /* *
  107. * The color of the line connecting the data label to the point.
  108. *
  109. * In styled mode, the connector stroke is given in the
  110. * `.highcharts-data-label-connector` class.
  111. *
  112. * @type {String}
  113. * @sample {highcharts} highcharts/series-timeline/connector-styles
  114. * Custom connector width and color
  115. */
  116. connectorColor: '#000000',
  117. backgroundColor: '#ffffff',
  118. /* *
  119. * @type {Highcharts.FormatterCallbackFunction<object>}
  120. * @default function () {
  121. * var format;
  122. *
  123. * if (!this.series.chart.styledMode) {
  124. * format = '<span style="color:' + this.point.color +
  125. * '">● </span><span style="font-weight: bold;" > ' +
  126. * (this.point.date || '') + '</span><br/>' +
  127. * (this.point.label || '');
  128. * } else {
  129. * format = '<span>● </span>' +
  130. * '<span>' + (this.point.date || '') +
  131. * '</span><br/>' + (this.point.label || '');
  132. * }
  133. * return format;
  134. * }
  135. * @apioption plotOptions.timeline.dataLabels.formatter
  136. */
  137. formatter: function () {
  138. var format;
  139. if (!this.series.chart.styledMode) {
  140. format = '<span style="color:' + this.point.color +
  141. '">● </span><span style="font-weight: bold;" > ' +
  142. (this.point.date || '') + '</span><br/>' +
  143. (this.point.label || '');
  144. } else {
  145. format = '<span>● </span>' +
  146. '<span>' + (this.point.date || '') +
  147. '</span><br/>' + (this.point.label || '');
  148. }
  149. return format;
  150. },
  151. borderWidth: 1,
  152. borderColor: '#666666',
  153. /* *
  154. * A pixel value defining the distance between the data label
  155. * and the point. Negative numbers puts the label on top
  156. * of the point.
  157. *
  158. * @type {Number}
  159. * @default 100
  160. */
  161. distance: 100,
  162. /* *
  163. * Whether to position data labels alternately. For example, if
  164. * [distance](#plotOptions.timeline.dataLabels.distance) is set
  165. * equal to `100`, then the first data label 's distance will be
  166. * set equal to `100`, the second one equal to `-100`, and so on.
  167. *
  168. * @type {Boolean}
  169. * @default true
  170. * @sample {highcharts} highcharts/series-timeline/alternate-disabled
  171. * Alternate disabled
  172. */
  173. alternate: true,
  174. verticalAlign: 'middle',
  175. color: '#333333'
  176. },
  177. marker: {
  178. enabledThreshold: 0,
  179. symbol: 'square',
  180. height: 15
  181. }
  182. }
  183. /* *
  184. * @lends Highcharts.Series#
  185. */
  186. , {
  187. requireSorting: false,
  188. trackerGroups: ['markerGroup', 'dataLabelsGroup'],
  189. // Use a simple symbol from LegendSymbolMixin
  190. drawLegendSymbol: LegendSymbolMixin.drawRectangle,
  191. // Use a group of trackers from TrackerMixin
  192. drawTracker: TrackerMixin.drawTrackerPoint,
  193. init: function () {
  194. var series = this;
  195. Series.prototype.init.apply(series, arguments);
  196. // Distribute data labels before rendering them. Distribution is
  197. // based on the 'dataLabels.distance' and 'dataLabels.alternate'
  198. // property.
  199. addEvent(series, 'drawDataLabels', function () {
  200. // Delete the oldTextWidth parameter, in order to force
  201. // adjusting data label wrapper box width. It's needed only when
  202. // useHTML is enabled. This prevents the data label text getting
  203. // out of the box range.
  204. if (series.options.dataLabels.useHTML) {
  205. series.points.forEach(function (p) {
  206. if (p.visible && p.dataLabel) {
  207. delete p.dataLabel.text.oldTextWidth;
  208. }
  209. });
  210. }
  211. // Distribute data labels basing on defined algorithm.
  212. series.distributeDL();
  213. });
  214. addEvent(series, 'afterDrawDataLabels', function () {
  215. var seriesOptions = series.options,
  216. options = seriesOptions.dataLabels,
  217. hasRendered = series.hasRendered || 0,
  218. defer = pick(options.defer, !!seriesOptions.animation),
  219. connectorsGroup = series.connectorsGroup,
  220. dataLabel;
  221. // Create (or redraw) the group for all connectors.
  222. connectorsGroup = series.plotGroup(
  223. 'connectorsGroup',
  224. 'data-labels-connectors',
  225. defer && !hasRendered ? 'hidden' : 'visible',
  226. options.zIndex || 5
  227. );
  228. // Draw or align connector for each point.
  229. series.points.forEach(function (point) {
  230. dataLabel = point.dataLabel;
  231. if (dataLabel) {
  232. // Within this wrap method is necessary to save the
  233. // current animation params, because the data label
  234. // target position (after animation) is needed to align
  235. // connectors.
  236. dataLabel.animate = function (params) {
  237. if (this.targetPosition) {
  238. this.targetPosition = params;
  239. }
  240. return H.SVGElement.prototype.animate.apply(
  241. this,
  242. arguments
  243. );
  244. };
  245. // Initialize the targetPosition field within data label
  246. // object. It's necessary because there is need to know
  247. // expected position of specific data label, when
  248. // aligning connectors. This field is overrided inside
  249. // of SVGElement.animate() wrapped method.
  250. if (!dataLabel.targetPosition) {
  251. dataLabel.targetPosition = {};
  252. }
  253. return !point.connector ?
  254. point.drawConnector() :
  255. point.alignConnector();
  256. }
  257. });
  258. // Animate connectors group. It's animated in the same way like
  259. // dataLabels, and also depends on dataLabels.defer parameter.
  260. if (defer) {
  261. connectorsGroup.attr({
  262. opacity: +hasRendered
  263. });
  264. if (!hasRendered) {
  265. addEvent(series, 'afterAnimate', function () {
  266. if (series.visible) {
  267. connectorsGroup.show(true);
  268. }
  269. connectorsGroup[
  270. seriesOptions.animation ? 'animate' : 'attr'
  271. ]({
  272. opacity: 1
  273. }, {
  274. duration: 200
  275. });
  276. });
  277. }
  278. }
  279. });
  280. },
  281. alignDataLabel: function (point, dataLabel) {
  282. var series = this,
  283. isInverted = series.chart.inverted,
  284. visiblePoints = series.visibilityMap.filter(function (point) {
  285. return point;
  286. }),
  287. visiblePointsCount = series.visiblePointsCount,
  288. pointIndex = visiblePoints.indexOf(point),
  289. isFirstOrLast = !pointIndex ||
  290. pointIndex === visiblePointsCount - 1,
  291. dataLabelsOptions = series.options.dataLabels,
  292. userDLOptions = point.userDLOptions || {},
  293. // Define multiplier which is used to calculate data label
  294. // width. If data labels are alternate, they have two times more
  295. // space to adapt (excepting first and last ones, which has only
  296. // one and half), than in case of placing all data labels side
  297. // by side.
  298. multiplier = dataLabelsOptions.alternate ?
  299. (isFirstOrLast ? 1.5 : 2) :
  300. 1,
  301. distance,
  302. availableSpace = Math.floor(
  303. series.xAxis.len / visiblePointsCount
  304. ),
  305. pad = dataLabel.padding,
  306. targetDLWidth,
  307. styles;
  308. // Adjust data label width to the currently available space.
  309. if (point.visible) {
  310. distance = Math.abs(
  311. userDLOptions.x || point.options.dataLabels.x
  312. );
  313. if (isInverted) {
  314. targetDLWidth = (
  315. (distance - pad) * 2 - (point.itemHeight / 2)
  316. );
  317. styles = {
  318. width: targetDLWidth,
  319. // Apply ellipsis when data label height is exceeded.
  320. textOverflow: dataLabel.width / targetDLWidth *
  321. dataLabel.height / 2 > availableSpace * multiplier ?
  322. 'ellipsis' : 'none'
  323. };
  324. } else {
  325. styles = {
  326. width: userDLOptions.width ||
  327. dataLabelsOptions.width ||
  328. availableSpace * multiplier - (pad * 2)
  329. };
  330. }
  331. dataLabel.css(styles);
  332. if (!series.chart.styledMode) {
  333. dataLabel.shadow({});
  334. }
  335. }
  336. Series.prototype.alignDataLabel.apply(series, arguments);
  337. },
  338. processData: function () {
  339. var series = this,
  340. xMap = [],
  341. base,
  342. visiblePoints = 0,
  343. i;
  344. series.visibilityMap = series.getVisibilityMap();
  345. // Calculate currently visible points.
  346. series.visibilityMap.forEach(function (point) {
  347. if (point) {
  348. visiblePoints++;
  349. }
  350. });
  351. series.visiblePointsCount = visiblePoints;
  352. base = series.xAxis.options.max / visiblePoints;
  353. // Generate xData map.
  354. for (i = 1; i <= visiblePoints; i++) {
  355. xMap.push(
  356. (base * i) - (base / 2)
  357. );
  358. }
  359. // Set all hidden points y values as negatives, in order to move
  360. // them away from plot area. It is necessary to avoid hiding data
  361. // labels, when dataLabels.allowOverlap is set to false.
  362. series.visibilityMap.forEach(function (vis, i) {
  363. if (!vis) {
  364. xMap.splice(i, 0, series.yData[i] === null ? null : -99);
  365. }
  366. });
  367. series.xData = xMap;
  368. series.yData = xMap.map(function (data) {
  369. return defined(data) ? 1 : null;
  370. });
  371. Series.prototype.processData.call(this, arguments);
  372. },
  373. generatePoints: function () {
  374. var series = this;
  375. Series.prototype.generatePoints.apply(series);
  376. series.points.forEach(function (point, i) {
  377. point.applyOptions({
  378. x: series.xData[i]
  379. });
  380. });
  381. },
  382. getVisibilityMap: function () {
  383. var series = this,
  384. map = (series.data.length ?
  385. series.data : series.userOptions.data
  386. ).map(function (point) {
  387. return (
  388. point &&
  389. point.visible !== false &&
  390. !point.isNull
  391. ) ? point : false;
  392. });
  393. return map;
  394. },
  395. distributeDL: function () {
  396. var series = this,
  397. dataLabelsOptions = series.options.dataLabels,
  398. options,
  399. pointDLOptions,
  400. newOptions = {},
  401. visibilityIndex = 1,
  402. distance = dataLabelsOptions.distance;
  403. series.points.forEach(function (point) {
  404. if (point.visible && !point.isNull) {
  405. options = point.options;
  406. pointDLOptions = point.options.dataLabels;
  407. if (!series.hasRendered) {
  408. point.userDLOptions = merge({}, pointDLOptions);
  409. }
  410. newOptions[series.chart.inverted ? 'x' : 'y'] =
  411. dataLabelsOptions.alternate && visibilityIndex % 2 ?
  412. -distance : distance;
  413. options.dataLabels = merge(newOptions, point.userDLOptions);
  414. visibilityIndex++;
  415. }
  416. });
  417. },
  418. markerAttribs: function (point, state) {
  419. var series = this,
  420. seriesMarkerOptions = series.options.marker,
  421. seriesStateOptions,
  422. pointMarkerOptions = point.marker || {},
  423. symbol = (
  424. pointMarkerOptions.symbol || seriesMarkerOptions.symbol
  425. ),
  426. pointStateOptions,
  427. width = pick(
  428. pointMarkerOptions.width,
  429. seriesMarkerOptions.width,
  430. series.xAxis.len / series.visiblePointsCount
  431. ),
  432. height = pick(
  433. pointMarkerOptions.height,
  434. seriesMarkerOptions.height
  435. ),
  436. radius = 0,
  437. attribs;
  438. // Handle hover and select states
  439. if (state) {
  440. seriesStateOptions = seriesMarkerOptions.states[state] || {};
  441. pointStateOptions = pointMarkerOptions.states &&
  442. pointMarkerOptions.states[state] || {};
  443. radius = pick(
  444. pointStateOptions.radius,
  445. seriesStateOptions.radius,
  446. radius + (
  447. seriesStateOptions.radiusPlus ||
  448. 0
  449. )
  450. );
  451. }
  452. point.hasImage = symbol && symbol.indexOf('url') === 0;
  453. attribs = {
  454. x: Math.floor(point.plotX) - (width / 2) - (radius / 2),
  455. y: point.plotY - (height / 2) - (radius / 2),
  456. width: width + radius,
  457. height: height + radius
  458. };
  459. return attribs;
  460. },
  461. bindAxes: function () {
  462. var series = this,
  463. timelineXAxis = {
  464. gridLineWidth: 0,
  465. lineWidth: 0,
  466. min: 0,
  467. dataMin: 0,
  468. minPadding: 0,
  469. max: 100,
  470. dataMax: 100,
  471. maxPadding: 0,
  472. title: null,
  473. tickPositions: []
  474. },
  475. timelineYAxis = {
  476. gridLineWidth: 0,
  477. min: 0.5,
  478. dataMin: 0.5,
  479. minPadding: 0,
  480. max: 1.5,
  481. dataMax: 1.5,
  482. maxPadding: 0,
  483. title: null,
  484. labels: {
  485. enabled: false
  486. }
  487. };
  488. Series.prototype.bindAxes.call(series);
  489. extend(series.xAxis.options, timelineXAxis);
  490. extend(series.yAxis.options, timelineYAxis);
  491. }
  492. }
  493. /* *
  494. * @lends Highcharts.Point#
  495. */
  496. , {
  497. init: function () {
  498. var point = Point.prototype.init.apply(this, arguments);
  499. point.name = pick(point.name, point.date, 'Event');
  500. point.y = 1;
  501. return point;
  502. },
  503. // The setVisible method is taken from Pie series prototype, in order to
  504. // prevent importing whole Pie series.
  505. setVisible: function (vis, redraw) {
  506. var point = this,
  507. series = point.series,
  508. chart = series.chart,
  509. ignoreHiddenPoint = series.options.ignoreHiddenPoint;
  510. redraw = pick(redraw, ignoreHiddenPoint);
  511. if (vis !== point.visible) {
  512. // If called without an argument, toggle visibility
  513. point.visible = point.options.visible = vis =
  514. vis === undefined ? !point.visible : vis;
  515. // update userOptions.data
  516. series.options.data[series.data.indexOf(point)] = point.options;
  517. // Show and hide associated elements. This is performed
  518. // regardless of redraw or not, because chart.redraw only
  519. // handles full series.
  520. ['graphic', 'dataLabel', 'connector'].forEach(
  521. function (key) {
  522. if (point[key]) {
  523. point[key][vis ? 'show' : 'hide'](true);
  524. }
  525. }
  526. );
  527. if (point.legendItem) {
  528. chart.legend.colorizeItem(point, vis);
  529. }
  530. // #4170, hide halo after hiding point
  531. if (!vis && point.state === 'hover') {
  532. point.setState('');
  533. }
  534. // Handle ignore hidden slices
  535. if (ignoreHiddenPoint) {
  536. series.isDirty = true;
  537. }
  538. if (redraw) {
  539. chart.redraw();
  540. }
  541. }
  542. },
  543. setState: function () {
  544. var proceed = Series.prototype.pointClass.prototype.setState;
  545. // Prevent triggering the setState method on null points.
  546. if (!this.isNull) {
  547. proceed.apply(this, arguments);
  548. }
  549. },
  550. getConnectorPath: function () {
  551. var point = this,
  552. chart = point.series.chart,
  553. xAxisLen = point.series.xAxis.len,
  554. inverted = chart.inverted,
  555. direction = inverted ? 'x2' : 'y2',
  556. dl = point.dataLabel,
  557. targetDLPos = dl.targetPosition,
  558. coords = {
  559. x1: point.plotX,
  560. y1: point.plotY,
  561. x2: point.plotX,
  562. y2: targetDLPos.y || dl.y
  563. },
  564. negativeDistance = (
  565. coords[direction] < point.series.yAxis.len / 2
  566. ),
  567. path;
  568. // Recalculate coords when the chart is inverted.
  569. if (inverted) {
  570. coords = {
  571. x1: point.plotY,
  572. y1: xAxisLen - point.plotX,
  573. x2: targetDLPos.x || dl.x,
  574. y2: xAxisLen - point.plotX
  575. };
  576. }
  577. // Subtract data label width or height from expected coordinate so
  578. // that the connector would start from the appropriate edge.
  579. if (negativeDistance) {
  580. coords[direction] += dl[inverted ? 'width' : 'height'];
  581. }
  582. path = chart.renderer.crispLine([
  583. 'M',
  584. coords.x1,
  585. coords.y1,
  586. 'L',
  587. coords.x2,
  588. coords.y2
  589. ], dl.options.connectorWidth || 1);
  590. return path;
  591. },
  592. drawConnector: function () {
  593. var point = this,
  594. series = point.series,
  595. dlOptions = point.dataLabel.options = merge(
  596. {}, series.options.dataLabels,
  597. point.options.dataLabels
  598. );
  599. point.connector = series.chart.renderer
  600. .path(point.getConnectorPath())
  601. .add(series.connectorsGroup);
  602. if (!series.chart.styledMode) {
  603. point.connector.attr({
  604. stroke: dlOptions.connectorColor,
  605. 'stroke-width': dlOptions.connectorWidth,
  606. opacity: point.dataLabel.opacity
  607. });
  608. }
  609. },
  610. alignConnector: function () {
  611. var point = this,
  612. connector = point.connector,
  613. bBox = connector.getBBox(),
  614. isVisible = bBox.y > 0;
  615. connector[isVisible ? 'animate' : 'attr']({
  616. d: point.getConnectorPath()
  617. });
  618. }
  619. });
  620. // Hide/show connector related with a specific data label, after overlapping
  621. // detected.
  622. addEvent(H.Chart, 'afterHideOverlappingLabels', function () {
  623. var series = this.series,
  624. dataLabel,
  625. connector;
  626. series.forEach(function (series) {
  627. if (series.points) {
  628. series.points.forEach(function (point) {
  629. dataLabel = point.dataLabel;
  630. connector = point.connector;
  631. if (
  632. dataLabel &&
  633. dataLabel.targetPosition &&
  634. connector
  635. ) {
  636. connector.attr({
  637. opacity: dataLabel.targetPosition.opacity ||
  638. dataLabel.newOpacity
  639. });
  640. }
  641. });
  642. }
  643. });
  644. });
  645. /* *
  646. * The `timeline` series. If the [type](#series.timeline.type) option is
  647. * not specified, it is inherited from [chart.type](#chart.type).
  648. *
  649. * @extends series,plotOptions.timeline
  650. * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,
  651. * cropThreshold, dashStyle, dataParser, dataURL, findNearestPointBy,
  652. * getExtremesFromAll, lineWidth, negativeColor,
  653. * pointInterval, pointIntervalUnit, pointPlacement, pointStart,
  654. * softThreshold, stacking, stack, step, threshold, turboThreshold,
  655. * zoneAxis, zones
  656. * @product highcharts
  657. * @apioption series.timeline
  658. */
  659. /* *
  660. * An array of data points for the series. For the `timeline` series type,
  661. * points can be given with three general parameters, `date`, `label`,
  662. * and `description`:
  663. *
  664. * Example:
  665. *
  666. * ```js
  667. * series: [{
  668. * type: 'timeline',
  669. * data: [{
  670. * date: 'Jan 2018',
  671. * label: 'Some event label',
  672. * description: 'Description to show in tooltip'
  673. * }]
  674. * }]
  675. * ```
  676. *
  677. * @sample {highcharts} highcharts/series-timeline/alternate-labels
  678. * Alternate labels
  679. *
  680. * @type {Array<number|*>}
  681. * @extends series.line.data
  682. * @excluding marker, x, y
  683. * @product highcharts
  684. * @apioption series.timeline.data
  685. */
  686. /* *
  687. * The date of event.
  688. *
  689. * @type {string}
  690. * @product highcharts
  691. * @apioption series.timeline.data.date
  692. */
  693. /* *
  694. * The label of event.
  695. *
  696. * @type {string}
  697. * @product highcharts
  698. * @apioption series.timeline.data.label
  699. */
  700. /* *
  701. * The description of event. This description will be shown in tooltip.
  702. *
  703. * @type {string}
  704. * @product highcharts
  705. * @apioption series.timeline.data.description
  706. */
  707. }(Highcharts));
  708. return (function () {
  709. }());
  710. }));