## 5 System Performance
### Enhanced Interactivity in Data Visualization  
With the functioning of the multi-sensor device, some amendments were made to the web application to enhance the user experience. Embedding a chart inside an _iframe_ allows seamless integration of Grafana with the web application, ensuring visual consistency across web pages. However, interaction between the web application and the _iframe_ is essential for users to navigate through different visualizations and update the chart accordingly. Grafana offers only a rudimentary mechanism for interacting with the _iframe_, i.e., altering its URL. This action prompts the _iframe_ to automatically clear its content and request another panel from the server in accordance with the specified parameters, as outlined in Section 4.2.2. However, as shown in Figure 16, this operation is not instantaneous and, by requiring the _iframe_ to clear before displaying a new chart, the previously occupied area remains empty for a significant period, causing a visually unpleasant effect. Figure 16: Detail of the network panel of the Chrome DevTools application showing the number of resources requested by the original (**left**) and the proposed (**right**) approach together with the time spent. Figure 15: Maximum error between the decimated and the original series for sampling times up to 5 min. An alternative mechanism has been implemented to prevent the _iframe_ from clearing its content when a chart needs updating. Instead of changing the URL, a message with the new parameters is passed from the application to the _iframe_ (which is itself a React web application) to communicate the need for an update. As a result, upon successfully retrieving the new data, the chart is redrawn accordingly without any visual interruption for the user. This solution is based on the JavaScript method _window.postMessage()_ that safely enables communication between window objects (i.e., web pages), such as the main page and the embedded _iframe_. The sender window may obtain a reference to the destination window and then dispatch a _MessageEvent_ on it, with the data passed to the method (i.e., the \"message\" containing the required data) being exposed to the receiving window through the event object; this window can then listen for dispatched messages by executing the _addEventListener_ method. The implementation of the mechanism on the sender side, the project web application, is relatively straightforward, because all the necessary data are readily available. Conversely, implementing this mechanism on the receiver side necessitates understanding and carefully modifying the Grafana code. Fortunately, Grafana is open source, and its codebase is accessible on GitHub, facilitating the necessary modifications. Two distinct message handlers are necessary in two separate components of the Grafana React Application, which is contained within the _iframe_. To modify the panel id, a callback must be registered via the _addEventListener_ method in the _GrafanaRoute_ component. Then, the change of the other parameters is managed by an _addEventListener_ callback in the _PanelStateWrapper_ component, where the panel variables can be adjusted, and a refresh of the panel can be triggered to display the new data. By implementing such modifications, the user is not presented with a blank page during the process. As shown in Figure 17, the proposed solution reduces the loading time, thereby offering a more immediate feedback to the user. The amount of resources that need to be retrieved from the server is significantly reduced, as detailed Figure 16, and although most of them are cached by the browser, this difference results in a refresh time reduction of almost an order of magnitude.