sankey.src.js 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  1. /**
  2. * @license Highcharts JS v8.0.0 (2019-12-10)
  3. *
  4. * Sankey diagram module
  5. *
  6. * (c) 2010-2019 Torstein Honsi
  7. *
  8. * License: www.highcharts.com/license
  9. */
  10. 'use strict';
  11. (function (factory) {
  12. if (typeof module === 'object' && module.exports) {
  13. factory['default'] = factory;
  14. module.exports = factory;
  15. } else if (typeof define === 'function' && define.amd) {
  16. define('highcharts/modules/sankey', ['highcharts'], function (Highcharts) {
  17. factory(Highcharts);
  18. factory.Highcharts = Highcharts;
  19. return factory;
  20. });
  21. } else {
  22. factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
  23. }
  24. }(function (Highcharts) {
  25. var _modules = Highcharts ? Highcharts._modules : {};
  26. function _registerModule(obj, path, args, fn) {
  27. if (!obj.hasOwnProperty(path)) {
  28. obj[path] = fn.apply(null, args);
  29. }
  30. }
  31. _registerModule(_modules, 'mixins/nodes.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
  32. /* *
  33. *
  34. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  35. *
  36. * */
  37. var defined = U.defined, extend = U.extend, pick = U.pick;
  38. var Point = H.Point;
  39. H.NodesMixin = {
  40. /* eslint-disable valid-jsdoc */
  41. /**
  42. * Create a single node that holds information on incoming and outgoing
  43. * links.
  44. * @private
  45. */
  46. createNode: function (id) {
  47. /**
  48. * @private
  49. */
  50. function findById(nodes, id) {
  51. return H.find(nodes, function (node) {
  52. return node.id === id;
  53. });
  54. }
  55. var node = findById(this.nodes, id), PointClass = this.pointClass, options;
  56. if (!node) {
  57. options = this.options.nodes && findById(this.options.nodes, id);
  58. node = (new PointClass()).init(this, extend({
  59. className: 'highcharts-node',
  60. isNode: true,
  61. id: id,
  62. y: 1 // Pass isNull test
  63. }, options));
  64. node.linksTo = [];
  65. node.linksFrom = [];
  66. node.formatPrefix = 'node';
  67. node.name = node.name || node.options.id; // for use in formats
  68. // Mass is used in networkgraph:
  69. node.mass = pick(
  70. // Node:
  71. node.options.mass, node.options.marker && node.options.marker.radius,
  72. // Series:
  73. this.options.marker && this.options.marker.radius,
  74. // Default:
  75. 4);
  76. /**
  77. * Return the largest sum of either the incoming or outgoing links.
  78. * @private
  79. */
  80. node.getSum = function () {
  81. var sumTo = 0, sumFrom = 0;
  82. node.linksTo.forEach(function (link) {
  83. sumTo += link.weight;
  84. });
  85. node.linksFrom.forEach(function (link) {
  86. sumFrom += link.weight;
  87. });
  88. return Math.max(sumTo, sumFrom);
  89. };
  90. /**
  91. * Get the offset in weight values of a point/link.
  92. * @private
  93. */
  94. node.offset = function (point, coll) {
  95. var offset = 0;
  96. for (var i = 0; i < node[coll].length; i++) {
  97. if (node[coll][i] === point) {
  98. return offset;
  99. }
  100. offset += node[coll][i].weight;
  101. }
  102. };
  103. // Return true if the node has a shape, otherwise all links are
  104. // outgoing.
  105. node.hasShape = function () {
  106. var outgoing = 0;
  107. node.linksTo.forEach(function (link) {
  108. if (link.outgoing) {
  109. outgoing++;
  110. }
  111. });
  112. return (!node.linksTo.length ||
  113. outgoing !== node.linksTo.length);
  114. };
  115. this.nodes.push(node);
  116. }
  117. return node;
  118. },
  119. /**
  120. * Extend generatePoints by adding the nodes, which are Point objects
  121. * but pushed to the this.nodes array.
  122. */
  123. generatePoints: function () {
  124. var chart = this.chart, nodeLookup = {};
  125. H.Series.prototype.generatePoints.call(this);
  126. if (!this.nodes) {
  127. this.nodes = []; // List of Point-like node items
  128. }
  129. this.colorCounter = 0;
  130. // Reset links from previous run
  131. this.nodes.forEach(function (node) {
  132. node.linksFrom.length = 0;
  133. node.linksTo.length = 0;
  134. node.level = node.options.level;
  135. });
  136. // Create the node list and set up links
  137. this.points.forEach(function (point) {
  138. if (defined(point.from)) {
  139. if (!nodeLookup[point.from]) {
  140. nodeLookup[point.from] = this.createNode(point.from);
  141. }
  142. nodeLookup[point.from].linksFrom.push(point);
  143. point.fromNode = nodeLookup[point.from];
  144. // Point color defaults to the fromNode's color
  145. if (chart.styledMode) {
  146. point.colorIndex = pick(point.options.colorIndex, nodeLookup[point.from].colorIndex);
  147. }
  148. else {
  149. point.color =
  150. point.options.color || nodeLookup[point.from].color;
  151. }
  152. }
  153. if (defined(point.to)) {
  154. if (!nodeLookup[point.to]) {
  155. nodeLookup[point.to] = this.createNode(point.to);
  156. }
  157. nodeLookup[point.to].linksTo.push(point);
  158. point.toNode = nodeLookup[point.to];
  159. }
  160. point.name = point.name || point.id; // for use in formats
  161. }, this);
  162. // Store lookup table for later use
  163. this.nodeLookup = nodeLookup;
  164. },
  165. // Destroy all nodes on setting new data
  166. setData: function () {
  167. if (this.nodes) {
  168. this.nodes.forEach(function (node) {
  169. node.destroy();
  170. });
  171. this.nodes.length = 0;
  172. }
  173. H.Series.prototype.setData.apply(this, arguments);
  174. },
  175. // Destroy alll nodes and links
  176. destroy: function () {
  177. // Nodes must also be destroyed (#8682, #9300)
  178. this.data = []
  179. .concat(this.points || [], this.nodes);
  180. return H.Series.prototype.destroy.apply(this, arguments);
  181. },
  182. /**
  183. * When hovering node, highlight all connected links. When hovering a link,
  184. * highlight all connected nodes.
  185. */
  186. setNodeState: function (state) {
  187. var args = arguments, others = this.isNode ? this.linksTo.concat(this.linksFrom) :
  188. [this.fromNode, this.toNode];
  189. if (state !== 'select') {
  190. others.forEach(function (linkOrNode) {
  191. if (linkOrNode.series) {
  192. Point.prototype.setState.apply(linkOrNode, args);
  193. if (!linkOrNode.isNode) {
  194. if (linkOrNode.fromNode.graphic) {
  195. Point.prototype.setState.apply(linkOrNode.fromNode, args);
  196. }
  197. if (linkOrNode.toNode.graphic) {
  198. Point.prototype.setState.apply(linkOrNode.toNode, args);
  199. }
  200. }
  201. }
  202. });
  203. }
  204. Point.prototype.setState.apply(this, args);
  205. }
  206. /* eslint-enable valid-jsdoc */
  207. };
  208. });
  209. _registerModule(_modules, 'mixins/tree-series.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
  210. /* *
  211. *
  212. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  213. *
  214. * */
  215. var extend = U.extend, isArray = U.isArray, isNumber = U.isNumber, isObject = U.isObject, pick = U.pick;
  216. var isBoolean = function (x) {
  217. return typeof x === 'boolean';
  218. }, isFn = function (x) {
  219. return typeof x === 'function';
  220. }, merge = H.merge;
  221. /* eslint-disable valid-jsdoc */
  222. /**
  223. * @todo Combine buildTree and buildNode with setTreeValues
  224. * @todo Remove logic from Treemap and make it utilize this mixin.
  225. * @private
  226. */
  227. var setTreeValues = function setTreeValues(tree, options) {
  228. var before = options.before, idRoot = options.idRoot, mapIdToNode = options.mapIdToNode, nodeRoot = mapIdToNode[idRoot], levelIsConstant = (isBoolean(options.levelIsConstant) ?
  229. options.levelIsConstant :
  230. true), points = options.points, point = points[tree.i], optionsPoint = point && point.options || {}, childrenTotal = 0, children = [], value;
  231. extend(tree, {
  232. levelDynamic: tree.level - (levelIsConstant ? 0 : nodeRoot.level),
  233. name: pick(point && point.name, ''),
  234. visible: (idRoot === tree.id ||
  235. (isBoolean(options.visible) ? options.visible : false))
  236. });
  237. if (isFn(before)) {
  238. tree = before(tree, options);
  239. }
  240. // First give the children some values
  241. tree.children.forEach(function (child, i) {
  242. var newOptions = extend({}, options);
  243. extend(newOptions, {
  244. index: i,
  245. siblings: tree.children.length,
  246. visible: tree.visible
  247. });
  248. child = setTreeValues(child, newOptions);
  249. children.push(child);
  250. if (child.visible) {
  251. childrenTotal += child.val;
  252. }
  253. });
  254. tree.visible = childrenTotal > 0 || tree.visible;
  255. // Set the values
  256. value = pick(optionsPoint.value, childrenTotal);
  257. extend(tree, {
  258. children: children,
  259. childrenTotal: childrenTotal,
  260. isLeaf: tree.visible && !childrenTotal,
  261. val: value
  262. });
  263. return tree;
  264. };
  265. /**
  266. * @private
  267. */
  268. var getColor = function getColor(node, options) {
  269. var index = options.index, mapOptionsToLevel = options.mapOptionsToLevel, parentColor = options.parentColor, parentColorIndex = options.parentColorIndex, series = options.series, colors = options.colors, siblings = options.siblings, points = series.points, getColorByPoint, chartOptionsChart = series.chart.options.chart, point, level, colorByPoint, colorIndexByPoint, color, colorIndex;
  270. /**
  271. * @private
  272. */
  273. function variation(color) {
  274. var colorVariation = level && level.colorVariation;
  275. if (colorVariation) {
  276. if (colorVariation.key === 'brightness') {
  277. return H.color(color).brighten(colorVariation.to * (index / siblings)).get();
  278. }
  279. }
  280. return color;
  281. }
  282. if (node) {
  283. point = points[node.i];
  284. level = mapOptionsToLevel[node.level] || {};
  285. getColorByPoint = point && level.colorByPoint;
  286. if (getColorByPoint) {
  287. colorIndexByPoint = point.index % (colors ?
  288. colors.length :
  289. chartOptionsChart.colorCount);
  290. colorByPoint = colors && colors[colorIndexByPoint];
  291. }
  292. // Select either point color, level color or inherited color.
  293. if (!series.chart.styledMode) {
  294. color = pick(point && point.options.color, level && level.color, colorByPoint, parentColor && variation(parentColor), series.color);
  295. }
  296. colorIndex = pick(point && point.options.colorIndex, level && level.colorIndex, colorIndexByPoint, parentColorIndex, options.colorIndex);
  297. }
  298. return {
  299. color: color,
  300. colorIndex: colorIndex
  301. };
  302. };
  303. /**
  304. * Creates a map from level number to its given options.
  305. *
  306. * @private
  307. * @function getLevelOptions
  308. * @param {object} params
  309. * Object containing parameters.
  310. * - `defaults` Object containing default options. The default options
  311. * are merged with the userOptions to get the final options for a
  312. * specific level.
  313. * - `from` The lowest level number.
  314. * - `levels` User options from series.levels.
  315. * - `to` The highest level number.
  316. * @return {Highcharts.Dictionary<object>|null}
  317. * Returns a map from level number to its given options.
  318. */
  319. var getLevelOptions = function getLevelOptions(params) {
  320. var result = null, defaults, converted, i, from, to, levels;
  321. if (isObject(params)) {
  322. result = {};
  323. from = isNumber(params.from) ? params.from : 1;
  324. levels = params.levels;
  325. converted = {};
  326. defaults = isObject(params.defaults) ? params.defaults : {};
  327. if (isArray(levels)) {
  328. converted = levels.reduce(function (obj, item) {
  329. var level, levelIsConstant, options;
  330. if (isObject(item) && isNumber(item.level)) {
  331. options = merge({}, item);
  332. levelIsConstant = (isBoolean(options.levelIsConstant) ?
  333. options.levelIsConstant :
  334. defaults.levelIsConstant);
  335. // Delete redundant properties.
  336. delete options.levelIsConstant;
  337. delete options.level;
  338. // Calculate which level these options apply to.
  339. level = item.level + (levelIsConstant ? 0 : from - 1);
  340. if (isObject(obj[level])) {
  341. extend(obj[level], options);
  342. }
  343. else {
  344. obj[level] = options;
  345. }
  346. }
  347. return obj;
  348. }, {});
  349. }
  350. to = isNumber(params.to) ? params.to : 1;
  351. for (i = 0; i <= to; i++) {
  352. result[i] = merge({}, defaults, isObject(converted[i]) ? converted[i] : {});
  353. }
  354. }
  355. return result;
  356. };
  357. /**
  358. * Update the rootId property on the series. Also makes sure that it is
  359. * accessible to exporting.
  360. *
  361. * @private
  362. * @function updateRootId
  363. *
  364. * @param {object} series
  365. * The series to operate on.
  366. *
  367. * @return {string}
  368. * Returns the resulting rootId after update.
  369. */
  370. var updateRootId = function (series) {
  371. var rootId, options;
  372. if (isObject(series)) {
  373. // Get the series options.
  374. options = isObject(series.options) ? series.options : {};
  375. // Calculate the rootId.
  376. rootId = pick(series.rootNode, options.rootId, '');
  377. // Set rootId on series.userOptions to pick it up in exporting.
  378. if (isObject(series.userOptions)) {
  379. series.userOptions.rootId = rootId;
  380. }
  381. // Set rootId on series to pick it up on next update.
  382. series.rootNode = rootId;
  383. }
  384. return rootId;
  385. };
  386. var result = {
  387. getColor: getColor,
  388. getLevelOptions: getLevelOptions,
  389. setTreeValues: setTreeValues,
  390. updateRootId: updateRootId
  391. };
  392. return result;
  393. });
  394. _registerModule(_modules, 'modules/sankey.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/tree-series.js']], function (H, U, mixinTreeSeries) {
  395. /* *
  396. *
  397. * Sankey diagram module
  398. *
  399. * (c) 2010-2019 Torstein Honsi
  400. *
  401. * License: www.highcharts.com/license
  402. *
  403. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  404. *
  405. * */
  406. /**
  407. * A node in a sankey diagram.
  408. *
  409. * @interface Highcharts.SankeyNodeObject
  410. * @extends Highcharts.Point
  411. * @product highcharts
  412. */ /**
  413. * The color of the auto generated node.
  414. *
  415. * @name Highcharts.SankeyNodeObject#color
  416. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  417. */ /**
  418. * The color index of the auto generated node, especially for use in styled
  419. * mode.
  420. *
  421. * @name Highcharts.SankeyNodeObject#colorIndex
  422. * @type {number}
  423. */ /**
  424. * An optional column index of where to place the node. The default behaviour is
  425. * to place it next to the preceding node.
  426. *
  427. * @see {@link https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/sankey-node-column/|Highcharts-Demo:}
  428. * Specified node column
  429. *
  430. * @name Highcharts.SankeyNodeObject#column
  431. * @type {number}
  432. * @since 6.0.5
  433. */ /**
  434. * The id of the auto-generated node, refering to the `from` or `to` setting of
  435. * the link.
  436. *
  437. * @name Highcharts.SankeyNodeObject#id
  438. * @type {string}
  439. */ /**
  440. * The name to display for the node in data labels and tooltips. Use this when
  441. * the name is different from the `id`. Where the id must be unique for each
  442. * node, this is not necessary for the name.
  443. *
  444. * @see {@link https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/sankey/|Highcharts-Demo:}
  445. * Sankey diagram with node options
  446. *
  447. * @name Highcharts.SankeyNodeObject#name
  448. * @type {string}
  449. * @product highcharts
  450. */ /**
  451. * The vertical offset of a node in terms of weight. Positive values shift the
  452. * node downwards, negative shift it upwards.
  453. *
  454. * @see {@link https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/sankey-node-column/|Highcharts-Demo:}
  455. * Specified node offset
  456. *
  457. * @name Highcharts.SankeyNodeObject#offset
  458. * @type {number}
  459. * @default 0
  460. * @since 6.0.5
  461. */
  462. /**
  463. * Formatter callback function.
  464. *
  465. * @callback Highcharts.SeriesSankeyDataLabelsFormatterCallbackFunction
  466. *
  467. * @param {Highcharts.SeriesSankeyDataLabelsFormatterContextObject|Highcharts.DataLabelsFormatterContextObject} this
  468. * Data label context to format
  469. *
  470. * @return {string|undefined}
  471. * Formatted data label text
  472. */
  473. /**
  474. * Context for the node formatter function.
  475. *
  476. * @interface Highcharts.SeriesSankeyDataLabelsFormatterContextObject
  477. * @extends Highcharts.DataLabelsFormatterContextObject
  478. */ /**
  479. * The node object. The node name, if defined, is available through
  480. * `this.point.name`.
  481. * @name Highcharts.SeriesSankeyDataLabelsFormatterContextObject#point
  482. * @type {Highcharts.SankeyNodeObject}
  483. */
  484. var defined = U.defined, isObject = U.isObject, pick = U.pick, relativeLength = U.relativeLength;
  485. var getLevelOptions = mixinTreeSeries.getLevelOptions;
  486. var find = H.find, merge = H.merge, seriesType = H.seriesType, Point = H.Point;
  487. // eslint-disable-next-line valid-jsdoc
  488. /**
  489. * @private
  490. */
  491. var getDLOptions = function getDLOptions(params) {
  492. var optionsPoint = (isObject(params.optionsPoint) ?
  493. params.optionsPoint.dataLabels :
  494. {}), optionsLevel = (isObject(params.level) ?
  495. params.level.dataLabels :
  496. {}), options = merge({
  497. style: {}
  498. }, optionsLevel, optionsPoint);
  499. return options;
  500. };
  501. /**
  502. * @private
  503. * @class
  504. * @name Highcharts.seriesTypes.sankey
  505. *
  506. * @augments Highcharts.Series
  507. */
  508. seriesType('sankey', 'column',
  509. /**
  510. * A sankey diagram is a type of flow diagram, in which the width of the
  511. * link between two nodes is shown proportionally to the flow quantity.
  512. *
  513. * @sample highcharts/demo/sankey-diagram/
  514. * Sankey diagram
  515. * @sample highcharts/plotoptions/sankey-inverted/
  516. * Inverted sankey diagram
  517. * @sample highcharts/plotoptions/sankey-outgoing
  518. * Sankey diagram with outgoing links
  519. *
  520. * @extends plotOptions.column
  521. * @since 6.0.0
  522. * @product highcharts
  523. * @excluding animationLimit, boostThreshold, borderRadius,
  524. * crisp, cropThreshold, colorAxis, colorKey, depth, dragDrop,
  525. * edgeColor, edgeWidth, findNearestPointBy, grouping,
  526. * groupPadding, groupZPadding, maxPointWidth, negativeColor,
  527. * pointInterval, pointIntervalUnit, pointPadding,
  528. * pointPlacement, pointRange, pointStart, pointWidth,
  529. * shadow, softThreshold, stacking, threshold, zoneAxis,
  530. * zones, minPointLength
  531. * @requires modules/sankey
  532. * @optionparent plotOptions.sankey
  533. */
  534. {
  535. borderWidth: 0,
  536. colorByPoint: true,
  537. /**
  538. * Higher numbers makes the links in a sankey diagram or dependency
  539. * wheelrender more curved. A `curveFactor` of 0 makes the lines
  540. * straight.
  541. *
  542. * @private
  543. */
  544. curveFactor: 0.33,
  545. /**
  546. * Options for the data labels appearing on top of the nodes and links.
  547. * For sankey charts, data labels are visible for the nodes by default,
  548. * but hidden for links. This is controlled by modifying the
  549. * `nodeFormat`, and the `format` that applies to links and is an empty
  550. * string by default.
  551. *
  552. * @declare Highcharts.SeriesSankeyDataLabelsOptionsObject
  553. *
  554. * @private
  555. */
  556. dataLabels: {
  557. enabled: true,
  558. backgroundColor: 'none',
  559. crop: false,
  560. /**
  561. * The
  562. * [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  563. * specifying what to show for _nodes_ in the sankey diagram. By
  564. * default the `nodeFormatter` returns `{point.name}`.
  565. *
  566. * @sample highcharts/plotoptions/sankey-link-datalabels/
  567. * Node and link data labels
  568. *
  569. * @type {string}
  570. */
  571. nodeFormat: void 0,
  572. // eslint-disable-next-line valid-jsdoc
  573. /**
  574. * Callback to format data labels for _nodes_ in the sankey diagram.
  575. * The `nodeFormat` option takes precedence over the
  576. * `nodeFormatter`.
  577. *
  578. * @type {Highcharts.SeriesSankeyDataLabelsFormatterCallbackFunction}
  579. * @since 6.0.2
  580. */
  581. nodeFormatter: function () {
  582. return this.point.name;
  583. },
  584. format: void 0,
  585. // eslint-disable-next-line valid-jsdoc
  586. /**
  587. * @type {Highcharts.SeriesSankeyDataLabelsFormatterCallbackFunction}
  588. */
  589. formatter: function () {
  590. return;
  591. },
  592. inside: true
  593. },
  594. /**
  595. * @ignore-option
  596. *
  597. * @private
  598. */
  599. inactiveOtherPoints: true,
  600. /**
  601. * Set options on specific levels. Takes precedence over series options,
  602. * but not node and link options.
  603. *
  604. * @sample highcharts/demo/sunburst
  605. * Sunburst chart
  606. *
  607. * @type {Array<*>}
  608. * @since 7.1.0
  609. * @apioption plotOptions.sankey.levels
  610. */
  611. /**
  612. * Can set `borderColor` on all nodes which lay on the same level.
  613. *
  614. * @type {Highcharts.ColorString}
  615. * @apioption plotOptions.sankey.levels.borderColor
  616. */
  617. /**
  618. * Can set `borderWidth` on all nodes which lay on the same level.
  619. *
  620. * @type {number}
  621. * @apioption plotOptions.sankey.levels.borderWidth
  622. */
  623. /**
  624. * Can set `color` on all nodes which lay on the same level.
  625. *
  626. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  627. * @apioption plotOptions.sankey.levels.color
  628. */
  629. /**
  630. * Can set `colorByPoint` on all nodes which lay on the same level.
  631. *
  632. * @type {boolean}
  633. * @default true
  634. * @apioption plotOptions.sankey.levels.colorByPoint
  635. */
  636. /**
  637. * Can set `dataLabels` on all points which lay on the same level.
  638. *
  639. * @extends plotOptions.sankey.dataLabels
  640. * @apioption plotOptions.sankey.levels.dataLabels
  641. */
  642. /**
  643. * Decides which level takes effect from the options set in the levels
  644. * object.
  645. *
  646. * @type {number}
  647. * @apioption plotOptions.sankey.levels.level
  648. */
  649. /**
  650. * Can set `linkOpacity` on all points which lay on the same level.
  651. *
  652. * @type {number}
  653. * @default 0.5
  654. * @apioption plotOptions.sankey.levels.linkOpacity
  655. */
  656. /**
  657. * Can set `states` on all nodes and points which lay on the same level.
  658. *
  659. * @extends plotOptions.sankey.states
  660. * @apioption plotOptions.sankey.levels.states
  661. */
  662. /**
  663. * Opacity for the links between nodes in the sankey diagram.
  664. *
  665. * @private
  666. */
  667. linkOpacity: 0.5,
  668. /**
  669. * The minimal width for a line of a sankey. By default,
  670. * 0 values are not shown.
  671. *
  672. * @sample highcharts/plotoptions/sankey-minlinkwidth
  673. * Sankey diagram with minimal link height
  674. *
  675. * @type {number}
  676. * @since 7.1.3
  677. * @default 0
  678. * @apioption plotOptions.sankey.minLinkWidth
  679. *
  680. * @private
  681. */
  682. minLinkWidth: 0,
  683. /**
  684. * The pixel width of each node in a sankey diagram or dependency wheel,
  685. * or the height in case the chart is inverted.
  686. *
  687. * @private
  688. */
  689. nodeWidth: 20,
  690. /**
  691. * The padding between nodes in a sankey diagram or dependency wheel, in
  692. * pixels.
  693. *
  694. * @private
  695. */
  696. nodePadding: 10,
  697. showInLegend: false,
  698. states: {
  699. hover: {
  700. /**
  701. * Opacity for the links between nodes in the sankey diagram in
  702. * hover mode.
  703. */
  704. linkOpacity: 1
  705. },
  706. /**
  707. * The opposite state of a hover for a single point node/link.
  708. *
  709. * @declare Highcharts.SeriesStatesInactiveOptionsObject
  710. */
  711. inactive: {
  712. /**
  713. * Opacity for the links between nodes in the sankey diagram in
  714. * inactive mode.
  715. */
  716. linkOpacity: 0.1,
  717. /**
  718. * Opacity of inactive markers.
  719. *
  720. * @type {number}
  721. * @apioption plotOptions.series.states.inactive.opacity
  722. */
  723. opacity: 0.1,
  724. /**
  725. * Animation when not hovering over the marker.
  726. *
  727. * @type {boolean|Highcharts.AnimationOptionsObject}
  728. * @apioption plotOptions.series.states.inactive.animation
  729. */
  730. animation: {
  731. /** @internal */
  732. duration: 50
  733. }
  734. }
  735. },
  736. tooltip: {
  737. /**
  738. * A callback for defining the format for _nodes_ in the chart's
  739. * tooltip, as opposed to links.
  740. *
  741. * @type {Highcharts.FormatterCallbackFunction<Highcharts.SankeyNodeObject>}
  742. * @since 6.0.2
  743. * @apioption plotOptions.sankey.tooltip.nodeFormatter
  744. */
  745. /**
  746. * Whether the tooltip should follow the pointer or stay fixed on
  747. * the item.
  748. */
  749. followPointer: true,
  750. headerFormat: '<span style="font-size: 10px">{series.name}</span><br/>',
  751. pointFormat: '{point.fromNode.name} \u2192 {point.toNode.name}: <b>{point.weight}</b><br/>',
  752. /**
  753. * The
  754. * [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  755. * specifying what to show for _nodes_ in tooltip of a diagram
  756. * series, as opposed to links.
  757. */
  758. nodeFormat: '{point.name}: <b>{point.sum}</b><br/>'
  759. }
  760. }, {
  761. isCartesian: false,
  762. invertable: true,
  763. forceDL: true,
  764. orderNodes: true,
  765. pointArrayMap: ['from', 'to'],
  766. // Create a single node that holds information on incoming and outgoing
  767. // links.
  768. createNode: H.NodesMixin.createNode,
  769. setData: H.NodesMixin.setData,
  770. destroy: H.NodesMixin.destroy,
  771. /* eslint-disable valid-jsdoc */
  772. /**
  773. * Overridable function to get node padding, overridden in dependency
  774. * wheel series type.
  775. * @private
  776. */
  777. getNodePadding: function () {
  778. return this.options.nodePadding;
  779. },
  780. /**
  781. * Create a node column.
  782. * @private
  783. */
  784. createNodeColumn: function () {
  785. var chart = this.chart, column = [], nodePadding = this.getNodePadding();
  786. column.sum = function () {
  787. return this.reduce(function (sum, node) {
  788. return sum + node.getSum();
  789. }, 0);
  790. };
  791. // Get the offset in pixels of a node inside the column.
  792. column.offset = function (node, factor) {
  793. var offset = 0, totalNodeOffset;
  794. for (var i = 0; i < column.length; i++) {
  795. totalNodeOffset = column[i].getSum() * factor + nodePadding;
  796. if (column[i] === node) {
  797. return {
  798. relativeTop: offset + relativeLength(node.options.offset || 0, totalNodeOffset)
  799. };
  800. }
  801. offset += totalNodeOffset;
  802. }
  803. };
  804. // Get the column height in pixels.
  805. column.top = function (factor) {
  806. var height = this.reduce(function (height, node) {
  807. if (height > 0) {
  808. height += nodePadding;
  809. }
  810. height += node.getSum() * factor;
  811. return height;
  812. }, 0);
  813. return (chart.plotSizeY - height) / 2;
  814. };
  815. return column;
  816. },
  817. /**
  818. * Create node columns by analyzing the nodes and the relations between
  819. * incoming and outgoing links.
  820. * @private
  821. */
  822. createNodeColumns: function () {
  823. var columns = [];
  824. this.nodes.forEach(function (node) {
  825. var fromColumn = -1, fromNode, i, point;
  826. if (!defined(node.options.column)) {
  827. // No links to this node, place it left
  828. if (node.linksTo.length === 0) {
  829. node.column = 0;
  830. // There are incoming links, place it to the right of the
  831. // highest order column that links to this one.
  832. }
  833. else {
  834. for (i = 0; i < node.linksTo.length; i++) {
  835. point = node.linksTo[0];
  836. if (point.fromNode.column > fromColumn) {
  837. fromNode = point.fromNode;
  838. fromColumn = fromNode.column;
  839. }
  840. }
  841. node.column = fromColumn + 1;
  842. // Hanging layout for organization chart
  843. if (fromNode &&
  844. fromNode.options.layout === 'hanging') {
  845. node.hangsFrom = fromNode;
  846. i = -1; // Reuse existing variable i
  847. find(fromNode.linksFrom, function (link, index) {
  848. var found = link.toNode === node;
  849. if (found) {
  850. i = index;
  851. }
  852. return found;
  853. });
  854. node.column += i;
  855. }
  856. }
  857. }
  858. if (!columns[node.column]) {
  859. columns[node.column] = this.createNodeColumn();
  860. }
  861. columns[node.column].push(node);
  862. }, this);
  863. // Fill in empty columns (#8865)
  864. for (var i = 0; i < columns.length; i++) {
  865. if (typeof columns[i] === 'undefined') {
  866. columns[i] = this.createNodeColumn();
  867. }
  868. }
  869. return columns;
  870. },
  871. /**
  872. * Define hasData function for non-cartesian series.
  873. * @private
  874. * @return {boolean}
  875. * Returns true if the series has points at all.
  876. */
  877. hasData: function () {
  878. return !!this.processedXData.length; // != 0
  879. },
  880. /**
  881. * Return the presentational attributes.
  882. * @private
  883. */
  884. pointAttribs: function (point, state) {
  885. var series = this, level = point.isNode ? point.level : point.fromNode.level, levelOptions = series.mapOptionsToLevel[level || 0] || {}, options = point.options, stateOptions = (levelOptions.states && levelOptions.states[state]) || {}, values = [
  886. 'colorByPoint', 'borderColor', 'borderWidth', 'linkOpacity'
  887. ].reduce(function (obj, key) {
  888. obj[key] = pick(stateOptions[key], options[key], levelOptions[key], series.options[key]);
  889. return obj;
  890. }, {}), color = pick(stateOptions.color, options.color, values.colorByPoint ? point.color : levelOptions.color);
  891. // Node attributes
  892. if (point.isNode) {
  893. return {
  894. fill: color,
  895. stroke: values.borderColor,
  896. 'stroke-width': values.borderWidth
  897. };
  898. }
  899. // Link attributes
  900. return {
  901. fill: H.color(color).setOpacity(values.linkOpacity).get()
  902. };
  903. },
  904. /**
  905. * Extend generatePoints by adding the nodes, which are Point objects
  906. * but pushed to the this.nodes array.
  907. * @private
  908. */
  909. generatePoints: function () {
  910. H.NodesMixin.generatePoints.apply(this, arguments);
  911. /**
  912. * Order the nodes, starting with the root node(s). (#9818)
  913. * @private
  914. */
  915. function order(node, level) {
  916. // Prevents circular recursion:
  917. if (typeof node.level === 'undefined') {
  918. node.level = level;
  919. node.linksFrom.forEach(function (link) {
  920. order(link.toNode, level + 1);
  921. });
  922. }
  923. }
  924. if (this.orderNodes) {
  925. this.nodes
  926. // Identify the root node(s)
  927. .filter(function (node) {
  928. return node.linksTo.length === 0;
  929. })
  930. // Start by the root node(s) and recursively set the level
  931. // on all following nodes.
  932. .forEach(function (node) {
  933. order(node, 0);
  934. });
  935. H.stableSort(this.nodes, function (a, b) {
  936. return a.level - b.level;
  937. });
  938. }
  939. },
  940. /**
  941. * Run translation operations for one node.
  942. * @private
  943. */
  944. translateNode: function (node, column) {
  945. var translationFactor = this.translationFactor, chart = this.chart, options = this.options, sum = node.getSum(), height = Math.round(sum * translationFactor), crisp = Math.round(options.borderWidth) % 2 / 2, nodeOffset = column.offset(node, translationFactor), fromNodeTop = Math.floor(pick(nodeOffset.absoluteTop, (column.top(translationFactor) +
  946. nodeOffset.relativeTop))) + crisp, left = Math.floor(this.colDistance * node.column +
  947. options.borderWidth / 2) + crisp, nodeLeft = chart.inverted ?
  948. chart.plotSizeX - left :
  949. left, nodeWidth = Math.round(this.nodeWidth);
  950. node.sum = sum;
  951. // Draw the node
  952. node.shapeType = 'rect';
  953. node.nodeX = nodeLeft;
  954. node.nodeY = fromNodeTop;
  955. if (!chart.inverted) {
  956. node.shapeArgs = {
  957. x: nodeLeft,
  958. y: fromNodeTop,
  959. width: node.options.width || options.width || nodeWidth,
  960. height: node.options.height || options.height || height
  961. };
  962. }
  963. else {
  964. node.shapeArgs = {
  965. x: nodeLeft - nodeWidth,
  966. y: chart.plotSizeY - fromNodeTop - height,
  967. width: node.options.height || options.height || nodeWidth,
  968. height: node.options.width || options.width || height
  969. };
  970. }
  971. node.shapeArgs.display = node.hasShape() ? '' : 'none';
  972. // Calculate data label options for the point
  973. node.dlOptions = getDLOptions({
  974. level: this.mapOptionsToLevel[node.level],
  975. optionsPoint: node.options
  976. });
  977. // Pass test in drawPoints
  978. node.plotY = 1;
  979. },
  980. /**
  981. * Run translation operations for one link.
  982. * @private
  983. */
  984. translateLink: function (point) {
  985. var fromNode = point.fromNode, toNode = point.toNode, chart = this.chart, translationFactor = this.translationFactor, linkHeight = Math.max(point.weight * translationFactor, this.options.minLinkWidth), options = this.options, fromLinkTop = (fromNode.offset(point, 'linksFrom') *
  986. translationFactor), curvy = ((chart.inverted ? -this.colDistance : this.colDistance) *
  987. options.curveFactor), fromY = fromNode.nodeY + fromLinkTop, nodeLeft = fromNode.nodeX, toColTop = this.nodeColumns[toNode.column]
  988. .top(translationFactor), toY = (toColTop +
  989. (toNode.offset(point, 'linksTo') *
  990. translationFactor) +
  991. this.nodeColumns[toNode.column].offset(toNode, translationFactor).relativeTop), nodeW = this.nodeWidth, right = toNode.column * this.colDistance, outgoing = point.outgoing, straight = right > nodeLeft;
  992. if (chart.inverted) {
  993. fromY = chart.plotSizeY - fromY;
  994. toY = chart.plotSizeY - toY;
  995. right = chart.plotSizeX - right;
  996. nodeW = -nodeW;
  997. linkHeight = -linkHeight;
  998. straight = nodeLeft > right;
  999. }
  1000. point.shapeType = 'path';
  1001. point.linkBase = [
  1002. fromY,
  1003. fromY + linkHeight,
  1004. toY,
  1005. toY + linkHeight
  1006. ];
  1007. // Links going from left to right
  1008. if (straight) {
  1009. point.shapeArgs = {
  1010. d: [
  1011. 'M', nodeLeft + nodeW, fromY,
  1012. 'C', nodeLeft + nodeW + curvy, fromY,
  1013. right - curvy, toY,
  1014. right, toY,
  1015. 'L',
  1016. right + (outgoing ? nodeW : 0),
  1017. toY + linkHeight / 2,
  1018. 'L',
  1019. right,
  1020. toY + linkHeight,
  1021. 'C', right - curvy, toY + linkHeight,
  1022. nodeLeft + nodeW + curvy,
  1023. fromY + linkHeight,
  1024. nodeLeft + nodeW, fromY + linkHeight,
  1025. 'z'
  1026. ]
  1027. };
  1028. // Experimental: Circular links pointing backwards. In
  1029. // v6.1.0 this breaks the rendering completely, so even
  1030. // this experimental rendering is an improvement. #8218.
  1031. // @todo
  1032. // - Make room for the link in the layout
  1033. // - Automatically determine if the link should go up or
  1034. // down.
  1035. }
  1036. else {
  1037. var bend = 20, vDist = chart.plotHeight - fromY - linkHeight, x1 = right - bend - linkHeight, x2 = right - bend, x3 = right, x4 = nodeLeft + nodeW, x5 = x4 + bend, x6 = x5 + linkHeight, fy1 = fromY, fy2 = fromY + linkHeight, fy3 = fy2 + bend, y4 = fy3 + vDist, y5 = y4 + bend, y6 = y5 + linkHeight, ty1 = toY, ty2 = ty1 + linkHeight, ty3 = ty2 + bend, cfy1 = fy2 - linkHeight * 0.7, cy2 = y5 + linkHeight * 0.7, cty1 = ty2 - linkHeight * 0.7, cx1 = x3 - linkHeight * 0.7, cx2 = x4 + linkHeight * 0.7;
  1038. point.shapeArgs = {
  1039. d: [
  1040. 'M', x4, fy1,
  1041. 'C', cx2, fy1, x6, cfy1, x6, fy3,
  1042. 'L', x6, y4,
  1043. 'C', x6, cy2, cx2, y6, x4, y6,
  1044. 'L', x3, y6,
  1045. 'C', cx1, y6, x1, cy2, x1, y4,
  1046. 'L', x1, ty3,
  1047. 'C', x1, cty1, cx1, ty1, x3, ty1,
  1048. 'L', x3, ty2,
  1049. 'C', x2, ty2, x2, ty2, x2, ty3,
  1050. 'L', x2, y4,
  1051. 'C', x2, y5, x2, y5, x3, y5,
  1052. 'L', x4, y5,
  1053. 'C', x5, y5, x5, y5, x5, y4,
  1054. 'L', x5, fy3,
  1055. 'C', x5, fy2, x5, fy2, x4, fy2,
  1056. 'z'
  1057. ]
  1058. };
  1059. }
  1060. // Place data labels in the middle
  1061. point.dlBox = {
  1062. x: nodeLeft + (right - nodeLeft + nodeW) / 2,
  1063. y: fromY + (toY - fromY) / 2,
  1064. height: linkHeight,
  1065. width: 0
  1066. };
  1067. // Pass test in drawPoints
  1068. point.y = point.plotY = 1;
  1069. if (!point.color) {
  1070. point.color = fromNode.color;
  1071. }
  1072. },
  1073. /**
  1074. * Run pre-translation by generating the nodeColumns.
  1075. * @private
  1076. */
  1077. translate: function () {
  1078. if (!this.processedXData) {
  1079. this.processData();
  1080. }
  1081. this.generatePoints();
  1082. this.nodeColumns = this.createNodeColumns();
  1083. this.nodeWidth = relativeLength(this.options.nodeWidth, this.chart.plotSizeX);
  1084. var series = this, chart = this.chart, options = this.options, nodeWidth = this.nodeWidth, nodeColumns = this.nodeColumns, nodePadding = this.getNodePadding();
  1085. // Find out how much space is needed. Base it on the translation
  1086. // factor of the most spaceous column.
  1087. this.translationFactor = nodeColumns.reduce(function (translationFactor, column) {
  1088. var height = chart.plotSizeY -
  1089. options.borderWidth -
  1090. (column.length - 1) * nodePadding;
  1091. return Math.min(translationFactor, height / column.sum());
  1092. }, Infinity);
  1093. this.colDistance =
  1094. (chart.plotSizeX - nodeWidth -
  1095. options.borderWidth) / Math.max(1, nodeColumns.length - 1);
  1096. // Calculate level options used in sankey and organization
  1097. series.mapOptionsToLevel = getLevelOptions({
  1098. // NOTE: if support for allowTraversingTree is added, then from
  1099. // should be the level of the root node.
  1100. from: 1,
  1101. levels: options.levels,
  1102. to: nodeColumns.length - 1,
  1103. defaults: {
  1104. borderColor: options.borderColor,
  1105. borderRadius: options.borderRadius,
  1106. borderWidth: options.borderWidth,
  1107. color: series.color,
  1108. colorByPoint: options.colorByPoint,
  1109. // NOTE: if support for allowTraversingTree is added, then
  1110. // levelIsConstant should be optional.
  1111. levelIsConstant: true,
  1112. linkColor: options.linkColor,
  1113. linkLineWidth: options.linkLineWidth,
  1114. linkOpacity: options.linkOpacity,
  1115. states: options.states
  1116. }
  1117. });
  1118. // First translate all nodes so we can use them when drawing links
  1119. nodeColumns.forEach(function (column) {
  1120. column.forEach(function (node) {
  1121. series.translateNode(node, column);
  1122. });
  1123. }, this);
  1124. // Then translate links
  1125. this.nodes.forEach(function (node) {
  1126. // Translate the links from this node
  1127. node.linksFrom.forEach(function (linkPoint) {
  1128. series.translateLink(linkPoint);
  1129. linkPoint.allowShadow = false;
  1130. });
  1131. });
  1132. },
  1133. /**
  1134. * Extend the render function to also render this.nodes together with
  1135. * the points.
  1136. * @private
  1137. */
  1138. render: function () {
  1139. var points = this.points;
  1140. this.points = this.points.concat(this.nodes || []);
  1141. H.seriesTypes.column.prototype.render.call(this);
  1142. this.points = points;
  1143. },
  1144. /* eslint-enable valid-jsdoc */
  1145. animate: H.Series.prototype.animate
  1146. }, {
  1147. applyOptions: function (options, x) {
  1148. Point.prototype.applyOptions.call(this, options, x);
  1149. // Treat point.level as a synonym of point.column
  1150. if (defined(this.options.level)) {
  1151. this.options.column = this.column = this.options.level;
  1152. }
  1153. return this;
  1154. },
  1155. setState: H.NodesMixin.setNodeState,
  1156. getClassName: function () {
  1157. return (this.isNode ? 'highcharts-node ' : 'highcharts-link ') +
  1158. Point.prototype.getClassName.call(this);
  1159. },
  1160. isValid: function () {
  1161. return this.isNode || typeof this.weight === 'number';
  1162. }
  1163. });
  1164. /**
  1165. * A `sankey` series. If the [type](#series.sankey.type) option is not
  1166. * specified, it is inherited from [chart.type](#chart.type).
  1167. *
  1168. * @extends series,plotOptions.sankey
  1169. * @excluding animationLimit, boostBlending, boostThreshold, borderColor,
  1170. * borderRadius, borderWidth, crisp, cropThreshold, dataParser,
  1171. * dataURL, depth, dragDrop, edgeColor, edgeWidth,
  1172. * findNearestPointBy, getExtremesFromAll, grouping, groupPadding,
  1173. * groupZPadding, label, maxPointWidth, negativeColor, pointInterval,
  1174. * pointIntervalUnit, pointPadding, pointPlacement, pointRange,
  1175. * pointStart, pointWidth, shadow, softThreshold, stacking,
  1176. * threshold, zoneAxis, zones
  1177. * @product highcharts
  1178. * @requires modules/sankey
  1179. * @apioption series.sankey
  1180. */
  1181. /**
  1182. * A collection of options for the individual nodes. The nodes in a sankey
  1183. * diagram are auto-generated instances of `Highcharts.Point`, but options can
  1184. * be applied here and linked by the `id`.
  1185. *
  1186. * @sample highcharts/css/sankey/
  1187. * Sankey diagram with node options
  1188. *
  1189. * @declare Highcharts.SeriesSankeyNodesOptionsObject
  1190. * @type {Array<*>}
  1191. * @product highcharts
  1192. * @apioption series.sankey.nodes
  1193. */
  1194. /**
  1195. * The id of the auto-generated node, refering to the `from` or `to` setting of
  1196. * the link.
  1197. *
  1198. * @type {string}
  1199. * @product highcharts
  1200. * @apioption series.sankey.nodes.id
  1201. */
  1202. /**
  1203. * The color of the auto generated node.
  1204. *
  1205. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  1206. * @product highcharts
  1207. * @apioption series.sankey.nodes.color
  1208. */
  1209. /**
  1210. * The color index of the auto generated node, especially for use in styled
  1211. * mode.
  1212. *
  1213. * @type {number}
  1214. * @product highcharts
  1215. * @apioption series.sankey.nodes.colorIndex
  1216. */
  1217. /**
  1218. * An optional column index of where to place the node. The default behaviour is
  1219. * to place it next to the preceding node. Note that this option name is
  1220. * counter intuitive in inverted charts, like for example an organization chart
  1221. * rendered top down. In this case the "columns" are horizontal.
  1222. *
  1223. * @sample highcharts/plotoptions/sankey-node-column/
  1224. * Specified node column
  1225. *
  1226. * @type {number}
  1227. * @since 6.0.5
  1228. * @product highcharts
  1229. * @apioption series.sankey.nodes.column
  1230. */
  1231. /**
  1232. * Individual data label for each node. The options are the same as
  1233. * the ones for [series.sankey.dataLabels](#series.sankey.dataLabels).
  1234. *
  1235. * @extends plotOptions.sankey.dataLabels
  1236. * @apioption series.sankey.nodes.dataLabels
  1237. */
  1238. /**
  1239. * An optional level index of where to place the node. The default behaviour is
  1240. * to place it next to the preceding node. Alias of `nodes.column`, but in
  1241. * inverted sankeys and org charts, the levels are laid out as rows.
  1242. *
  1243. * @type {number}
  1244. * @since 7.1.0
  1245. * @product highcharts
  1246. * @apioption series.sankey.nodes.level
  1247. */
  1248. /**
  1249. * The name to display for the node in data labels and tooltips. Use this when
  1250. * the name is different from the `id`. Where the id must be unique for each
  1251. * node, this is not necessary for the name.
  1252. *
  1253. * @sample highcharts/css/sankey/
  1254. * Sankey diagram with node options
  1255. *
  1256. * @type {string}
  1257. * @product highcharts
  1258. * @apioption series.sankey.nodes.name
  1259. */
  1260. /**
  1261. * In a horizontal layout, the vertical offset of a node in terms of weight.
  1262. * Positive values shift the node downwards, negative shift it upwards. In a
  1263. * vertical layout, like organization chart, the offset is horizontal.
  1264. *
  1265. * If a percantage string is given, the node is offset by the percentage of the
  1266. * node size plus `nodePadding`.
  1267. *
  1268. * @sample highcharts/plotoptions/sankey-node-column/
  1269. * Specified node offset
  1270. *
  1271. * @type {number|string}
  1272. * @default 0
  1273. * @since 6.0.5
  1274. * @product highcharts
  1275. * @apioption series.sankey.nodes.offset
  1276. */
  1277. /**
  1278. * An array of data points for the series. For the `sankey` series type,
  1279. * points can be given in the following way:
  1280. *
  1281. * An array of objects with named values. The following snippet shows only a
  1282. * few settings, see the complete options set below. If the total number of data
  1283. * points exceeds the series' [turboThreshold](#series.area.turboThreshold),
  1284. * this option is not available.
  1285. *
  1286. * ```js
  1287. * data: [{
  1288. * from: 'Category1',
  1289. * to: 'Category2',
  1290. * weight: 2
  1291. * }, {
  1292. * from: 'Category1',
  1293. * to: 'Category3',
  1294. * weight: 5
  1295. * }]
  1296. * ```
  1297. *
  1298. * @sample {highcharts} highcharts/series/data-array-of-objects/
  1299. * Config objects
  1300. *
  1301. * @declare Highcharts.SeriesSankeyPointOptionsObject
  1302. * @type {Array<*>}
  1303. * @extends series.line.data
  1304. * @excluding dragDrop, drilldown, marker, x, y
  1305. * @product highcharts
  1306. * @apioption series.sankey.data
  1307. */
  1308. /**
  1309. * The color for the individual _link_. By default, the link color is the same
  1310. * as the node it extends from. The `series.fillOpacity` option also applies to
  1311. * the points, so when setting a specific link color, consider setting the
  1312. * `fillOpacity` to 1.
  1313. *
  1314. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  1315. * @product highcharts
  1316. * @apioption series.sankey.data.color
  1317. */
  1318. /**
  1319. * @type {Highcharts.SeriesSankeyDataLabelsOptionsObject|Array<Highcharts.SeriesSankeyDataLabelsOptionsObject>}
  1320. * @product highcharts
  1321. * @apioption series.sankey.data.dataLabels
  1322. */
  1323. /**
  1324. * The node that the link runs from.
  1325. *
  1326. * @type {string}
  1327. * @product highcharts
  1328. * @apioption series.sankey.data.from
  1329. */
  1330. /**
  1331. * The node that the link runs to.
  1332. *
  1333. * @type {string}
  1334. * @product highcharts
  1335. * @apioption series.sankey.data.to
  1336. */
  1337. /**
  1338. * Whether the link goes out of the system.
  1339. *
  1340. * @sample highcharts/plotoptions/sankey-outgoing
  1341. * Sankey chart with outgoing links
  1342. *
  1343. * @type {boolean}
  1344. * @default false
  1345. * @product highcharts
  1346. * @apioption series.sankey.data.outgoing
  1347. */
  1348. /**
  1349. * The weight of the link.
  1350. *
  1351. * @type {number|null}
  1352. * @product highcharts
  1353. * @apioption series.sankey.data.weight
  1354. */
  1355. ''; // adds doclets above to transpiled file
  1356. });
  1357. _registerModule(_modules, 'masters/modules/sankey.src.js', [], function () {
  1358. });
  1359. }));