LineSeries.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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 palette from '../../Core/Color/Palette.js';
  25. import Series from '../../Core/Series/Series.js';
  26. import SeriesRegistry from '../../Core/Series/SeriesRegistry.js';
  27. import U from '../../Core/Utilities.js';
  28. var defined = U.defined, merge = U.merge;
  29. /* *
  30. *
  31. * Class
  32. *
  33. * */
  34. /**
  35. * The line series is the base type and is therefor the series base prototype.
  36. *
  37. * @private
  38. */
  39. var LineSeries = /** @class */ (function (_super) {
  40. __extends(LineSeries, _super);
  41. function LineSeries() {
  42. /* *
  43. *
  44. * Static Functions
  45. *
  46. * */
  47. var _this = _super !== null && _super.apply(this, arguments) || this;
  48. /* *
  49. *
  50. * Properties
  51. *
  52. * */
  53. _this.data = void 0;
  54. _this.options = void 0;
  55. _this.points = void 0;
  56. return _this;
  57. }
  58. /* *
  59. *
  60. * Functions
  61. *
  62. * */
  63. /**
  64. * Draw the graph. Called internally when rendering line-like series
  65. * types. The first time it generates the `series.graph` item and
  66. * optionally other series-wide items like `series.area` for area
  67. * charts. On subsequent calls these items are updated with new
  68. * positions and attributes.
  69. *
  70. * @function Highcharts.Series#drawGraph
  71. */
  72. LineSeries.prototype.drawGraph = function () {
  73. var series = this, options = this.options, graphPath = (this.gappedPath || this.getGraphPath).call(this), styledMode = this.chart.styledMode, props = [[
  74. 'graph',
  75. 'highcharts-graph'
  76. ]];
  77. // Presentational properties
  78. if (!styledMode) {
  79. props[0].push((options.lineColor ||
  80. this.color ||
  81. palette.neutralColor20 // when colorByPoint = true
  82. ), options.dashStyle);
  83. }
  84. props = series.getZonesGraphs(props);
  85. // Draw the graph
  86. props.forEach(function (prop, i) {
  87. var graphKey = prop[0], graph = series[graphKey], verb = graph ? 'animate' : 'attr', attribs;
  88. if (graph) {
  89. graph.endX = series.preventGraphAnimation ?
  90. null :
  91. graphPath.xMap;
  92. graph.animate({ d: graphPath });
  93. }
  94. else if (graphPath.length) { // #1487
  95. /**
  96. * SVG element of area-based charts. Can be used for styling
  97. * purposes. If zones are configured, this element will be
  98. * hidden and replaced by multiple zone areas, accessible
  99. * via `series['zone-area-x']` (where x is a number,
  100. * starting with 0).
  101. *
  102. * @name Highcharts.Series#area
  103. * @type {Highcharts.SVGElement|undefined}
  104. */
  105. /**
  106. * SVG element of line-based charts. Can be used for styling
  107. * purposes. If zones are configured, this element will be
  108. * hidden and replaced by multiple zone lines, accessible
  109. * via `series['zone-graph-x']` (where x is a number,
  110. * starting with 0).
  111. *
  112. * @name Highcharts.Series#graph
  113. * @type {Highcharts.SVGElement|undefined}
  114. */
  115. series[graphKey] = graph = series.chart.renderer
  116. .path(graphPath)
  117. .addClass(prop[1])
  118. .attr({ zIndex: 1 }) // #1069
  119. .add(series.group);
  120. }
  121. if (graph && !styledMode) {
  122. attribs = {
  123. 'stroke': prop[2],
  124. 'stroke-width': options.lineWidth,
  125. // Polygon series use filled graph
  126. 'fill': (series.fillGraph && series.color) || 'none'
  127. };
  128. if (prop[3]) {
  129. attribs.dashstyle = prop[3];
  130. }
  131. else if (options.linecap !== 'square') {
  132. attribs['stroke-linecap'] =
  133. attribs['stroke-linejoin'] = 'round';
  134. }
  135. graph[verb](attribs)
  136. // Add shadow to normal series (0) or to first
  137. // zone (1) #3932
  138. .shadow((i < 2) && options.shadow);
  139. }
  140. // Helpers for animation
  141. if (graph) {
  142. graph.startX = graphPath.xMap;
  143. graph.isArea = graphPath.isArea; // For arearange animation
  144. }
  145. });
  146. };
  147. // eslint-disable-next-line valid-jsdoc
  148. /**
  149. * Get the graph path.
  150. *
  151. * @private
  152. */
  153. LineSeries.prototype.getGraphPath = function (points, nullsAsZeroes, connectCliffs) {
  154. var series = this, options = series.options, step = options.step, reversed, graphPath = [], xMap = [], gap;
  155. points = points || series.points;
  156. // Bottom of a stack is reversed
  157. reversed = points.reversed;
  158. if (reversed) {
  159. points.reverse();
  160. }
  161. // Reverse the steps (#5004)
  162. step = {
  163. right: 1,
  164. center: 2
  165. }[step] || (step && 3);
  166. if (step && reversed) {
  167. step = 4 - step;
  168. }
  169. // Remove invalid points, especially in spline (#5015)
  170. points = this.getValidPoints(points, false, !(options.connectNulls && !nullsAsZeroes && !connectCliffs));
  171. // Build the line
  172. points.forEach(function (point, i) {
  173. var plotX = point.plotX, plotY = point.plotY, lastPoint = points[i - 1],
  174. // the path to this point from the previous
  175. pathToPoint;
  176. if ((point.leftCliff || (lastPoint && lastPoint.rightCliff)) &&
  177. !connectCliffs) {
  178. gap = true; // ... and continue
  179. }
  180. // Line series, nullsAsZeroes is not handled
  181. if (point.isNull && !defined(nullsAsZeroes) && i > 0) {
  182. gap = !options.connectNulls;
  183. // Area series, nullsAsZeroes is set
  184. }
  185. else if (point.isNull && !nullsAsZeroes) {
  186. gap = true;
  187. }
  188. else {
  189. if (i === 0 || gap) {
  190. pathToPoint = [[
  191. 'M',
  192. point.plotX,
  193. point.plotY
  194. ]];
  195. // Generate the spline as defined in the SplineSeries object
  196. }
  197. else if (series.getPointSpline) {
  198. pathToPoint = [series.getPointSpline(points, point, i)];
  199. }
  200. else if (step) {
  201. if (step === 1) { // right
  202. pathToPoint = [[
  203. 'L',
  204. lastPoint.plotX,
  205. plotY
  206. ]];
  207. }
  208. else if (step === 2) { // center
  209. pathToPoint = [[
  210. 'L',
  211. (lastPoint.plotX + plotX) / 2,
  212. lastPoint.plotY
  213. ], [
  214. 'L',
  215. (lastPoint.plotX + plotX) / 2,
  216. plotY
  217. ]];
  218. }
  219. else {
  220. pathToPoint = [[
  221. 'L',
  222. plotX,
  223. lastPoint.plotY
  224. ]];
  225. }
  226. pathToPoint.push([
  227. 'L',
  228. plotX,
  229. plotY
  230. ]);
  231. }
  232. else {
  233. // normal line to next point
  234. pathToPoint = [[
  235. 'L',
  236. plotX,
  237. plotY
  238. ]];
  239. }
  240. // Prepare for animation. When step is enabled, there are
  241. // two path nodes for each x value.
  242. xMap.push(point.x);
  243. if (step) {
  244. xMap.push(point.x);
  245. if (step === 2) { // step = center (#8073)
  246. xMap.push(point.x);
  247. }
  248. }
  249. graphPath.push.apply(graphPath, pathToPoint);
  250. gap = false;
  251. }
  252. });
  253. graphPath.xMap = xMap;
  254. series.graphPath = graphPath;
  255. return graphPath;
  256. };
  257. // eslint-disable-next-line valid-jsdoc
  258. /**
  259. * Get zones properties for building graphs. Extendable by series with
  260. * multiple lines within one series.
  261. *
  262. * @private
  263. */
  264. LineSeries.prototype.getZonesGraphs = function (props) {
  265. // Add the zone properties if any
  266. this.zones.forEach(function (zone, i) {
  267. var propset = [
  268. 'zone-graph-' + i,
  269. 'highcharts-graph highcharts-zone-graph-' + i + ' ' +
  270. (zone.className || '')
  271. ];
  272. if (!this.chart.styledMode) {
  273. propset.push((zone.color || this.color), (zone.dashStyle || this.options.dashStyle));
  274. }
  275. props.push(propset);
  276. }, this);
  277. return props;
  278. };
  279. /**
  280. * General options for all series types.
  281. *
  282. * @optionparent plotOptions.series
  283. */
  284. LineSeries.defaultOptions = merge(Series.defaultOptions, {
  285. // nothing here yet
  286. });
  287. return LineSeries;
  288. }(Series));
  289. SeriesRegistry.registerSeriesType('line', LineSeries);
  290. /* *
  291. *
  292. * Default Export
  293. *
  294. * */
  295. export default LineSeries;
  296. /* *
  297. *
  298. * API Options
  299. *
  300. * */
  301. /**
  302. * A line series displays information as a series of data points connected by
  303. * straight line segments.
  304. *
  305. * @sample {highcharts} highcharts/demo/line-basic/
  306. * Line chart
  307. * @sample {highstock} stock/demo/basic-line/
  308. * Line chart
  309. *
  310. * @extends plotOptions.series
  311. * @product highcharts highstock
  312. * @apioption plotOptions.line
  313. */
  314. /**
  315. * The SVG value used for the `stroke-linecap` and `stroke-linejoin`
  316. * of a line graph. Round means that lines are rounded in the ends and
  317. * bends.
  318. *
  319. * @type {Highcharts.SeriesLinecapValue}
  320. * @default round
  321. * @since 3.0.7
  322. * @apioption plotOptions.line.linecap
  323. */
  324. /**
  325. * A `line` series. If the [type](#series.line.type) option is not
  326. * specified, it is inherited from [chart.type](#chart.type).
  327. *
  328. * @extends series,plotOptions.line
  329. * @excluding dataParser,dataURL
  330. * @product highcharts highstock
  331. * @apioption series.line
  332. */
  333. /**
  334. * An array of data points for the series. For the `line` series type,
  335. * points can be given in the following ways:
  336. *
  337. * 1. An array of numerical values. In this case, the numerical values will be
  338. * interpreted as `y` options. The `x` values will be automatically
  339. * calculated, either starting at 0 and incremented by 1, or from
  340. * `pointStart` and `pointInterval` given in the series options. If the axis
  341. * has categories, these will be used. Example:
  342. * ```js
  343. * data: [0, 5, 3, 5]
  344. * ```
  345. *
  346. * 2. An array of arrays with 2 values. In this case, the values correspond to
  347. * `x,y`. If the first value is a string, it is applied as the name of the
  348. * point, and the `x` value is inferred.
  349. * ```js
  350. * data: [
  351. * [0, 1],
  352. * [1, 2],
  353. * [2, 8]
  354. * ]
  355. * ```
  356. *
  357. * 3. An array of objects with named values. The following snippet shows only a
  358. * few settings, see the complete options set below. If the total number of
  359. * data points exceeds the series'
  360. * [turboThreshold](#series.line.turboThreshold),
  361. * this option is not available.
  362. * ```js
  363. * data: [{
  364. * x: 1,
  365. * y: 9,
  366. * name: "Point2",
  367. * color: "#00FF00"
  368. * }, {
  369. * x: 1,
  370. * y: 6,
  371. * name: "Point1",
  372. * color: "#FF00FF"
  373. * }]
  374. * ```
  375. *
  376. * **Note:** In TypeScript you have to extend `PointOptionsObject` with an
  377. * additional declaration to allow custom data types:
  378. * ```ts
  379. * declare module `highcharts` {
  380. * interface PointOptionsObject {
  381. * custom: Record<string, (boolean|number|string)>;
  382. * }
  383. * }
  384. * ```
  385. *
  386. * @sample {highcharts} highcharts/chart/reflow-true/
  387. * Numerical values
  388. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  389. * Arrays of numeric x and y
  390. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  391. * Arrays of datetime x and y
  392. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  393. * Arrays of point.name and y
  394. * @sample {highcharts} highcharts/series/data-array-of-objects/
  395. * Config objects
  396. *
  397. * @declare Highcharts.PointOptionsObject
  398. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  399. * @apioption series.line.data
  400. */
  401. /**
  402. * An additional, individual class name for the data point's graphic
  403. * representation.
  404. *
  405. * @type {string}
  406. * @since 5.0.0
  407. * @product highcharts gantt
  408. * @apioption series.line.data.className
  409. */
  410. /**
  411. * Individual color for the point. By default the color is pulled from
  412. * the global `colors` array.
  413. *
  414. * In styled mode, the `color` option doesn't take effect. Instead, use
  415. * `colorIndex`.
  416. *
  417. * @sample {highcharts} highcharts/point/color/
  418. * Mark the highest point
  419. *
  420. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  421. * @product highcharts highstock gantt
  422. * @apioption series.line.data.color
  423. */
  424. /**
  425. * A specific color index to use for the point, so its graphic representations
  426. * are given the class name `highcharts-color-{n}`. In styled mode this will
  427. * change the color of the graphic. In non-styled mode, the color by is set by
  428. * the `fill` attribute, so the change in class name won't have a visual effect
  429. * by default.
  430. *
  431. * @type {number}
  432. * @since 5.0.0
  433. * @product highcharts gantt
  434. * @apioption series.line.data.colorIndex
  435. */
  436. /**
  437. * A reserved subspace to store options and values for customized functionality.
  438. * Here you can add additional data for your own event callbacks and formatter
  439. * callbacks.
  440. *
  441. * @sample {highcharts} highcharts/point/custom/
  442. * Point and series with custom data
  443. *
  444. * @type {Highcharts.Dictionary<*>}
  445. * @apioption series.line.data.custom
  446. */
  447. /**
  448. * Individual data label for each point. The options are the same as
  449. * the ones for [plotOptions.series.dataLabels](
  450. * #plotOptions.series.dataLabels).
  451. *
  452. * @sample highcharts/point/datalabels/
  453. * Show a label for the last value
  454. *
  455. * @declare Highcharts.DataLabelsOptions
  456. * @extends plotOptions.line.dataLabels
  457. * @product highcharts highstock gantt
  458. * @apioption series.line.data.dataLabels
  459. */
  460. /**
  461. * A description of the point to add to the screen reader information
  462. * about the point.
  463. *
  464. * @type {string}
  465. * @since 5.0.0
  466. * @requires modules/accessibility
  467. * @apioption series.line.data.description
  468. */
  469. /**
  470. * An id for the point. This can be used after render time to get a
  471. * pointer to the point object through `chart.get()`.
  472. *
  473. * @sample {highcharts} highcharts/point/id/
  474. * Remove an id'd point
  475. *
  476. * @type {string}
  477. * @since 1.2.0
  478. * @product highcharts highstock gantt
  479. * @apioption series.line.data.id
  480. */
  481. /**
  482. * The rank for this point's data label in case of collision. If two
  483. * data labels are about to overlap, only the one with the highest `labelrank`
  484. * will be drawn.
  485. *
  486. * @type {number}
  487. * @apioption series.line.data.labelrank
  488. */
  489. /**
  490. * The name of the point as shown in the legend, tooltip, dataLabels, etc.
  491. *
  492. * @see [xAxis.uniqueNames](#xAxis.uniqueNames)
  493. *
  494. * @sample {highcharts} highcharts/series/data-array-of-objects/
  495. * Point names
  496. *
  497. * @type {string}
  498. * @apioption series.line.data.name
  499. */
  500. /**
  501. * Whether the data point is selected initially.
  502. *
  503. * @type {boolean}
  504. * @default false
  505. * @product highcharts highstock gantt
  506. * @apioption series.line.data.selected
  507. */
  508. /**
  509. * The x value of the point. For datetime axes, the X value is the timestamp
  510. * in milliseconds since 1970.
  511. *
  512. * @type {number}
  513. * @product highcharts highstock
  514. * @apioption series.line.data.x
  515. */
  516. /**
  517. * The y value of the point.
  518. *
  519. * @type {number|null}
  520. * @product highcharts highstock
  521. * @apioption series.line.data.y
  522. */
  523. /**
  524. * The individual point events.
  525. *
  526. * @extends plotOptions.series.point.events
  527. * @product highcharts highstock gantt
  528. * @apioption series.line.data.events
  529. */
  530. /**
  531. * Options for the point markers of line-like series.
  532. *
  533. * @declare Highcharts.PointMarkerOptionsObject
  534. * @extends plotOptions.series.marker
  535. * @product highcharts highstock
  536. * @apioption series.line.data.marker
  537. */
  538. ''; // include precedent doclets in transpilat