FlagsSeries.js 21 KB

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