Chart/Chart.ts

  1. /**
  2. * Copyright (c) 2017 ~ present NAVER Corp.
  3. * billboard.js project is licensed under the MIT license
  4. */
  5. import ChartInternal from "../ChartInternal/ChartInternal";
  6. import {loadConfig} from "../config/config";
  7. import {extend, isFunction, notEmpty} from "../module/util";
  8. import apiChart from "./api/chart";
  9. import apiColor from "./api/color";
  10. import apiData from "./api/data";
  11. import apiExport from "./api/export";
  12. import apiFocus from "./api/focus";
  13. import apiLegend from "./api/legend";
  14. import apiLoad from "./api/load";
  15. import apiShow from "./api/show";
  16. import apiTooltip from "./api/tooltip";
  17. /**
  18. * Main chart class.
  19. * - Note: Instantiated via `bb.generate()`.
  20. * @class Chart
  21. * @example
  22. * var chart = bb.generate({
  23. * data: {
  24. * columns: [
  25. * ["x", "2015-11-02", "2015-12-01", "2016-01-01", "2016-02-01", "2016-03-01"],
  26. * ["count1", 11, 8, 7, 6, 5 ],
  27. * ["count2", 9, 3, 6, 2, 8 ]
  28. * ]}
  29. * }
  30. * @see {@link bb.generate} for the initialization.
  31. */
  32. /**
  33. * Access instance's primary node elements
  34. * @member {object} $
  35. * @property {object} $ Access instance's primary node elements
  36. * @property {d3.selection} $.chart Wrapper element
  37. * @property {d3.selection} $.svg Main svg element
  38. * @property {d3.selection} $.defs Definition element
  39. * @property {d3.selection} $.main Main grouping element
  40. * @property {d3.selection} $.needle Needle element
  41. * - **NOTE:**
  42. * - The element will have `bb-needle` as class name.
  43. * - Will provide speical helper `.updateHelper(value: number, updateConfig: boolean)` method to facilitate needle position update.
  44. * @property {d3.selection} $.tooltip Tooltip element
  45. * @property {d3.selection} $.legend Legend element
  46. * @property {d3.selection} $.title Title element
  47. * @property {d3.selection} $.grid Grid element
  48. * @property {d3.selection} $.arc Arc element
  49. * @property {d3.selection} $.circles Data point circle elements
  50. * @property {object} $.bar Bar element object
  51. * @property {d3.selection} $.bar.bars Bar elements
  52. * @property {d3.selection} $.candlestick Candlestick elements
  53. * @property {object} $.line Line element object
  54. * @property {d3.selection} $.line.lines Line elements
  55. * @property {d3.selection} $.line.areas Areas elements
  56. * @property {object} $.text Text element object
  57. * @property {d3.selection} $.text.texts Data label text elements
  58. * @memberof Chart
  59. * @example
  60. * const chart = bb.generate({ ... });
  61. *
  62. * chart.$.chart; // wrapper element
  63. * chart.$.line.circles; // all data point circle elements
  64. * @example
  65. * // Update arc needle position
  66. * const chart = bb.generate({
  67. * data: {
  68. * type: "donut"
  69. * },
  70. * arc: {
  71. * needle: {
  72. * show: true,
  73. * ...
  74. * }
  75. * }
  76. * });
  77. *
  78. * chart.$.needle.updateHelper(70); // update needle position to point value 70.
  79. *
  80. * // update needle position to point value 70 and the config value.
  81. * // NOTE: updating config value, will update needle pointer initial value too.
  82. * chart.$.needle.updateHelper(70, true);
  83. *
  84. * // update needle point position every 1 second
  85. * let i = 0;
  86. * setInterval(() => {
  87. * chart.$.needle.updateHelper(i += 10);
  88. * }, 1000)
  89. */
  90. /**
  91. * Plugin instance array
  92. * @member {Array} plugins
  93. * @memberof Chart
  94. * @example
  95. * var chart = bb.generate({
  96. * ...
  97. * plugins: [
  98. * new bb.plugin.stanford({ ... }),
  99. * new PluginA()
  100. * ]
  101. * });
  102. *
  103. * chart.plugins; // [Stanford, PluginA] - instance array
  104. */
  105. export default class Chart {
  106. public plugins = [];
  107. public internal: ChartInternal;
  108. constructor(options) {
  109. const $$ = new ChartInternal(this);
  110. // let hook = () => {};
  111. this.internal = $$;
  112. // bind to namespaced APIs
  113. (function bindThis(fn, target, argThis) {
  114. Object.keys(fn).forEach(key => {
  115. const isFunc = isFunction(fn[key]);
  116. const isChild = target !== argThis;
  117. const isNotNil = notEmpty(fn[key]);
  118. const hasChild = isNotNil && Object.keys(fn[key]).length > 0;
  119. // const hookFn = function(...params) {
  120. // hook();
  121. // return fn[key].bind(argThis)(...params);
  122. // }
  123. if (isFunc && ((!isChild && hasChild) || isChild)) {
  124. target[key] = fn[key].bind(argThis);
  125. } else if (isNotNil && !isFunc) {
  126. target[key] = {};
  127. } else {
  128. target[key] = fn[key];
  129. }
  130. hasChild && bindThis(fn[key], target[key], argThis);
  131. });
  132. })(Chart.prototype, this, this);
  133. loadConfig.call($$, options);
  134. $$.beforeInit();
  135. $$.init();
  136. // if ($$.config.render.lazy !== false && hasStyle($$.$el.chart, {"display": "none", "visibility": "hidden"})) {
  137. // hook = () => {
  138. // logError(`The call of APIs won't work. Please, make sure if chart element is %cvisible.`);
  139. // };
  140. // }
  141. }
  142. }
  143. // extend common APIs as part of Chart class
  144. extend(Chart.prototype, [
  145. apiChart,
  146. apiColor,
  147. apiData,
  148. apiExport,
  149. apiFocus,
  150. apiLegend,
  151. apiLoad,
  152. apiShow,
  153. apiTooltip
  154. ]);