dependency-wheel.src.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /**
  2. * @license Highcharts JS v9.0.1 (2021-02-16)
  3. *
  4. * Dependency wheel module
  5. *
  6. * (c) 2010-2021 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/dependency-wheel', ['highcharts', 'highcharts/modules/sankey'], 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, 'Series/DependencyWheel/DependencyWheelPoint.js', [_modules['Mixins/Nodes.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (NodesMixin, SeriesRegistry, U) {
  32. /* *
  33. *
  34. * Dependency wheel module
  35. *
  36. * (c) 2018-2021 Torstein Honsi
  37. *
  38. * License: www.highcharts.com/license
  39. *
  40. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  41. *
  42. * */
  43. var __extends = (this && this.__extends) || (function () {
  44. var extendStatics = function (d,
  45. b) {
  46. extendStatics = Object.setPrototypeOf ||
  47. ({ __proto__: [] } instanceof Array && function (d,
  48. b) { d.__proto__ = b; }) ||
  49. function (d,
  50. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51. return extendStatics(d, b);
  52. };
  53. return function (d, b) {
  54. extendStatics(d, b);
  55. function __() { this.constructor = d; }
  56. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  57. };
  58. })();
  59. var SankeySeries = SeriesRegistry.seriesTypes.sankey;
  60. var extend = U.extend;
  61. /* *
  62. *
  63. * Class
  64. *
  65. * */
  66. var DependencyWheelPoint = /** @class */ (function (_super) {
  67. __extends(DependencyWheelPoint, _super);
  68. function DependencyWheelPoint() {
  69. /* *
  70. *
  71. * Properties
  72. *
  73. * */
  74. var _this = _super !== null && _super.apply(this,
  75. arguments) || this;
  76. _this.angle = void 0;
  77. _this.fromNode = void 0;
  78. _this.index = void 0;
  79. _this.linksFrom = void 0;
  80. _this.linksTo = void 0;
  81. _this.options = void 0;
  82. _this.series = void 0;
  83. _this.shapeArgs = void 0;
  84. _this.toNode = void 0;
  85. return _this;
  86. /* eslint-enable valid-jsdoc */
  87. }
  88. /* *
  89. *
  90. * Functions
  91. *
  92. * */
  93. /* eslint-disable valid-jsdoc */
  94. /**
  95. * Return a text path that the data label uses.
  96. * @private
  97. */
  98. DependencyWheelPoint.prototype.getDataLabelPath = function (label) {
  99. var renderer = this.series.chart.renderer,
  100. shapeArgs = this.shapeArgs,
  101. upperHalf = this.angle < 0 || this.angle > Math.PI,
  102. start = shapeArgs.start,
  103. end = shapeArgs.end;
  104. if (!this.dataLabelPath) {
  105. this.dataLabelPath = renderer
  106. .arc({
  107. open: true,
  108. longArc: Math.abs(Math.abs(start) - Math.abs(end)) < Math.PI ? 0 : 1
  109. })
  110. // Add it inside the data label group so it gets destroyed
  111. // with the label
  112. .add(label);
  113. }
  114. this.dataLabelPath.attr({
  115. x: shapeArgs.x,
  116. y: shapeArgs.y,
  117. r: (shapeArgs.r +
  118. (this.dataLabel.options.distance || 0)),
  119. start: (upperHalf ? start : end),
  120. end: (upperHalf ? end : start),
  121. clockwise: +upperHalf
  122. });
  123. return this.dataLabelPath;
  124. };
  125. DependencyWheelPoint.prototype.isValid = function () {
  126. // No null points here
  127. return true;
  128. };
  129. return DependencyWheelPoint;
  130. }(SankeySeries.prototype.pointClass));
  131. extend(DependencyWheelPoint.prototype, {
  132. setState: NodesMixin.setNodeState
  133. });
  134. /* *
  135. *
  136. * Default Export
  137. *
  138. * */
  139. return DependencyWheelPoint;
  140. });
  141. _registerModule(_modules, 'Series/DependencyWheel/DependencyWheelSeries.js', [_modules['Core/Animation/AnimationUtilities.js'], _modules['Series/DependencyWheel/DependencyWheelPoint.js'], _modules['Core/Globals.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (A, DependencyWheelPoint, H, SeriesRegistry, U) {
  142. /* *
  143. *
  144. * Dependency wheel module
  145. *
  146. * (c) 2018-2021 Torstein Honsi
  147. *
  148. * License: www.highcharts.com/license
  149. *
  150. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  151. *
  152. * */
  153. var __extends = (this && this.__extends) || (function () {
  154. var extendStatics = function (d,
  155. b) {
  156. extendStatics = Object.setPrototypeOf ||
  157. ({ __proto__: [] } instanceof Array && function (d,
  158. b) { d.__proto__ = b; }) ||
  159. function (d,
  160. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  161. return extendStatics(d, b);
  162. };
  163. return function (d, b) {
  164. extendStatics(d, b);
  165. function __() { this.constructor = d; }
  166. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  167. };
  168. })();
  169. var animObject = A.animObject;
  170. var deg2rad = H.deg2rad;
  171. var _a = SeriesRegistry.seriesTypes,
  172. PieSeries = _a.pie,
  173. SankeySeries = _a.sankey;
  174. var extend = U.extend,
  175. merge = U.merge;
  176. /* *
  177. *
  178. * Class
  179. *
  180. * */
  181. /**
  182. * @private
  183. * @class
  184. * @name Highcharts.seriesTypes.dependencywheel
  185. *
  186. * @augments Highcharts.seriesTypes.sankey
  187. */
  188. var DependencyWheelSeries = /** @class */ (function (_super) {
  189. __extends(DependencyWheelSeries, _super);
  190. function DependencyWheelSeries() {
  191. /* *
  192. *
  193. * Static Properties
  194. *
  195. * */
  196. var _this = _super !== null && _super.apply(this,
  197. arguments) || this;
  198. /* *
  199. *
  200. * Properties
  201. *
  202. * */
  203. _this.data = void 0;
  204. _this.options = void 0;
  205. _this.nodeColumns = void 0;
  206. _this.nodes = void 0;
  207. _this.points = void 0;
  208. return _this;
  209. /* eslint-enable valid-jsdoc */
  210. }
  211. /* *
  212. *
  213. * Functions
  214. *
  215. * */
  216. /* eslint-disable valid-jsdoc */
  217. DependencyWheelSeries.prototype.animate = function (init) {
  218. if (!init) {
  219. var duration = animObject(this.options.animation).duration,
  220. step = (duration / 2) / this.nodes.length;
  221. this.nodes.forEach(function (point, i) {
  222. var graphic = point.graphic;
  223. if (graphic) {
  224. graphic.attr({ opacity: 0 });
  225. setTimeout(function () {
  226. graphic.animate({ opacity: 1 }, { duration: step });
  227. }, step * i);
  228. }
  229. }, this);
  230. this.points.forEach(function (point) {
  231. var graphic = point.graphic;
  232. if (!point.isNode && graphic) {
  233. graphic.attr({ opacity: 0 })
  234. .animate({
  235. opacity: 1
  236. }, this.options.animation);
  237. }
  238. }, this);
  239. }
  240. };
  241. DependencyWheelSeries.prototype.createNode = function (id) {
  242. var node = SankeySeries.prototype.createNode.call(this,
  243. id);
  244. node.index = this.nodes.length - 1;
  245. /**
  246. * Return the sum of incoming and outgoing links.
  247. * @private
  248. */
  249. node.getSum = function () {
  250. return node.linksFrom
  251. .concat(node.linksTo)
  252. .reduce(function (acc, link) {
  253. return acc + link.weight;
  254. }, 0);
  255. };
  256. /**
  257. * Get the offset in weight values of a point/link.
  258. * @private
  259. */
  260. node.offset = function (point) {
  261. var offset = 0,
  262. i,
  263. links = node.linksFrom.concat(node.linksTo),
  264. sliced;
  265. /**
  266. * @private
  267. */
  268. function otherNode(link) {
  269. if (link.fromNode === node) {
  270. return link.toNode;
  271. }
  272. return link.fromNode;
  273. }
  274. // Sort and slice the links to avoid links going out of each
  275. // node crossing each other.
  276. links.sort(function (a, b) {
  277. return otherNode(a).index - otherNode(b).index;
  278. });
  279. for (i = 0; i < links.length; i++) {
  280. if (otherNode(links[i]).index > node.index) {
  281. links = links.slice(0, i).reverse().concat(links.slice(i).reverse());
  282. sliced = true;
  283. break;
  284. }
  285. }
  286. if (!sliced) {
  287. links.reverse();
  288. }
  289. for (i = 0; i < links.length; i++) {
  290. if (links[i] === point) {
  291. return offset;
  292. }
  293. offset += links[i].weight;
  294. }
  295. };
  296. return node;
  297. };
  298. /**
  299. * Dependency wheel has only one column, it runs along the perimeter.
  300. * @private
  301. */
  302. DependencyWheelSeries.prototype.createNodeColumns = function () {
  303. var columns = [this.createNodeColumn()];
  304. this.nodes.forEach(function (node) {
  305. node.column = 0;
  306. columns[0].push(node);
  307. });
  308. return columns;
  309. };
  310. /**
  311. * Translate from vertical pixels to perimeter.
  312. * @private
  313. */
  314. DependencyWheelSeries.prototype.getNodePadding = function () {
  315. return this.options.nodePadding / Math.PI;
  316. };
  317. /**
  318. * @private
  319. * @todo Override the refactored sankey translateLink and translateNode
  320. * functions instead of the whole translate function.
  321. */
  322. DependencyWheelSeries.prototype.translate = function () {
  323. var options = this.options,
  324. factor = 2 * Math.PI /
  325. (this.chart.plotHeight + this.getNodePadding()),
  326. center = this.getCenter(),
  327. startAngle = (options.startAngle - 90) * deg2rad;
  328. SankeySeries.prototype.translate.call(this);
  329. this.nodeColumns[0].forEach(function (node) {
  330. // Don't render the nodes if sum is 0 #12453
  331. if (node.sum) {
  332. var shapeArgs = node.shapeArgs,
  333. centerX = center[0],
  334. centerY = center[1],
  335. r = center[2] / 2,
  336. innerR = r - options.nodeWidth,
  337. start = startAngle + factor * shapeArgs.y,
  338. end = startAngle +
  339. factor * (shapeArgs.y + shapeArgs.height);
  340. // Middle angle
  341. node.angle = start + (end - start) / 2;
  342. node.shapeType = 'arc';
  343. node.shapeArgs = {
  344. x: centerX,
  345. y: centerY,
  346. r: r,
  347. innerR: innerR,
  348. start: start,
  349. end: end
  350. };
  351. node.dlBox = {
  352. x: centerX + Math.cos((start + end) / 2) * (r + innerR) / 2,
  353. y: centerY + Math.sin((start + end) / 2) * (r + innerR) / 2,
  354. width: 1,
  355. height: 1
  356. };
  357. // Draw the links from this node
  358. node.linksFrom.forEach(function (point) {
  359. if (point.linkBase) {
  360. var distance;
  361. var corners = point.linkBase.map(function (top,
  362. i) {
  363. var angle = factor * top,
  364. x = Math.cos(startAngle + angle) * (innerR + 1),
  365. y = Math.sin(startAngle + angle) * (innerR + 1),
  366. curveFactor = options.curveFactor;
  367. // The distance between the from and to node
  368. // along the perimeter. This affect how curved
  369. // the link is, so that links between neighbours
  370. // don't extend too far towards the center.
  371. distance = Math.abs(point.linkBase[3 - i] * factor - angle);
  372. if (distance > Math.PI) {
  373. distance = 2 * Math.PI - distance;
  374. }
  375. distance = distance * innerR;
  376. if (distance < innerR) {
  377. curveFactor *= (distance / innerR);
  378. }
  379. return {
  380. x: centerX + x,
  381. y: centerY + y,
  382. cpX: centerX + (1 - curveFactor) * x,
  383. cpY: centerY + (1 - curveFactor) * y
  384. };
  385. });
  386. point.shapeArgs = {
  387. d: [[
  388. 'M',
  389. corners[0].x, corners[0].y
  390. ], [
  391. 'A',
  392. innerR, innerR,
  393. 0,
  394. 0,
  395. 1,
  396. corners[1].x, corners[1].y
  397. ], [
  398. 'C',
  399. corners[1].cpX, corners[1].cpY,
  400. corners[2].cpX, corners[2].cpY,
  401. corners[2].x, corners[2].y
  402. ], [
  403. 'A',
  404. innerR, innerR,
  405. 0,
  406. 0,
  407. 1,
  408. corners[3].x, corners[3].y
  409. ], [
  410. 'C',
  411. corners[3].cpX, corners[3].cpY,
  412. corners[0].cpX, corners[0].cpY,
  413. corners[0].x, corners[0].y
  414. ]]
  415. };
  416. }
  417. });
  418. }
  419. });
  420. };
  421. /**
  422. * A dependency wheel chart is a type of flow diagram, where all nodes are
  423. * laid out in a circle, and the flow between the are drawn as link bands.
  424. *
  425. * @sample highcharts/demo/dependency-wheel/
  426. * Dependency wheel
  427. *
  428. * @extends plotOptions.sankey
  429. * @exclude dataSorting
  430. * @since 7.1.0
  431. * @product highcharts
  432. * @requires modules/dependency-wheel
  433. * @optionparent plotOptions.dependencywheel
  434. */
  435. DependencyWheelSeries.defaultOptions = merge(SankeySeries.defaultOptions, {
  436. /**
  437. * The center of the wheel relative to the plot area. Can be
  438. * percentages or pixel values. The default behaviour is to
  439. * center the wheel inside the plot area.
  440. *
  441. * @type {Array<number|string|null>}
  442. * @default [null, null]
  443. * @product highcharts
  444. */
  445. center: [null, null],
  446. curveFactor: 0.6,
  447. /**
  448. * The start angle of the dependency wheel, in degrees where 0 is up.
  449. */
  450. startAngle: 0
  451. });
  452. return DependencyWheelSeries;
  453. }(SankeySeries));
  454. extend(DependencyWheelSeries.prototype, {
  455. orderNodes: false,
  456. getCenter: PieSeries.prototype.getCenter
  457. });
  458. DependencyWheelSeries.prototype.pointClass = DependencyWheelPoint;
  459. SeriesRegistry.registerSeriesType('dependencywheel', DependencyWheelSeries);
  460. /* *
  461. *
  462. * Default Export
  463. *
  464. * */
  465. /* *
  466. *
  467. * API Options
  468. *
  469. * */
  470. /**
  471. * A `dependencywheel` series. If the [type](#series.dependencywheel.type)
  472. * option is not specified, it is inherited from [chart.type](#chart.type).
  473. *
  474. * @extends series,plotOptions.dependencywheel
  475. * @exclude dataSorting
  476. * @product highcharts
  477. * @requires modules/sankey
  478. * @requires modules/dependency-wheel
  479. * @apioption series.dependencywheel
  480. */
  481. /**
  482. * A collection of options for the individual nodes. The nodes in a dependency
  483. * diagram are auto-generated instances of `Highcharts.Point`, but options can
  484. * be applied here and linked by the `id`.
  485. *
  486. * @extends series.sankey.nodes
  487. * @type {Array<*>}
  488. * @product highcharts
  489. * @excluding offset
  490. * @apioption series.dependencywheel.nodes
  491. */
  492. /**
  493. * An array of data points for the series. For the `dependencywheel` series
  494. * type, points can be given in the following way:
  495. *
  496. * An array of objects with named values. The following snippet shows only a
  497. * few settings, see the complete options set below. If the total number of data
  498. * points exceeds the series' [turboThreshold](#series.area.turboThreshold),
  499. * this option is not available.
  500. *
  501. * ```js
  502. * data: [{
  503. * from: 'Category1',
  504. * to: 'Category2',
  505. * weight: 2
  506. * }, {
  507. * from: 'Category1',
  508. * to: 'Category3',
  509. * weight: 5
  510. * }]
  511. * ```
  512. *
  513. * @type {Array<*>}
  514. * @extends series.sankey.data
  515. * @product highcharts
  516. * @excluding outgoing, dataLabels
  517. * @apioption series.dependencywheel.data
  518. */
  519. /**
  520. * Individual data label for each node. The options are the same as
  521. * the ones for [series.dependencywheel.dataLabels](#series.dependencywheel.dataLabels).
  522. *
  523. * @apioption series.dependencywheel.nodes.dataLabels
  524. */
  525. ''; // adds doclets above to the transpiled file
  526. return DependencyWheelSeries;
  527. });
  528. _registerModule(_modules, 'masters/modules/dependency-wheel.src.js', [], function () {
  529. });
  530. }));