Chart/api/regions.ts

  1. /**
  2. * Copyright (c) 2017 ~ present NAVER Corp.
  3. * billboard.js project is licensed under the MIT license
  4. */
  5. import {$REGION} from "../../config/classes";
  6. import {extend, getOption, isTabVisible} from "../../module/util";
  7. type RegionsParam = {axis?: "add" | "update", class?: string, start?: number, end?: number}[];
  8. /**
  9. * Region add/update function
  10. * @param {Array} regions Regions will be replaced with this argument. The format of this argument is the same as regions.
  11. * @param {boolean} isAdd If true, add new regions, otherwise update regions
  12. * @returns {Array} regions
  13. * @private
  14. */
  15. function regionsFn(regions: RegionsParam, isAdd = false): RegionsParam {
  16. const $$ = this.internal;
  17. const {config} = $$;
  18. const withTransition = config.transition_duration && isTabVisible();
  19. if (!regions) {
  20. return config.regions;
  21. }
  22. config.regions = isAdd ? config.regions.concat(regions) : regions;
  23. $$.updateRegion();
  24. $$.redrawRegion(withTransition);
  25. return isAdd ? config.regions : regions;
  26. }
  27. /**
  28. * Update regions.
  29. * @function regions
  30. * @instance
  31. * @memberof Chart
  32. * @param {Array} regions Regions will be replaced with this argument. The format of this argument is the same as [regions](./Options.html#.regions) option.
  33. * @returns {Array} regions
  34. * @example
  35. * // Show 2 regions
  36. * chart.regions([
  37. * {axis: "x", start: 5, class: "regionX"},
  38. * {
  39. * axis: "y", end: 50, class: "regionY",
  40. * label: {
  41. * text: "Region Text",
  42. * x: 5, // position relative of the initial x coordinate
  43. * y: 5, // position relative of the initial y coordinate
  44. * color: "red", // color string
  45. * rotated: true // make text to show in vertical or horizontal
  46. * }
  47. * }
  48. * ]);
  49. */
  50. const regions = function(regions: RegionsParam): RegionsParam {
  51. return regionsFn.bind(this)(regions);
  52. };
  53. extend(regions, {
  54. /**
  55. * Add new region.<br><br>
  56. * This API adds new region instead of replacing like regions.
  57. * @function regions․add
  58. * @instance
  59. * @memberof Chart
  60. * @param {Array|object} regions New region will be added. The format of this argument is the same as [regions](./Options.html#.regions) and it's possible to give an Object if only one region will be added.
  61. * @returns {Array} regions
  62. * @example
  63. * // Add a new region
  64. * chart.regions.add(
  65. * {
  66. * axis: "x", start: 5, class: "regionX",
  67. * label: {
  68. * text: "Region Text",
  69. * color: "red" // color string
  70. * }
  71. * }
  72. * );
  73. *
  74. * // Add new regions
  75. * chart.regions.add([
  76. * {axis: "x", start: 5, class: "regionX"},
  77. * {
  78. * axis: "y", end: 50, class: "regionY",
  79. * label: {
  80. * text: "Region Text",
  81. * x: 5, // position relative of the initial x coordinate
  82. * y: 5, // position relative of the initial y coordinate
  83. * color: "red", // color string
  84. * rotated: true // make text to show in vertical or horizontal
  85. * }
  86. * }
  87. * ]);
  88. */
  89. add: function(regions: RegionsParam): RegionsParam {
  90. return regionsFn.bind(this)(regions, true);
  91. },
  92. /**
  93. * Remove regions.<br><br>
  94. * This API removes regions.
  95. * @function regions․remove
  96. * @instance
  97. * @memberof Chart
  98. * @param {object} optionsValue This argument should include classes. If classes is given, the regions that have one of the specified classes will be removed. If args is not given, all of regions will be removed.
  99. * @returns {Array} regions Removed regions
  100. * @example
  101. * // regions that have 'region-A' or 'region-B' will be removed.
  102. * chart.regions.remove({
  103. * classes: [
  104. * "region-A", "region-B"
  105. * ]
  106. * });
  107. *
  108. * // all of regions will be removed.
  109. * chart.regions.remove();
  110. */
  111. remove: function(optionsValue: RegionsParam): RegionsParam {
  112. const $$ = this.internal;
  113. const {config, $T} = $$;
  114. const options = optionsValue || {};
  115. const classes = getOption(options, "classes", [$REGION.region]);
  116. let regions = $$.$el.main.select(`.${$REGION.regions}`)
  117. .selectAll(classes.map(c => `.${c}`));
  118. $T(regions)
  119. .style("opacity", "0")
  120. .remove();
  121. regions = config.regions;
  122. if (Object.keys(options).length) {
  123. regions = regions.filter(region => {
  124. let found = false;
  125. if (!region.class) {
  126. return true;
  127. }
  128. region.class.split(" ").forEach(c => {
  129. if (classes.indexOf(c) >= 0) {
  130. found = true;
  131. }
  132. });
  133. return !found;
  134. });
  135. config.regions = regions;
  136. } else {
  137. config.regions = [];
  138. }
  139. return regions;
  140. }
  141. });
  142. export default {regions};