FlagsSeries.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  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 FlagsPoint from './FlagsPoint.js';
  25. import H from '../../Core/Globals.js';
  26. var noop = H.noop;
  27. import OnSeriesMixin from '../../Mixins/OnSeries.js';
  28. import palette from '../../Core/Color/Palette.js';
  29. import SeriesRegistry from '../../Core/Series/SeriesRegistry.js';
  30. var Series = SeriesRegistry.series, ColumnSeries = SeriesRegistry.seriesTypes.column;
  31. import SVGElement from '../../Core/Renderer/SVG/SVGElement.js';
  32. import U from '../../Core/Utilities.js';
  33. var addEvent = U.addEvent, defined = U.defined, extend = U.extend, merge = U.merge, objectEach = U.objectEach, wrap = U.wrap;
  34. import './FlagsSymbols.js';
  35. /**
  36. * The Flags series.
  37. *
  38. * @private
  39. * @class
  40. * @name Highcharts.seriesTypes.flags
  41. *
  42. * @augments Highcharts.Series
  43. */
  44. var FlagsSeries = /** @class */ (function (_super) {
  45. __extends(FlagsSeries, _super);
  46. function FlagsSeries() {
  47. /* *
  48. *
  49. * Static Properties
  50. *
  51. * */
  52. var _this = _super !== null && _super.apply(this, arguments) || this;
  53. /* *
  54. *
  55. * Properties
  56. *
  57. * */
  58. _this.data = void 0;
  59. _this.options = void 0;
  60. _this.points = void 0;
  61. return _this;
  62. /* eslint-enable valid-jsdoc */
  63. }
  64. /* *
  65. *
  66. * Functions
  67. *
  68. * */
  69. /* eslint-disable valid-jsdoc */
  70. /**
  71. * Disable animation, but keep clipping (#8546).
  72. * @private
  73. */
  74. FlagsSeries.prototype.animate = function (init) {
  75. if (init) {
  76. this.setClip();
  77. }
  78. };
  79. /**
  80. * Draw the markers.
  81. * @private
  82. */
  83. FlagsSeries.prototype.drawPoints = function () {
  84. var series = this, points = series.points, chart = series.chart, renderer = chart.renderer, plotX, plotY, inverted = chart.inverted, options = series.options, optionsY = options.y, shape, i, point, graphic, stackIndex, anchorY, attribs, outsideRight, yAxis = series.yAxis, boxesMap = {}, boxes = [], centered;
  85. i = points.length;
  86. while (i--) {
  87. point = points[i];
  88. outsideRight =
  89. (inverted ? point.plotY : point.plotX) >
  90. series.xAxis.len;
  91. plotX = point.plotX;
  92. stackIndex = point.stackIndex;
  93. shape = point.options.shape || options.shape;
  94. plotY = point.plotY;
  95. if (typeof plotY !== 'undefined') {
  96. plotY = point.plotY + optionsY -
  97. (typeof stackIndex !== 'undefined' &&
  98. (stackIndex * options.stackDistance));
  99. }
  100. // skip connectors for higher level stacked points
  101. point.anchorX = stackIndex ? void 0 : point.plotX;
  102. anchorY = stackIndex ? void 0 : point.plotY;
  103. centered = shape !== 'flag';
  104. graphic = point.graphic;
  105. // Only draw the point if y is defined and the flag is within
  106. // the visible area
  107. if (typeof plotY !== 'undefined' &&
  108. plotX >= 0 &&
  109. !outsideRight) {
  110. // #15384
  111. if (graphic && point.hasNewShapeType()) {
  112. graphic = graphic.destroy();
  113. }
  114. // Create the flag
  115. if (!graphic) {
  116. graphic = point.graphic = renderer.label('', null, null, shape, null, null, options.useHTML)
  117. .addClass('highcharts-point')
  118. .add(series.markerGroup);
  119. // Add reference to the point for tracker (#6303)
  120. if (point.graphic.div) {
  121. point.graphic.div.point = point;
  122. }
  123. graphic.isNew = true;
  124. }
  125. graphic.attr({
  126. align: centered ? 'center' : 'left',
  127. width: options.width,
  128. height: options.height,
  129. 'text-align': options.textAlign
  130. });
  131. if (!chart.styledMode) {
  132. graphic
  133. .attr(series.pointAttribs(point))
  134. .css(merge(options.style, point.style))
  135. .shadow(options.shadow);
  136. }
  137. if (plotX > 0) { // #3119
  138. plotX -= graphic.strokeWidth() % 2; // #4285
  139. }
  140. // Plant the flag
  141. attribs = {
  142. y: plotY,
  143. anchorY: anchorY
  144. };
  145. if (options.allowOverlapX) {
  146. attribs.x = plotX;
  147. attribs.anchorX = point.anchorX;
  148. }
  149. graphic.attr({
  150. text: point.options.title || options.title || 'A'
  151. })[graphic.isNew ? 'attr' : 'animate'](attribs);
  152. // Rig for the distribute function
  153. if (!options.allowOverlapX) {
  154. if (!boxesMap[point.plotX]) {
  155. boxesMap[point.plotX] = {
  156. align: centered ? 0.5 : 0,
  157. size: graphic.width,
  158. target: plotX,
  159. anchorX: plotX
  160. };
  161. }
  162. else {
  163. boxesMap[point.plotX].size = Math.max(boxesMap[point.plotX].size, graphic.width);
  164. }
  165. }
  166. // Set the tooltip anchor position
  167. point.tooltipPos = [
  168. plotX,
  169. plotY + yAxis.pos - chart.plotTop
  170. ]; // #6327
  171. }
  172. else if (graphic) {
  173. point.graphic = graphic.destroy();
  174. }
  175. }
  176. // Handle X-dimension overlapping
  177. if (!options.allowOverlapX) {
  178. objectEach(boxesMap, function (box) {
  179. box.plotX = box.anchorX;
  180. boxes.push(box);
  181. });
  182. H.distribute(boxes, inverted ? yAxis.len : this.xAxis.len, 100);
  183. points.forEach(function (point) {
  184. var box = point.graphic && boxesMap[point.plotX];
  185. if (box) {
  186. point.graphic[point.graphic.isNew ? 'attr' : 'animate']({
  187. x: box.pos + box.align * box.size,
  188. anchorX: point.anchorX
  189. });
  190. // Hide flag when its box position is not specified
  191. // (#8573, #9299)
  192. if (!defined(box.pos)) {
  193. point.graphic.attr({
  194. x: -9999,
  195. anchorX: -9999
  196. });
  197. point.graphic.isNew = true;
  198. }
  199. else {
  200. point.graphic.isNew = false;
  201. }
  202. }
  203. });
  204. }
  205. // Can be a mix of SVG and HTML and we need events for both (#6303)
  206. if (options.useHTML) {
  207. wrap(series.markerGroup, 'on', function (proceed) {
  208. return SVGElement.prototype.on.apply(
  209. // for HTML
  210. // eslint-disable-next-line no-invalid-this
  211. proceed.apply(this, [].slice.call(arguments, 1)),
  212. // and for SVG
  213. [].slice.call(arguments, 1));
  214. });
  215. }
  216. };
  217. /**
  218. * Extend the column trackers with listeners to expand and contract
  219. * stacks.
  220. * @private
  221. */
  222. FlagsSeries.prototype.drawTracker = function () {
  223. var series = this, points = series.points;
  224. _super.prototype.drawTracker.call(this);
  225. /* *
  226. * Bring each stacked flag up on mouse over, this allows readability
  227. * of vertically stacked elements as well as tight points on the x
  228. * axis. #1924.
  229. */
  230. points.forEach(function (point) {
  231. var graphic = point.graphic;
  232. if (graphic) {
  233. if (point.unbindMouseOver) {
  234. point.unbindMouseOver();
  235. }
  236. point.unbindMouseOver = addEvent(graphic.element, 'mouseover', function () {
  237. // Raise this point
  238. if (point.stackIndex > 0 &&
  239. !point.raised) {
  240. point._y = graphic.y;
  241. graphic.attr({
  242. y: point._y - 8
  243. });
  244. point.raised = true;
  245. }
  246. // Revert other raised points
  247. points.forEach(function (otherPoint) {
  248. if (otherPoint !== point &&
  249. otherPoint.raised &&
  250. otherPoint.graphic) {
  251. otherPoint.graphic.attr({
  252. y: otherPoint._y
  253. });
  254. otherPoint.raised = false;
  255. }
  256. });
  257. });
  258. }
  259. });
  260. };
  261. /**
  262. * Get presentational attributes
  263. * @private
  264. */
  265. FlagsSeries.prototype.pointAttribs = function (point, state) {
  266. var options = this.options, color = (point && point.color) || this.color, lineColor = options.lineColor, lineWidth = (point && point.lineWidth), fill = (point && point.fillColor) || options.fillColor;
  267. if (state) {
  268. fill = options.states[state].fillColor;
  269. lineColor = options.states[state].lineColor;
  270. lineWidth = options.states[state].lineWidth;
  271. }
  272. return {
  273. fill: fill || color,
  274. stroke: lineColor || color,
  275. 'stroke-width': lineWidth || options.lineWidth || 0
  276. };
  277. };
  278. /**
  279. * @private
  280. */
  281. FlagsSeries.prototype.setClip = function () {
  282. Series.prototype.setClip.apply(this, arguments);
  283. if (this.options.clip !== false &&
  284. this.sharedClipKey &&
  285. this.markerGroup) {
  286. this.markerGroup.clip(this.chart.sharedClips[this.sharedClipKey]);
  287. }
  288. };
  289. /**
  290. * Flags are used to mark events in stock charts. They can be added on the
  291. * timeline, or attached to a specific series.
  292. *
  293. * @sample stock/demo/flags-general/
  294. * Flags on a line series
  295. *
  296. * @extends plotOptions.column
  297. * @excluding animation, borderColor, borderRadius, borderWidth,
  298. * colorByPoint, dataGrouping, pointPadding, pointWidth,
  299. * turboThreshold
  300. * @product highstock
  301. * @optionparent plotOptions.flags
  302. */
  303. FlagsSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  304. /**
  305. * In case the flag is placed on a series, on what point key to place
  306. * it. Line and columns have one key, `y`. In range or OHLC-type series,
  307. * however, the flag can optionally be placed on the `open`, `high`,
  308. * `low` or `close` key.
  309. *
  310. * @sample {highstock} stock/plotoptions/flags-onkey/
  311. * Range series, flag on high
  312. *
  313. * @type {string}
  314. * @default y
  315. * @since 4.2.2
  316. * @product highstock
  317. * @validvalue ["y", "open", "high", "low", "close"]
  318. * @apioption plotOptions.flags.onKey
  319. */
  320. /**
  321. * The id of the series that the flags should be drawn on. If no id
  322. * is given, the flags are drawn on the x axis.
  323. *
  324. * @sample {highstock} stock/plotoptions/flags/
  325. * Flags on series and on x axis
  326. *
  327. * @type {string}
  328. * @product highstock
  329. * @apioption plotOptions.flags.onSeries
  330. */
  331. pointRange: 0,
  332. /**
  333. * Whether the flags are allowed to overlap sideways. If `false`, the
  334. * flags are moved sideways using an algorithm that seeks to place every
  335. * flag as close as possible to its original position.
  336. *
  337. * @sample {highstock} stock/plotoptions/flags-allowoverlapx
  338. * Allow sideways overlap
  339. *
  340. * @since 6.0.4
  341. */
  342. allowOverlapX: false,
  343. /**
  344. * The shape of the marker. Can be one of "flag", "circlepin",
  345. * "squarepin", or an image of the format `url(/path-to-image.jpg)`.
  346. * Individual shapes can also be set for each point.
  347. *
  348. * @sample {highstock} stock/plotoptions/flags/
  349. * Different shapes
  350. *
  351. * @type {Highcharts.FlagsShapeValue}
  352. * @product highstock
  353. */
  354. shape: 'flag',
  355. /**
  356. * When multiple flags in the same series fall on the same value, this
  357. * number determines the vertical offset between them.
  358. *
  359. * @sample {highstock} stock/plotoptions/flags-stackdistance/
  360. * A greater stack distance
  361. *
  362. * @product highstock
  363. */
  364. stackDistance: 12,
  365. /**
  366. * Text alignment for the text inside the flag.
  367. *
  368. * @since 5.0.0
  369. * @product highstock
  370. * @validvalue ["left", "center", "right"]
  371. */
  372. textAlign: 'center',
  373. /**
  374. * Specific tooltip options for flag series. Flag series tooltips are
  375. * different from most other types in that a flag doesn't have a data
  376. * value, so the tooltip rather displays the `text` option for each
  377. * point.
  378. *
  379. * @extends plotOptions.series.tooltip
  380. * @excluding changeDecimals, valueDecimals, valuePrefix, valueSuffix
  381. * @product highstock
  382. */
  383. tooltip: {
  384. pointFormat: '{point.text}'
  385. },
  386. threshold: null,
  387. /**
  388. * The text to display on each flag. This can be defined on series
  389. * level, or individually for each point. Defaults to `"A"`.
  390. *
  391. * @type {string}
  392. * @default A
  393. * @product highstock
  394. * @apioption plotOptions.flags.title
  395. */
  396. /**
  397. * The y position of the top left corner of the flag relative to either
  398. * the series (if onSeries is defined), or the x axis. Defaults to
  399. * `-30`.
  400. *
  401. * @product highstock
  402. */
  403. y: -30,
  404. /**
  405. * Whether to use HTML to render the flag texts. Using HTML allows for
  406. * advanced formatting, images and reliable bi-directional text
  407. * rendering. Note that exported images won't respect the HTML, and that
  408. * HTML won't respect Z-index settings.
  409. *
  410. * @type {boolean}
  411. * @default false
  412. * @since 1.3
  413. * @product highstock
  414. * @apioption plotOptions.flags.useHTML
  415. */
  416. /**
  417. * Fixed width of the flag's shape. By default, width is autocalculated
  418. * according to the flag's title.
  419. *
  420. * @sample {highstock} stock/demo/flags-shapes/
  421. * Flags with fixed width
  422. *
  423. * @type {number}
  424. * @product highstock
  425. * @apioption plotOptions.flags.width
  426. */
  427. /**
  428. * Fixed height of the flag's shape. By default, height is
  429. * autocalculated according to the flag's title.
  430. *
  431. * @type {number}
  432. * @product highstock
  433. * @apioption plotOptions.flags.height
  434. */
  435. /**
  436. * The fill color for the flags.
  437. *
  438. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  439. * @product highstock
  440. */
  441. fillColor: palette.backgroundColor,
  442. /**
  443. * The color of the line/border of the flag.
  444. *
  445. * In styled mode, the stroke is set in the
  446. * `.highcharts-flag-series.highcharts-point` rule.
  447. *
  448. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  449. * @default #000000
  450. * @product highstock
  451. * @apioption plotOptions.flags.lineColor
  452. */
  453. /**
  454. * The pixel width of the flag's line/border.
  455. *
  456. * @product highstock
  457. */
  458. lineWidth: 1,
  459. states: {
  460. /**
  461. * @extends plotOptions.column.states.hover
  462. * @product highstock
  463. */
  464. hover: {
  465. /**
  466. * The color of the line/border of the flag.
  467. *
  468. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  469. * @product highstock
  470. */
  471. lineColor: palette.neutralColor100,
  472. /**
  473. * The fill or background color of the flag.
  474. *
  475. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  476. * @product highstock
  477. */
  478. fillColor: palette.highlightColor20
  479. }
  480. },
  481. /**
  482. * The text styles of the flag.
  483. *
  484. * In styled mode, the styles are set in the
  485. * `.highcharts-flag-series .highcharts-point` rule.
  486. *
  487. * @type {Highcharts.CSSObject}
  488. * @default {"fontSize": "11px", "fontWeight": "bold"}
  489. * @product highstock
  490. */
  491. style: {
  492. /** @ignore-option */
  493. fontSize: '11px',
  494. /** @ignore-option */
  495. fontWeight: 'bold'
  496. }
  497. });
  498. return FlagsSeries;
  499. }(ColumnSeries));
  500. extend(FlagsSeries.prototype, {
  501. allowDG: false,
  502. /**
  503. * @private
  504. * @function Highcharts.seriesTypes.flags#buildKDTree
  505. */
  506. buildKDTree: noop,
  507. forceCrop: true,
  508. getPlotBox: OnSeriesMixin.getPlotBox,
  509. /**
  510. * Inherit the initialization from base Series.
  511. *
  512. * @private
  513. * @borrows Highcharts.Series#init as Highcharts.seriesTypes.flags#init
  514. */
  515. init: Series.prototype.init,
  516. /**
  517. * Don't invert the flag marker group (#4960).
  518. *
  519. * @private
  520. * @function Highcharts.seriesTypes.flags#invertGroups
  521. */
  522. invertGroups: noop,
  523. // Flags series group should not be invertible (#14063).
  524. invertible: false,
  525. noSharedTooltip: true,
  526. pointClass: FlagsPoint,
  527. sorted: false,
  528. takeOrdinalPosition: false,
  529. trackerGroups: ['markerGroup'],
  530. translate: OnSeriesMixin.translate
  531. });
  532. SeriesRegistry.registerSeriesType('flags', FlagsSeries);
  533. /* *
  534. *
  535. * Default Export
  536. *
  537. * */
  538. export default FlagsSeries;
  539. /* *
  540. *
  541. * API Declarations
  542. *
  543. * */
  544. /**
  545. * @typedef {"circlepin"|"flag"|"squarepin"} Highcharts.FlagsShapeValue
  546. */
  547. ''; // detach doclets above
  548. /* *
  549. *
  550. * API Option
  551. *
  552. * */
  553. /**
  554. * A `flags` series. If the [type](#series.flags.type) option is not
  555. * specified, it is inherited from [chart.type](#chart.type).
  556. *
  557. * @extends series,plotOptions.flags
  558. * @excluding animation, borderColor, borderRadius, borderWidth, colorByPoint,
  559. * connectNulls, dashStyle, dataGrouping, dataParser, dataURL,
  560. * gapSize, gapUnit, linecap, lineWidth, marker, pointPadding,
  561. * pointWidth, step, turboThreshold, useOhlcData
  562. * @product highstock
  563. * @apioption series.flags
  564. */
  565. /**
  566. * An array of data points for the series. For the `flags` series type,
  567. * points can be given in the following ways:
  568. *
  569. * 1. An array of objects with named values. The following snippet shows only a
  570. * few settings, see the complete options set below. If the total number of
  571. * data points exceeds the series'
  572. * [turboThreshold](#series.flags.turboThreshold), this option is not
  573. * available.
  574. * ```js
  575. * data: [{
  576. * x: 1,
  577. * title: "A",
  578. * text: "First event"
  579. * }, {
  580. * x: 1,
  581. * title: "B",
  582. * text: "Second event"
  583. * }]
  584. * ```
  585. *
  586. * @type {Array<*>}
  587. * @extends series.line.data
  588. * @excluding dataLabels, marker, name, y
  589. * @product highstock
  590. * @apioption series.flags.data
  591. */
  592. /**
  593. * The fill color of an individual flag. By default it inherits from
  594. * the series color.
  595. *
  596. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  597. * @product highstock
  598. * @apioption series.flags.data.fillColor
  599. */
  600. /**
  601. * The longer text to be shown in the flag's tooltip.
  602. *
  603. * @type {string}
  604. * @product highstock
  605. * @apioption series.flags.data.text
  606. */
  607. /**
  608. * The short text to be shown on the flag.
  609. *
  610. * @type {string}
  611. * @product highstock
  612. * @apioption series.flags.data.title
  613. */
  614. ''; // adds doclets above to transpiled file