GanttSeries.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /* *
  2. *
  3. * (c) 2016-2020 Highsoft AS
  4. *
  5. * Author: Lars A. V. Cabrera
  6. *
  7. * License: www.highcharts.com/license
  8. *
  9. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  10. *
  11. * */
  12. 'use strict';
  13. import H from '../Core/Globals.js';
  14. import O from '../Core/Options.js';
  15. var dateFormat = O.dateFormat;
  16. import '../Core/Axis/TreeGridAxis.js';
  17. import U from '../Core/Utilities.js';
  18. var isNumber = U.isNumber, merge = U.merge, pick = U.pick, seriesType = U.seriesType, splat = U.splat;
  19. import '../Extensions/CurrentDateIndication.js';
  20. import '../Extensions/StaticScale.js';
  21. import '../Gantt/Pathfinder.js';
  22. import './XRangeSeries.js';
  23. var seriesTypes = H.seriesTypes, Series = H.Series, parent = seriesTypes.xrange;
  24. /**
  25. * @private
  26. * @class
  27. * @name Highcharts.seriesTypes.gantt
  28. *
  29. * @augments Highcharts.Series
  30. */
  31. seriesType('gantt', 'xrange'
  32. /**
  33. * A `gantt` series. If the [type](#series.gantt.type) option is not specified,
  34. * it is inherited from [chart.type](#chart.type).
  35. *
  36. * @extends plotOptions.xrange
  37. * @product gantt
  38. * @requires highcharts-gantt
  39. * @optionparent plotOptions.gantt
  40. */
  41. , {
  42. // options - default options merged with parent
  43. grouping: false,
  44. dataLabels: {
  45. enabled: true
  46. },
  47. tooltip: {
  48. headerFormat: '<span style="font-size: 10px">{series.name}</span><br/>',
  49. pointFormat: null,
  50. pointFormatter: function () {
  51. var point = this, series = point.series, tooltip = series.chart.tooltip, xAxis = series.xAxis, formats = series.tooltipOptions.dateTimeLabelFormats, startOfWeek = xAxis.options.startOfWeek, ttOptions = series.tooltipOptions, format = ttOptions.xDateFormat, start, end, milestone = point.options.milestone, retVal = '<b>' + (point.name || point.yCategory) + '</b>';
  52. if (ttOptions.pointFormat) {
  53. return point.tooltipFormatter(ttOptions.pointFormat);
  54. }
  55. if (!format) {
  56. format = splat(tooltip.getDateFormat(xAxis.closestPointRange, point.start, startOfWeek, formats))[0];
  57. }
  58. start = dateFormat(format, point.start);
  59. end = dateFormat(format, point.end);
  60. retVal += '<br/>';
  61. if (!milestone) {
  62. retVal += 'Start: ' + start + '<br/>';
  63. retVal += 'End: ' + end + '<br/>';
  64. }
  65. else {
  66. retVal += start + '<br/>';
  67. }
  68. return retVal;
  69. }
  70. },
  71. connectors: {
  72. type: 'simpleConnect',
  73. /**
  74. * @declare Highcharts.ConnectorsAnimationOptionsObject
  75. */
  76. animation: {
  77. reversed: true // Dependencies go from child to parent
  78. },
  79. startMarker: {
  80. enabled: true,
  81. symbol: 'arrow-filled',
  82. radius: 4,
  83. fill: '#fa0',
  84. align: 'left'
  85. },
  86. endMarker: {
  87. enabled: false,
  88. align: 'right'
  89. }
  90. }
  91. }, {
  92. pointArrayMap: ['start', 'end', 'y'],
  93. // Keyboard navigation, don't use nearest vertical mode
  94. keyboardMoveVertical: false,
  95. /* eslint-disable valid-jsdoc */
  96. /**
  97. * Handle milestones, as they have no x2.
  98. * @private
  99. */
  100. translatePoint: function (point) {
  101. var series = this, shapeArgs, size;
  102. parent.prototype.translatePoint.call(series, point);
  103. if (point.options.milestone) {
  104. shapeArgs = point.shapeArgs;
  105. size = shapeArgs.height;
  106. point.shapeArgs = {
  107. x: shapeArgs.x - (size / 2),
  108. y: shapeArgs.y,
  109. width: size,
  110. height: size
  111. };
  112. }
  113. },
  114. /**
  115. * Draws a single point in the series.
  116. *
  117. * This override draws the point as a diamond if point.options.milestone
  118. * is true, and uses the original drawPoint() if it is false or not set.
  119. *
  120. * @requires highcharts-gantt
  121. *
  122. * @private
  123. * @function Highcharts.seriesTypes.gantt#drawPoint
  124. *
  125. * @param {Highcharts.Point} point
  126. * An instance of Point in the series
  127. *
  128. * @param {"animate"|"attr"} verb
  129. * 'animate' (animates changes) or 'attr' (sets options)
  130. *
  131. * @return {void}
  132. */
  133. drawPoint: function (point, verb) {
  134. var series = this, seriesOpts = series.options, renderer = series.chart.renderer, shapeArgs = point.shapeArgs, plotY = point.plotY, graphic = point.graphic, state = point.selected && 'select', cutOff = seriesOpts.stacking && !seriesOpts.borderRadius, diamondShape;
  135. if (point.options.milestone) {
  136. if (isNumber(plotY) && point.y !== null && point.visible !== false) {
  137. diamondShape = renderer.symbols.diamond(shapeArgs.x, shapeArgs.y, shapeArgs.width, shapeArgs.height);
  138. if (graphic) {
  139. graphic[verb]({
  140. d: diamondShape
  141. });
  142. }
  143. else {
  144. point.graphic = graphic = renderer.path(diamondShape)
  145. .addClass(point.getClassName(), true)
  146. .add(point.group || series.group);
  147. }
  148. // Presentational
  149. if (!series.chart.styledMode) {
  150. point.graphic
  151. .attr(series.pointAttribs(point, state))
  152. .shadow(seriesOpts.shadow, null, cutOff);
  153. }
  154. }
  155. else if (graphic) {
  156. point.graphic = graphic.destroy(); // #1269
  157. }
  158. }
  159. else {
  160. parent.prototype.drawPoint.call(series, point, verb);
  161. }
  162. },
  163. setData: Series.prototype.setData,
  164. /**
  165. * @private
  166. */
  167. setGanttPointAliases: function (options) {
  168. /**
  169. * Add a value to options if the value exists.
  170. * @private
  171. */
  172. function addIfExists(prop, val) {
  173. if (typeof val !== 'undefined') {
  174. options[prop] = val;
  175. }
  176. }
  177. addIfExists('x', pick(options.start, options.x));
  178. addIfExists('x2', pick(options.end, options.x2));
  179. addIfExists('partialFill', pick(options.completed, options.partialFill));
  180. addIfExists('connect', pick(options.dependency, options.connect));
  181. }
  182. /* eslint-enable valid-jsdoc */
  183. }, merge(parent.prototype.pointClass.prototype, {
  184. // pointProps - point member overrides. We inherit from parent as well.
  185. /* eslint-disable valid-jsdoc */
  186. /**
  187. * Applies the options containing the x and y data and possible some
  188. * extra properties. This is called on point init or from point.update.
  189. *
  190. * @private
  191. * @function Highcharts.Point#applyOptions
  192. *
  193. * @param {object} options
  194. * The point options
  195. *
  196. * @param {number} x
  197. * The x value
  198. *
  199. * @return {Highcharts.Point}
  200. * The Point instance
  201. */
  202. applyOptions: function (options, x) {
  203. var point = this, retVal = merge(options);
  204. H.seriesTypes.gantt.prototype.setGanttPointAliases(retVal);
  205. retVal = parent.prototype.pointClass.prototype.applyOptions
  206. .call(point, retVal, x);
  207. return retVal;
  208. },
  209. isValid: function () {
  210. return ((typeof this.start === 'number' ||
  211. typeof this.x === 'number') &&
  212. (typeof this.end === 'number' ||
  213. typeof this.x2 === 'number' ||
  214. this.milestone));
  215. }
  216. /* eslint-enable valid-jsdoc */
  217. }));
  218. /**
  219. * A `gantt` series.
  220. *
  221. * @extends series,plotOptions.gantt
  222. * @excluding boostThreshold, connectors, dashStyle, findNearestPointBy,
  223. * getExtremesFromAll, marker, negativeColor, pointInterval,
  224. * pointIntervalUnit, pointPlacement, pointStart
  225. * @product gantt
  226. * @requires highcharts-gantt
  227. * @apioption series.gantt
  228. */
  229. /**
  230. * Data for a Gantt series.
  231. *
  232. * @declare Highcharts.GanttPointOptionsObject
  233. * @type {Array<*>}
  234. * @extends series.xrange.data
  235. * @excluding className, color, colorIndex, connect, dataLabels, events,
  236. * partialFill, selected, x, x2
  237. * @product gantt
  238. * @apioption series.gantt.data
  239. */
  240. /**
  241. * Whether the grid node belonging to this point should start as collapsed. Used
  242. * in axes of type treegrid.
  243. *
  244. * @sample {gantt} gantt/treegrid-axis/collapsed/
  245. * Start as collapsed
  246. *
  247. * @type {boolean}
  248. * @default false
  249. * @product gantt
  250. * @apioption series.gantt.data.collapsed
  251. */
  252. /**
  253. * The start time of a task.
  254. *
  255. * @type {number}
  256. * @product gantt
  257. * @apioption series.gantt.data.start
  258. */
  259. /**
  260. * The end time of a task.
  261. *
  262. * @type {number}
  263. * @product gantt
  264. * @apioption series.gantt.data.end
  265. */
  266. /**
  267. * The Y value of a task.
  268. *
  269. * @type {number}
  270. * @product gantt
  271. * @apioption series.gantt.data.y
  272. */
  273. /**
  274. * The name of a task. If a `treegrid` y-axis is used (default in Gantt charts),
  275. * this will be picked up automatically, and used to calculate the y-value.
  276. *
  277. * @type {string}
  278. * @product gantt
  279. * @apioption series.gantt.data.name
  280. */
  281. /**
  282. * Progress indicator, how much of the task completed. If it is a number, the
  283. * `fill` will be applied automatically.
  284. *
  285. * @sample {gantt} gantt/demo/progress-indicator
  286. * Progress indicator
  287. *
  288. * @type {number|*}
  289. * @extends series.xrange.data.partialFill
  290. * @product gantt
  291. * @apioption series.gantt.data.completed
  292. */
  293. /**
  294. * The amount of the progress indicator, ranging from 0 (not started) to 1
  295. * (finished).
  296. *
  297. * @type {number}
  298. * @default 0
  299. * @apioption series.gantt.data.completed.amount
  300. */
  301. /**
  302. * The fill of the progress indicator. Defaults to a darkened variety of the
  303. * main color.
  304. *
  305. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  306. * @apioption series.gantt.data.completed.fill
  307. */
  308. /**
  309. * The ID of the point (task) that this point depends on in Gantt charts.
  310. * Aliases [connect](series.xrange.data.connect). Can also be an object,
  311. * specifying further connecting [options](series.gantt.connectors) between the
  312. * points. Multiple connections can be specified by providing an array.
  313. *
  314. * @sample gantt/demo/project-management
  315. * Dependencies
  316. * @sample gantt/pathfinder/demo
  317. * Different connection types
  318. *
  319. * @type {string|Array<string|*>|*}
  320. * @extends series.xrange.data.connect
  321. * @since 6.2.0
  322. * @product gantt
  323. * @apioption series.gantt.data.dependency
  324. */
  325. /**
  326. * Whether this point is a milestone. If so, only the `start` option is handled,
  327. * while `end` is ignored.
  328. *
  329. * @sample gantt/gantt/milestones
  330. * Milestones
  331. *
  332. * @type {boolean}
  333. * @since 6.2.0
  334. * @product gantt
  335. * @apioption series.gantt.data.milestone
  336. */
  337. /**
  338. * The ID of the parent point (task) of this point in Gantt charts.
  339. *
  340. * @sample gantt/demo/subtasks
  341. * Gantt chart with subtasks
  342. *
  343. * @type {string}
  344. * @since 6.2.0
  345. * @product gantt
  346. * @apioption series.gantt.data.parent
  347. */
  348. /**
  349. * @excluding afterAnimate
  350. * @apioption series.gantt.events
  351. */
  352. ''; // adds doclets above to the transpiled file