controllers/dashboard/data_visualisation_controller.js

  1. import { Controller } from "@hotwired/stimulus"
  2. import { debounce } from "debounce"
  3. import { subscription } from "~/javascripts/store/mixins/subscription"
  4. import LineChart from "~/javascripts/dashboard/LineChart"
  5. /**
  6. * @class Dashboard.DataVisualisationController
  7. * @classdesc Stimulus controller that handles the line chart data visualisation.
  8. * @extends Controller
  9. **/
  10. export default class extends Controller {
  11. static targets = [ "loading", "visualisation" ]
  12. static values = {
  13. date: String,
  14. storeId: String,
  15. timeFormat: String,
  16. xAxis: String,
  17. yAxis: String
  18. }
  19. /**
  20. * Subscribe to the store. Debounces the method for handling window resizes
  21. *
  22. * @instance
  23. * @memberof Dashboard.DataVisualisationController
  24. **/
  25. connect() {
  26. subscription(this)
  27. this.subscribe()
  28. this.editStore("frameLoaded", true)
  29. this.reconnect()
  30. this.resize = debounce(this.resize, 250).bind(this)
  31. }
  32. /**
  33. * Handles a repeated Turbo visit to the dashboard page.
  34. *
  35. * @instance
  36. * @memberof Dashboard.DataVisualisationController
  37. **/
  38. reconnect() {
  39. if (this.store("selectedContextData")) {
  40. this.storeUpdated("selectedContextData", this.storeIdValue)
  41. }
  42. }
  43. /**
  44. * Checks if the visualisation has been created yet
  45. *
  46. * @instance
  47. * @memberof Dashboard.DataVisualisationController
  48. **/
  49. isDataVizEmpty() {
  50. return document.querySelector("[data-viz='wrapper']").getElementsByTagName("svg").length === 0
  51. }
  52. /**
  53. * Creates a new instance of the LineChart class if not created, otherwise returns the instance of
  54. * the class
  55. *
  56. * @instance
  57. * @memberof Dashboard.DataVisualisationController
  58. **/
  59. lineChart() {
  60. if (this._lineChart === undefined) {
  61. this._windowWidth = window.innerWidth
  62. this._lineChart = new LineChart(
  63. this.store("selectedContextData"),
  64. this.store("contextSelected"),
  65. this.yAxisValue,
  66. this.xAxisValue,
  67. this.dateValue,
  68. this.timeFormatValue,
  69. "[data-viz='wrapper']",
  70. "[data-viz='tooltip']"
  71. )
  72. }
  73. return this._lineChart
  74. }
  75. /**
  76. * Handles a resize of the screen by width but ignores height changes. Deletes the current
  77. * visualisation and the instance of the LineChart class so it will be created from scratch again.
  78. *
  79. * @instance
  80. * @memberof Dashboard.DataVisualisationController
  81. **/
  82. resize() {
  83. if (window.innerWidth === this._windowWidth) return
  84. this._windowWidth = window.innerWidth
  85. this._lineChart = undefined
  86. const wrapper = document.querySelector("[data-viz='wrapper']")
  87. wrapper.removeChild(wrapper.lastChild)
  88. this.lineChart().createDataVis()
  89. }
  90. /**
  91. * When the context is selected the data visualisation will either be creted or updated
  92. *
  93. * @instance
  94. * @memberof Dashboard.DataVisualisationController
  95. **/
  96. storeUpdated(prop, storeId) {
  97. if (this.store("fetchingDataVizData")) {
  98. this.loadingTarget.style.display = "block"
  99. this.visualisationTarget.style.display = "none"
  100. } else {
  101. if (prop !== "selectedContextData" && storeId === this.storeIdValue) return
  102. this.loadingTarget.style.display = "none"
  103. this.visualisationTarget.style.display = "block"
  104. if(this.isDataVizEmpty()) {
  105. this.lineChart().createDataVis()
  106. } else {
  107. this.lineChart().updateDataVis(this.store("selectedContextData"), this.store("contextSelected"))
  108. }
  109. }
  110. }
  111. /**
  112. * Unsubscribe from the store
  113. *
  114. * @instance
  115. * @memberof Dashboard.DataVisualisationController
  116. **/
  117. disconnect() {
  118. this.unsubscribe()
  119. }
  120. }