DumbbellSeries.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /* *
  2. *
  3. * (c) 2010-2020 Sebastian Bochan, Rafal Sebestjanski
  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. var SVGRenderer = H.SVGRenderer;
  13. import U from '../Core/Utilities.js';
  14. var extend = U.extend, pick = U.pick, seriesType = U.seriesType;
  15. import './AreaRangeSeries.js';
  16. var seriesTypes = H.seriesTypes, seriesProto = H.Series.prototype, areaRangeProto = seriesTypes.arearange.prototype, columnRangeProto = seriesTypes.columnrange.prototype, colProto = seriesTypes.column.prototype, areaRangePointProto = areaRangeProto.pointClass.prototype;
  17. /**
  18. * The dumbbell series is a cartesian series with higher and lower values for
  19. * each point along an X axis, connected with a line between the values.
  20. * Requires `highcharts-more.js` and `modules/dumbbell.js`.
  21. *
  22. * @sample {highcharts} highcharts/demo/dumbbell/
  23. * Dumbbell chart
  24. * @sample {highcharts} highcharts/series-dumbbell/styled-mode-dumbbell/
  25. * Styled mode
  26. *
  27. * @extends plotOptions.arearange
  28. * @product highcharts highstock
  29. * @excluding fillColor, fillOpacity, lineWidth, stack, stacking,
  30. * stickyTracking, trackByArea, boostThreshold, boostBlending
  31. * @since 8.0.0
  32. * @optionparent plotOptions.dumbbell
  33. */
  34. seriesType('dumbbell', 'arearange', {
  35. /** @ignore-option */
  36. trackByArea: false,
  37. /** @ignore-option */
  38. fillColor: 'none',
  39. /** @ignore-option */
  40. lineWidth: 0,
  41. pointRange: 1,
  42. /**
  43. * Pixel width of the line that connects the dumbbell point's values.
  44. *
  45. * @since 8.0.0
  46. * @product highcharts highstock
  47. */
  48. connectorWidth: 1,
  49. /** @ignore-option */
  50. stickyTracking: false,
  51. groupPadding: 0.2,
  52. crisp: false,
  53. pointPadding: 0.1,
  54. /**
  55. * Color of the start markers in a dumbbell graph.
  56. *
  57. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  58. * @since 8.0.0
  59. * @product highcharts highstock
  60. */
  61. lowColor: '#333333',
  62. /**
  63. * Color of the line that connects the dumbbell point's values.
  64. * By default it is the series' color.
  65. *
  66. * @type {string}
  67. * @product highcharts highstock
  68. * @since 8.0.0
  69. * @apioption plotOptions.dumbbell.connectorColor
  70. */
  71. states: {
  72. hover: {
  73. /** @ignore-option */
  74. lineWidthPlus: 0,
  75. /**
  76. * The additional connector line width for a hovered point.
  77. *
  78. * @since 8.0.0
  79. * @product highcharts highstock
  80. */
  81. connectorWidthPlus: 1,
  82. /** @ignore-option */
  83. halo: false
  84. }
  85. }
  86. }, {
  87. trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
  88. drawTracker: H.TrackerMixin.drawTrackerPoint,
  89. drawGraph: H.noop,
  90. crispCol: colProto.crispCol,
  91. /**
  92. * Get connector line path and styles that connects dumbbell point's low and
  93. * high values.
  94. * @private
  95. *
  96. * @param {Highcharts.Series} this The series of points.
  97. * @param {Highcharts.Point} point The point to inspect.
  98. *
  99. * @return {Highcharts.SVGAttributes} attribs The path and styles.
  100. */
  101. getConnectorAttribs: function (point) {
  102. var series = this, chart = series.chart, pointOptions = point.options, seriesOptions = series.options, xAxis = series.xAxis, yAxis = series.yAxis, connectorWidth = pick(pointOptions.connectorWidth, seriesOptions.connectorWidth), connectorColor = pick(pointOptions.connectorColor, seriesOptions.connectorColor, pointOptions.color, point.zone ? point.zone.color : void 0, point.color), connectorWidthPlus = pick(seriesOptions.states &&
  103. seriesOptions.states.hover &&
  104. seriesOptions.states.hover.connectorWidthPlus, 1), dashStyle = pick(pointOptions.dashStyle, seriesOptions.dashStyle), pointTop = pick(point.plotLow, point.plotY), pxThreshold = yAxis.toPixels(seriesOptions.threshold || 0, true), pointHeight = chart.inverted ?
  105. yAxis.len - pxThreshold : pxThreshold, pointBottom = pick(point.plotHigh, pointHeight), attribs, origProps;
  106. if (point.state) {
  107. connectorWidth = connectorWidth + connectorWidthPlus;
  108. }
  109. if (pointTop < 0) {
  110. pointTop = 0;
  111. }
  112. else if (pointTop >= yAxis.len) {
  113. pointTop = yAxis.len;
  114. }
  115. if (pointBottom < 0) {
  116. pointBottom = 0;
  117. }
  118. else if (pointBottom >= yAxis.len) {
  119. pointBottom = yAxis.len;
  120. }
  121. if (point.plotX < 0 || point.plotX > xAxis.len) {
  122. connectorWidth = 0;
  123. }
  124. // Connector should reflect upper marker's zone color
  125. if (point.upperGraphic) {
  126. origProps = {
  127. y: point.y,
  128. zone: point.zone
  129. };
  130. point.y = point.high;
  131. point.zone = point.zone ? point.getZone() : void 0;
  132. connectorColor = pick(pointOptions.connectorColor, seriesOptions.connectorColor, pointOptions.color, point.zone ? point.zone.color : void 0, point.color);
  133. extend(point, origProps);
  134. }
  135. attribs = {
  136. d: SVGRenderer.prototype.crispLine([[
  137. 'M',
  138. point.plotX,
  139. pointTop
  140. ], [
  141. 'L',
  142. point.plotX,
  143. pointBottom
  144. ]], connectorWidth, 'ceil')
  145. };
  146. if (!chart.styledMode) {
  147. attribs.stroke = connectorColor;
  148. attribs['stroke-width'] = connectorWidth;
  149. if (dashStyle) {
  150. attribs.dashstyle = dashStyle;
  151. }
  152. }
  153. return attribs;
  154. },
  155. /**
  156. * Draw connector line that connects dumbbell point's low and high values.
  157. * @private
  158. *
  159. * @param {Highcharts.Series} this The series of points.
  160. * @param {Highcharts.Point} point The point to inspect.
  161. *
  162. * @return {void}
  163. */
  164. drawConnector: function (point) {
  165. var series = this, animationLimit = pick(series.options.animationLimit, 250), verb = point.connector && series.chart.pointCount < animationLimit ?
  166. 'animate' : 'attr';
  167. if (!point.connector) {
  168. point.connector = series.chart.renderer.path()
  169. .addClass('highcharts-lollipop-stem')
  170. .attr({
  171. zIndex: -1
  172. })
  173. .add(series.markerGroup);
  174. }
  175. point.connector[verb](this.getConnectorAttribs(point));
  176. },
  177. /**
  178. * Return the width and x offset of the dumbbell adjusted for grouping,
  179. * groupPadding, pointPadding, pointWidth etc.
  180. *
  181. * @private
  182. *
  183. * @function Highcharts.seriesTypes.column#getColumnMetrics
  184. *
  185. * @param {Highcharts.Series} this The series of points.
  186. *
  187. * @return {Highcharts.ColumnMetricsObject} metrics shapeArgs
  188. *
  189. */
  190. getColumnMetrics: function () {
  191. var metrics = colProto.getColumnMetrics.apply(this, arguments);
  192. metrics.offset += metrics.width / 2;
  193. return metrics;
  194. },
  195. translatePoint: areaRangeProto.translate,
  196. setShapeArgs: columnRangeProto.translate,
  197. /**
  198. * Translate each point to the plot area coordinate system and find
  199. * shape positions
  200. *
  201. * @private
  202. *
  203. * @function Highcharts.seriesTypes.dumbbell#translate
  204. *
  205. * @param {Highcharts.Series} this The series of points.
  206. *
  207. * @return {void}
  208. */
  209. translate: function () {
  210. // Calculate shapeargs
  211. this.setShapeArgs.apply(this);
  212. // Calculate point low / high values
  213. this.translatePoint.apply(this, arguments);
  214. // Correct x position
  215. this.points.forEach(function (point) {
  216. var shapeArgs = point.shapeArgs, pointWidth = point.pointWidth;
  217. point.plotX = shapeArgs.x;
  218. shapeArgs.x = point.plotX - pointWidth / 2;
  219. point.tooltipPos = null;
  220. });
  221. this.columnMetrics.offset -= this.columnMetrics.width / 2;
  222. },
  223. seriesDrawPoints: areaRangeProto.drawPoints,
  224. /**
  225. * Extend the arearange series' drawPoints method by applying a connector
  226. * and coloring markers.
  227. * @private
  228. *
  229. * @function Highcharts.Series#drawPoints
  230. *
  231. * @param {Highcharts.Series} this The series of points.
  232. *
  233. * @return {void}
  234. */
  235. drawPoints: function () {
  236. var series = this, chart = series.chart, pointLength = series.points.length, seriesLowColor = series.lowColor = series.options.lowColor, i = 0, lowerGraphicColor, point, zoneColor;
  237. this.seriesDrawPoints.apply(series, arguments);
  238. // Draw connectors and color upper markers
  239. while (i < pointLength) {
  240. point = series.points[i];
  241. series.drawConnector(point);
  242. if (point.upperGraphic) {
  243. point.upperGraphic.element.point = point;
  244. point.upperGraphic.addClass('highcharts-lollipop-high');
  245. }
  246. point.connector.element.point = point;
  247. if (point.lowerGraphic) {
  248. zoneColor = point.zone && point.zone.color;
  249. lowerGraphicColor = pick(point.options.lowColor, seriesLowColor, point.options.color, zoneColor, point.color, series.color);
  250. if (!chart.styledMode) {
  251. point.lowerGraphic.attr({
  252. fill: lowerGraphicColor
  253. });
  254. }
  255. point.lowerGraphic.addClass('highcharts-lollipop-low');
  256. }
  257. i++;
  258. }
  259. },
  260. /**
  261. * Get non-presentational attributes for a point. Used internally for
  262. * both styled mode and classic. Set correct position in link with connector
  263. * line.
  264. *
  265. * @see Series#pointAttribs
  266. *
  267. * @function Highcharts.Series#markerAttribs
  268. *
  269. * @param {Highcharts.Series} this The series of points.
  270. *
  271. * @return {Highcharts.SVGAttributes}
  272. * A hash containing those attributes that are not settable from
  273. * CSS.
  274. */
  275. markerAttribs: function () {
  276. var ret = areaRangeProto.markerAttribs.apply(this, arguments);
  277. ret.x = Math.floor(ret.x);
  278. ret.y = Math.floor(ret.y);
  279. return ret;
  280. },
  281. /**
  282. * Get presentational attributes
  283. *
  284. * @private
  285. * @function Highcharts.seriesTypes.column#pointAttribs
  286. *
  287. * @param {Highcharts.Series} this The series of points.
  288. * @param {Highcharts.Point} point The point to inspect.
  289. * @param {string} state current state of point (normal, hover, select)
  290. *
  291. * @return {Highcharts.SVGAttributes} pointAttribs SVGAttributes
  292. */
  293. pointAttribs: function (point, state) {
  294. var pointAttribs;
  295. pointAttribs = seriesProto.pointAttribs.apply(this, arguments);
  296. if (state === 'hover') {
  297. delete pointAttribs.fill;
  298. }
  299. return pointAttribs;
  300. }
  301. }, {
  302. // seriesTypes doesn't inherit from arearange point proto so put below
  303. // methods rigidly.
  304. destroyElements: areaRangePointProto.destroyElements,
  305. isValid: areaRangePointProto.isValid,
  306. pointSetState: areaRangePointProto.setState,
  307. /**
  308. * Set the point's state extended by have influence on the connector
  309. * (between low and high value).
  310. *
  311. * @private
  312. * @param {Highcharts.Point} this The point to inspect.
  313. *
  314. * @return {void}
  315. */
  316. setState: function () {
  317. var point = this, series = point.series, chart = series.chart, seriesLowColor = series.options.lowColor, seriesMarker = series.options.marker, pointOptions = point.options, pointLowColor = pointOptions.lowColor, zoneColor = point.zone && point.zone.color, lowerGraphicColor = pick(pointLowColor, seriesLowColor, pointOptions.color, zoneColor, point.color, series.color), verb = 'attr', upperGraphicColor, origProps;
  318. this.pointSetState.apply(this, arguments);
  319. if (!point.state) {
  320. verb = 'animate';
  321. if (point.lowerGraphic && !chart.styledMode) {
  322. point.lowerGraphic.attr({
  323. fill: lowerGraphicColor
  324. });
  325. if (point.upperGraphic) {
  326. origProps = {
  327. y: point.y,
  328. zone: point.zone
  329. };
  330. point.y = point.high;
  331. point.zone = point.zone ? point.getZone() : void 0;
  332. upperGraphicColor = pick(point.marker ? point.marker.fillColor : void 0, seriesMarker ? seriesMarker.fillColor : void 0, pointOptions.color, point.zone ? point.zone.color : void 0, point.color);
  333. point.upperGraphic.attr({
  334. fill: upperGraphicColor
  335. });
  336. extend(point, origProps);
  337. }
  338. }
  339. }
  340. point.connector[verb](series.getConnectorAttribs(point));
  341. }
  342. });
  343. /**
  344. * The `dumbbell` series. If the [type](#series.dumbbell.type) option is
  345. * not specified, it is inherited from [chart.type](#chart.type).
  346. *
  347. * @extends series,plotOptions.dumbbell
  348. * @excluding boostThreshold, boostBlending
  349. * @product highcharts highstock
  350. * @requires highcharts-more
  351. * @requires modules/dumbbell
  352. * @apioption series.dumbbell
  353. */
  354. /**
  355. * An array of data points for the series. For the `dumbbell` series
  356. * type, points can be given in the following ways:
  357. *
  358. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  359. * to `x,low,high`. If the first value is a string, it is applied as the name
  360. * of the point, and the `x` value is inferred. The `x` value can also be
  361. * omitted, in which case the inner arrays should be of length 2\. Then the
  362. * `x` value is automatically calculated, either starting at 0 and
  363. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  364. * series options.
  365. * ```js
  366. * data: [
  367. * [0, 4, 2],
  368. * [1, 2, 1],
  369. * [2, 9, 10]
  370. * ]
  371. * ```
  372. *
  373. * 2. An array of objects with named values. The following snippet shows only a
  374. * few settings, see the complete options set below. If the total number of
  375. * data points exceeds the series'
  376. * [turboThreshold](#series.dumbbell.turboThreshold), this option is not
  377. * available.
  378. * ```js
  379. * data: [{
  380. * x: 1,
  381. * low: 0,
  382. * high: 4,
  383. * name: "Point2",
  384. * color: "#00FF00",
  385. * lowColor: "#00FFFF",
  386. * connectorWidth: 3,
  387. * connectorColor: "#FF00FF"
  388. * }, {
  389. * x: 1,
  390. * low: 5,
  391. * high: 3,
  392. * name: "Point1",
  393. * color: "#FF00FF"
  394. * }]
  395. * ```
  396. *
  397. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  398. * Arrays of numeric x and y
  399. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  400. * Arrays of datetime x and y
  401. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  402. * Arrays of point.name and y
  403. * @sample {highcharts} highcharts/series/data-array-of-objects/
  404. * Config objects
  405. *
  406. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  407. * @extends series.arearange.data
  408. * @product highcharts highstock
  409. * @apioption series.dumbbell.data
  410. */
  411. /**
  412. * Color of the line that connects the dumbbell point's values.
  413. * By default it is the series' color.
  414. *
  415. * @type {string}
  416. * @since 8.0.0
  417. * @product highcharts highstock
  418. * @apioption series.dumbbell.data.connectorColor
  419. */
  420. /**
  421. * Pixel width of the line that connects the dumbbell point's values.
  422. *
  423. * @type {number}
  424. * @since 8.0.0
  425. * @default 1
  426. * @product highcharts highstock
  427. * @apioption series.dumbbell.data.connectorWidth
  428. */
  429. /**
  430. * Color of the start markers in a dumbbell graph.
  431. *
  432. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  433. * @since 8.0.0
  434. * @default #333333
  435. * @product highcharts highstock
  436. * @apioption series.dumbbell.data.lowColor
  437. */
  438. ''; // adds doclets above to transpiled file