Chart/api/load.ts

  1. /**
  2. * Copyright (c) 2017 ~ present NAVER Corp.
  3. * billboard.js project is licensed under the MIT license
  4. */
  5. import {callDone} from "../../ChartInternal/data/load";
  6. import {requestIdleCallback} from "../../module/browser";
  7. import {isArray, isEmpty, isString} from "../../module/util";
  8. export default {
  9. /**
  10. * Load data to the chart.<br><br>
  11. * You can specify multiple targets by giving an array that includes id as String. If no argument is given, all of targets will be toggles.
  12. * - <b>Note:</b>
  13. * - unload should be used if some data needs to be unloaded simultaneously.
  14. * If you call unload API soon after/before load instead of unload param, chart will not be rendered properly because of cancel of animation.<br>
  15. * - done will be called after data loaded, but it's not after rendering.
  16. * It's because rendering will finish after some transition and there is some time lag between loading and rendering
  17. * @function load
  18. * @instance
  19. * @memberof Chart
  20. * @param {object} args The object can consist with following members:<br>
  21. *
  22. * | Key | Type | Description |
  23. * | --- | --- | --- |
  24. * | columns | Array | The `columns` data will be loaded. If data that has the same target id is given, the chart will be updated. Otherwise, new target will be added |
  25. * | json | Array | The `json` data will be loaded. If data that has the same target id is given, the chart will be updated. Otherwise, new target will be added |
  26. * | rows | Array | The `rows` data will be loaded. If data that has the same target id is given, the chart will be updated. Otherwise, new target will be added |
  27. * | url | string | The data from `url` will be loaded. If data that has the same target id is given, the chart will be updated. Otherwise, new target will be added |
  28. * | &nbsp; | | |
  29. * | append | boolean | Load data appending it to the current dataseries.<br>If the existing chart has`x` value, should provide with corresponding `x` value for newly loaded data. |
  30. * | axes | Object | The axes specified by data.axes will be updated. axes must be Object that has target id as keys. |
  31. * | categories | Array | The categories specified by axis.x.categories or data.x will be updated. categories must be Array. |
  32. * | classes | Object | The classes specified by data.classes will be updated. classes must be Object that has target id as keys. |
  33. * | colors | Object | The colors specified by data.colors will be updated. colors must be Object that has target id as keys. |
  34. * | data | Obejct | Data objects to be loaded. Checkout the example. |
  35. * | done | Function | The specified function will be called after data loaded.|
  36. * | headers | string | Set request header if loading via `data.url`.<br>@see [data․headers](Options.html#.data%25E2%2580%25A4headers) |
  37. * | keys | Object | Choose which JSON objects keys correspond to desired data.<br>**NOTE:** Only for JSON object given as array.<br>@see [data․keys](Options.html#.data%25E2%2580%25A4keys) |
  38. * | mimeType | string | Set 'json' if loading JSON via url.<br>@see [data․mimeType](Options.html#.data%25E2%2580%25A4mimeType) |
  39. * | names | Object | Same as data.names() |
  40. * | resizeAfter | boolean | Resize after the load. Default value is `false`.<br>- This option won't call `onresize` neither `onresized`.<br>- When set to 'true', will call `.flush(true)` at the end of load. |
  41. * | type | string | The type of targets will be updated. |
  42. * | types | Object | The types of targets will be updated. |
  43. * | unload | Array | Specify the data will be unloaded before loading new data. If true given, all of data will be unloaded. If target ids given as String or Array, specified targets will be unloaded. If absent or false given, unload will not occur. |
  44. * | xs | string | Same as data.xs option |
  45. * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataFromURL)
  46. * @example
  47. * // Load data1 and unload data2 and data3
  48. * chart.load({
  49. * columns: [
  50. * ["data1", 100, 200, 150, ...],
  51. * ...
  52. * ],
  53. * unload: ["data2", "data3"],
  54. * url: "...",
  55. * done: function() { ... }
  56. * resizeAfter: true // will resize after load
  57. * });
  58. * @example
  59. * const chart = bb.generate({
  60. * data: {
  61. * columns: [
  62. * ["data1", 20, 30, 40]
  63. * ]
  64. * }
  65. * });
  66. *
  67. * chart.load({
  68. * columns: [
  69. * // with 'append' option, the 'data1' will have `[20,30,40,50,60]`.
  70. * ["data1", 50, 60]
  71. * ],
  72. * append: true
  73. * });
  74. * @example
  75. * const chart = bb.generate({
  76. * data: {
  77. * x: "x",
  78. * xFormat: "%Y-%m-%dT%H:%M:%S",
  79. * columns: [
  80. * ["x", "2021-01-03T03:00:00", "2021-01-04T12:00:00", "2021-01-05T21:00:00"],
  81. * ["data1", 36, 30, 24]
  82. * ]
  83. * },
  84. * axis: {
  85. * x: {
  86. * type: "timeseries"
  87. * }
  88. * }
  89. * };
  90. *
  91. * chart.load({
  92. * columns: [
  93. * // when existing chart has `x` value, should provide correponding 'x' value.
  94. * // with 'append' option, the 'data1' will have `[36,30,24,37]`.
  95. * ["x", "2021-02-01T08:00:00"],
  96. * ["data1", 37]
  97. * ],
  98. * append: true
  99. * });
  100. * @example
  101. * // myAPI.json
  102. * // {
  103. * // "data1": [220, 240, 270, 250, 280],
  104. * // "data2": [180, 150, 300, 70, 120]
  105. * // }
  106. *
  107. * chart.load({
  108. * url: './data/myAPI.json',
  109. * mimeType: "json",
  110. *
  111. * // set request header if is needed
  112. * headers: {
  113. * "Content-Type": "text/json"
  114. * }
  115. * });
  116. * @example
  117. * chart.load({
  118. * data: [
  119. * // equivalent as: columns: [["data1", 30, 200, 100]]
  120. * {"data1": 30}, {"data1": 200}, {"data1": 100}
  121. *
  122. * // or
  123. * // equivalent as: columns: [["data1", 10, 20], ["data2", 13, 30]]
  124. * // {"data1": 10, "data2": 13}, {"data1": 20, "data2": 30}}
  125. * ]
  126. * });
  127. * @example
  128. * chart.load({
  129. * json: [
  130. * {name: "www.site1.com", upload: 800, download: 500, total: 400},
  131. * ],
  132. * keys: {
  133. * x: "name",
  134. * value: ["upload", "download"]
  135. * }
  136. * });
  137. * @example
  138. * chart.load({
  139. * json: {
  140. * data1:[30, 20, 50, 40, 60, 50],
  141. * data2:[200, 130, 90, 240, 130, 220],
  142. * }
  143. * });
  144. */
  145. load(args): void {
  146. const $$ = this.internal;
  147. const {config} = $$;
  148. // update xs if specified
  149. args.xs && $$.addXs(args.xs);
  150. // update names if exists
  151. "names" in args && this.data.names(args.names);
  152. // update classes if exists
  153. "classes" in args && Object.keys(args.classes).forEach(id => {
  154. config.data_classes[id] = args.classes[id];
  155. });
  156. // update categories if exists
  157. if ("categories" in args && $$.axis.isCategorized()) {
  158. config.axis_x_categories = args.categories;
  159. }
  160. // update axes if exists
  161. "axes" in args && Object.keys(args.axes).forEach(id => {
  162. config.data_axes[id] = args.axes[id];
  163. });
  164. // update colors if exists
  165. "colors" in args && Object.keys(args.colors).forEach(id => {
  166. config.data_colors[id] = args.colors[id];
  167. });
  168. // unload if needed
  169. if ("unload" in args && args.unload !== false) {
  170. // TODO: do not unload if target will load (included in url/rows/columns)
  171. $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), () => {
  172. // to mitigate improper rendering for multiple consecutive calls
  173. // https://github.com/naver/billboard.js/issues/2121
  174. requestIdleCallback(() => $$.loadFromArgs(args));
  175. });
  176. } else {
  177. $$.loadFromArgs(args);
  178. }
  179. },
  180. /**
  181. * Unload data to the chart.<br><br>
  182. * You can specify multiple targets by giving an array that includes id as String. If no argument is given, all of targets will be toggles.
  183. * - <b>Note:</b>
  184. * If you call load API soon after/before unload, unload param of load should be used. Otherwise chart will not be rendered properly because of cancel of animation.<br>
  185. * `done` will be called after data loaded, but it's not after rendering. It's because rendering will finish after some transition and there is some time lag between loading and rendering.
  186. * @function unload
  187. * @instance
  188. * @memberof Chart
  189. * @param {object} argsValue
  190. * | key | Type | Description |
  191. * | --- | --- | --- |
  192. * | ids | String &vert; Array | Target id data to be unloaded. If not given, all data will be unloaded. |
  193. * | done | Fuction | Callback after data is unloaded. |
  194. * | resizeAfter | boolean | Resize after the unload. Default value is `false`.<br>- This option won't call `onresize` neither `onresized`.<br>- When set to 'true', will call `.flush(true)` at the end of unload. |
  195. * @example
  196. * // Unload data2 and data3
  197. * chart.unload({
  198. * ids: ["data2", "data3"],
  199. * done: function() {
  200. * // called after the unloaded
  201. * },
  202. * resizeAfter: true // will resize after unload
  203. * });
  204. */
  205. unload(argsValue): void {
  206. const $$ = this.internal;
  207. let args = argsValue || {};
  208. // hide possible tooltip display when data is completely unloaded
  209. isEmpty(args) && this.tooltip.hide();
  210. if (isArray(args)) {
  211. args = {ids: args};
  212. } else if (isString(args)) {
  213. args = {ids: [args]};
  214. }
  215. const ids = $$.mapToTargetIds(args.ids);
  216. $$.unload(ids, () => {
  217. $$.redraw({
  218. withUpdateOrgXDomain: true,
  219. withUpdateXDomain: true,
  220. withLegend: true
  221. });
  222. $$.cache.remove(ids);
  223. callDone.call($$, args.done, args.resizeAfter);
  224. });
  225. }
  226. };