Chart/api/chart.ts

  1. /**
  2. * Copyright (c) 2017 ~ present NAVER Corp.
  3. * billboard.js project is licensed under the MIT license
  4. */
  5. import {window} from "../../module/browser";
  6. import {isDefined, isEmpty, notEmpty} from "../../module/util";
  7. export default {
  8. /**
  9. * Resize the chart.
  10. * @function resize
  11. * @instance
  12. * @memberof Chart
  13. * @param {object} size This argument should include width and height in pixels.
  14. * @param {number} [size.width] width value
  15. * @param {number} [size.height] height value
  16. * @example
  17. * // Resize to 640x480
  18. * chart.resize({
  19. * width: 640,
  20. * height: 480
  21. * });
  22. */
  23. resize(size?: {width?: number, height?: number}): void {
  24. const $$ = this.internal;
  25. const {config, state} = $$;
  26. if (state.rendered) {
  27. config.size_width = size ? size.width : null;
  28. config.size_height = size ? size.height : null;
  29. state.resizing = true;
  30. this.flush(false);
  31. $$.resizeFunction();
  32. }
  33. },
  34. /**
  35. * Force to redraw.
  36. * - **NOTE:** When zoom/subchart is used, the zoomed state will be resetted.
  37. * @function flush
  38. * @instance
  39. * @memberof Chart
  40. * @param {boolean} [soft] For soft redraw.
  41. * @example
  42. * chart.flush();
  43. *
  44. * // for soft redraw
  45. * chart.flush(true);
  46. */
  47. flush(soft?: boolean): void {
  48. const $$ = this.internal;
  49. const {state, $el: {zoomResetBtn}} = $$;
  50. if (state.rendered) {
  51. // reset possible zoom scale when is called from resize event
  52. if (state.resizing) { // arguments[1] is given when is called from resize
  53. $$.brush?.updateResize();
  54. } else {
  55. // re-update config info
  56. $$.axis?.setOrient();
  57. }
  58. // hide possible reset zoom button
  59. // https://github.com/naver/billboard.js/issues/2201
  60. zoomResetBtn?.style("display", "none");
  61. $$.scale.zoom = null;
  62. soft ?
  63. $$.redraw({
  64. withTransform: true,
  65. withUpdateXDomain: true,
  66. withUpdateOrgXDomain: true,
  67. withLegend: true
  68. }) :
  69. $$.updateAndRedraw({
  70. withLegend: true,
  71. withTransition: false,
  72. withTransitionForTransform: false
  73. });
  74. // reset subchart selection & selection state
  75. if (!state.resizing && $$.brush) {
  76. $$.brush.getSelection().call($$.brush.move);
  77. $$.unselectRect();
  78. }
  79. } else {
  80. $$.initToRender(true);
  81. }
  82. },
  83. /**
  84. * Reset the chart object and remove element and events completely.
  85. * @function destroy
  86. * @instance
  87. * @memberof Chart
  88. * @returns {null}
  89. * @example
  90. * chart.destroy();
  91. */
  92. destroy(): null {
  93. const $$ = this.internal;
  94. const {$el: {chart, style, svg}} = $$;
  95. if (notEmpty($$)) {
  96. $$.callPluginHook("$willDestroy");
  97. $$.charts.splice($$.charts.indexOf(this), 1);
  98. // detach events
  99. $$.unbindAllEvents();
  100. // clear timers && pending transition
  101. svg.select("*").interrupt();
  102. $$.resizeFunction.clear();
  103. $$.resizeFunction.resizeObserver?.disconnect();
  104. window.removeEventListener("resize", $$.resizeFunction);
  105. chart.classed("bb", false)
  106. .style("position", null)
  107. .selectChildren()
  108. .remove();
  109. // remove <style> element added by boost.useCssRule option
  110. style && style.parentNode.removeChild(style);
  111. // releasing own references
  112. Object.keys(this).forEach(key => {
  113. key === "internal" && Object.keys($$).forEach(k => {
  114. $$[k] = null;
  115. });
  116. this[key] = null;
  117. delete this[key];
  118. });
  119. // release prototype chains
  120. for (const key in this) {
  121. this[key] = () => {};
  122. }
  123. }
  124. return null;
  125. },
  126. /**
  127. * Get or set config option value.
  128. * - **NOTE**
  129. * - The option key name must be specified as the last level.
  130. * - when no argument is given, will return all specified generation options object only. (will exclude any other options not specified at the initialization)
  131. * @function config
  132. * @instance
  133. * @memberof Chart
  134. * @param {string} name The option key name.
  135. * @param {*} [value] The value accepted for indicated option.
  136. * @param {boolean} [redraw] Set to redraw with the new option changes.
  137. * - **NOTE:** Doesn't guarantee work in all circumstances. It can be applied for limited options only.
  138. * @returns {*}
  139. * @example
  140. *
  141. * // Getter
  142. * chart.config("gauge.max");
  143. *
  144. * // Getter specified with top level key name will not work.
  145. * // The option key name must be specified as the last level.
  146. * // chart.config("gauge"); // will not work
  147. *
  148. * // without any arguments, it returns generation config object
  149. * chart.config(); // {data: { ... }, axis: { ... }, ...}
  150. *
  151. * // Setter
  152. * chart.config("gauge.max", 100);
  153. *
  154. * // Setter specified with top level key name will not work.
  155. * // The option key name must be specified as the last level.
  156. * // chart.config("gauge", {min: 10, max: 20}); // will not work
  157. *
  158. * // Setter & redraw with the new option
  159. * chart.config("gauge.max", 100, true);
  160. */
  161. config(name: string, value?: any, redraw?: boolean): any {
  162. const $$ = this.internal;
  163. const {config, state} = $$;
  164. const key = name?.replace(/\./g, "_");
  165. let res;
  166. if (name && key in config) {
  167. if (isDefined(value)) {
  168. config[key] = value;
  169. res = value;
  170. redraw && this.flush();
  171. } else {
  172. res = config[key];
  173. }
  174. } else if (arguments.length === 0 || isEmpty(name)) {
  175. res = state.orgConfig;
  176. }
  177. return res;
  178. }
  179. };