feat(uti): Add iterative data
[csit.git] / resources / tools / dash / app / pal / trending / layout.py
index b5286a0..55d0d08 100644 (file)
@@ -14,6 +14,7 @@
 """Plotly Dash HTML layout override.
 """
 
 """Plotly Dash HTML layout override.
 """
 
+import logging
 import pandas as pd
 import dash_bootstrap_components as dbc
 
 import pandas as pd
 import dash_bootstrap_components as dbc
 
@@ -27,8 +28,10 @@ from yaml import load, FullLoader, YAMLError
 from datetime import datetime, timedelta
 from copy import deepcopy
 from json import loads, JSONDecodeError
 from datetime import datetime, timedelta
 from copy import deepcopy
 from json import loads, JSONDecodeError
+from ast import literal_eval
 
 from ..data.data import Data
 
 from ..data.data import Data
+from ..data.url_processing import url_decode, url_encode
 from .graphs import graph_trending, graph_hdrh_latency, \
     select_trending_data
 
 from .graphs import graph_trending, graph_hdrh_latency, \
     select_trending_data
 
@@ -37,6 +40,10 @@ class Layout:
     """
     """
 
     """
     """
 
+    # If True, clear all inputs in control panel when button "ADD SELECTED" is
+    # pressed.
+    CLEAR_ALL_INPUTS = False
+
     STYLE_DISABLED = {"display": "none"}
     STYLE_ENABLED = {"display": "inherit"}
 
     STYLE_DISABLED = {"display": "none"}
     STYLE_ENABLED = {"display": "inherit"}
 
@@ -72,8 +79,14 @@ class Layout:
         "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
     }
 
         "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
     }
 
-    def __init__(self, app: Flask, html_layout_file: str, spec_file: str,
-        graph_layout_file: str, data_spec_file: str,
+    URL_STYLE = {
+        "background-color": "#d2ebf5",
+        "border-color": "#bce1f1",
+        "color": "#135d7c"
+    }
+
+    def __init__(self, app: Flask, html_layout_file: str,
+        graph_layout_file: str, data_spec_file: str, tooltip_file: str,
         time_period: str=None) -> None:
         """
         """
         time_period: str=None) -> None:
         """
         """
@@ -81,9 +94,9 @@ class Layout:
         # Inputs
         self._app = app
         self._html_layout_file = html_layout_file
         # Inputs
         self._app = app
         self._html_layout_file = html_layout_file
-        self._spec_file = spec_file
         self._graph_layout_file = graph_layout_file
         self._data_spec_file = data_spec_file
         self._graph_layout_file = graph_layout_file
         self._data_spec_file = data_spec_file
+        self._tooltip_file = tooltip_file
         self._time_period = time_period
 
         # Read the data:
         self._time_period = time_period
 
         # Read the data:
@@ -135,7 +148,7 @@ class Layout:
             infra = "-".join((tbed, nic, driver))
             lst_test = test.split("-")
             framesize = lst_test[0]
             infra = "-".join((tbed, nic, driver))
             lst_test = test.split("-")
             framesize = lst_test[0]
-            core = lst_test[1] if lst_test[1] else "1C"
+            core = lst_test[1] if lst_test[1] else "8C"
             test = "-".join(lst_test[2: -1])
 
             if tbs.get(dut, None) is None:
             test = "-".join(lst_test[2: -1])
 
             if tbs.get(dut, None) is None:
@@ -167,6 +180,7 @@ class Layout:
         # Read from files:
         self._html_layout = ""
         self._graph_layout = None
         # Read from files:
         self._html_layout = ""
         self._graph_layout = None
+        self._tooltips = dict()
 
         try:
             with open(self._html_layout_file, "r") as file_read:
 
         try:
             with open(self._html_layout_file, "r") as file_read:
@@ -187,8 +201,20 @@ class Layout:
         except YAMLError as err:
             raise RuntimeError(
                 f"An error occurred while parsing the specification file "
         except YAMLError as err:
             raise RuntimeError(
                 f"An error occurred while parsing the specification file "
-                f"{self._graph_layout_file}\n"
-                f"{err}"
+                f"{self._graph_layout_file}\n{err}"
+            )
+
+        try:
+            with open(self._tooltip_file, "r") as file_read:
+                self._tooltips = load(file_read, Loader=FullLoader)
+        except IOError as err:
+            logging.warning(
+                f"Not possible to open the file {self._tooltip_file}\n{err}"
+            )
+        except YAMLError as err:
+            logging.warning(
+                f"An error occurred while parsing the specification file "
+                f"{self._tooltip_file}\n{err}"
             )
 
         # Callbacks:
             )
 
         # Callbacks:
@@ -218,6 +244,29 @@ class Layout:
     def label(self, key: str) -> str:
         return self.LABELS.get(key, key)
 
     def label(self, key: str) -> str:
         return self.LABELS.get(key, key)
 
+    def _show_tooltip(self, id: str, title: str,
+            clipboard_id: str=None) -> list:
+        """
+        """
+        return [
+            dcc.Clipboard(target_id=clipboard_id, title="Copy URL") \
+                if clipboard_id else str(),
+            f"{title} ",
+            dbc.Badge(
+                id=id,
+                children="?",
+                pill=True,
+                color="white",
+                text_color="info",
+                class_name="border ms-1",
+            ),
+            dbc.Tooltip(
+                children=self._tooltips.get(id, str()),
+                target=id,
+                placement="auto"
+            )
+        ]
+
     def add_content(self):
         """
         """
     def add_content(self):
         """
         """
@@ -249,12 +298,9 @@ class Layout:
                         id="row-main",
                         class_name="g-0",
                         children=[
                         id="row-main",
                         class_name="g-0",
                         children=[
-                            dcc.Store(
-                                id="selected-tests"
-                            ),
-                            dcc.Store(
-                                id="control-panel"
-                            ),
+                            dcc.Store(id="selected-tests"),
+                            dcc.Store(id="control-panel"),
+                            dcc.Location(id="url", refresh=False),
                             self._add_ctrl_col(),
                             self._add_plotting_col(),
                         ]
                             self._add_ctrl_col(),
                             self._add_plotting_col(),
                         ]
@@ -353,7 +399,10 @@ class Layout:
                     children=[
                         dbc.InputGroup(
                             [
                     children=[
                         dbc.InputGroup(
                             [
-                                dbc.InputGroupText("DUT"),
+                                dbc.InputGroupText(
+                                    children=self._show_tooltip(
+                                        "help-dut", "DUT")
+                                ),
                                 dbc.Select(
                                     id="dd-ctrl-dut",
                                     placeholder=(
                                 dbc.Select(
                                     id="dd-ctrl-dut",
                                     placeholder=(
@@ -378,7 +427,10 @@ class Layout:
                     children=[
                         dbc.InputGroup(
                             [
                     children=[
                         dbc.InputGroup(
                             [
-                                dbc.InputGroupText("Infra"),
+                                dbc.InputGroupText(
+                                    children=self._show_tooltip(
+                                        "help-infra", "Infra")
+                                ),
                                 dbc.Select(
                                     id="dd-ctrl-phy",
                                     placeholder=(
                                 dbc.Select(
                                     id="dd-ctrl-phy",
                                     placeholder=(
@@ -397,7 +449,10 @@ class Layout:
                     children=[
                         dbc.InputGroup(
                             [
                     children=[
                         dbc.InputGroup(
                             [
-                                dbc.InputGroupText("Area"),
+                                dbc.InputGroupText(
+                                    children=self._show_tooltip(
+                                        "help-area", "Area")
+                                ),
                                 dbc.Select(
                                     id="dd-ctrl-area",
                                     placeholder="Select an Area...",
                                 dbc.Select(
                                     id="dd-ctrl-area",
                                     placeholder="Select an Area...",
@@ -414,7 +469,10 @@ class Layout:
                     children=[
                         dbc.InputGroup(
                             [
                     children=[
                         dbc.InputGroup(
                             [
-                                dbc.InputGroupText("Test"),
+                                dbc.InputGroupText(
+                                    children=self._show_tooltip(
+                                        "help-test", "Test")
+                                ),
                                 dbc.Select(
                                     id="dd-ctrl-test",
                                     placeholder="Select a Test...",
                                 dbc.Select(
                                     id="dd-ctrl-test",
                                     placeholder="Select a Test...",
@@ -427,28 +485,29 @@ class Layout:
                     ]
                 ),
                 dbc.Row(
                     ]
                 ),
                 dbc.Row(
-                    id="row-ctrl-core",
+                    id="row-ctrl-framesize",
                     class_name="gy-1",
                     children=[
                         dbc.Label(
                     class_name="gy-1",
                     children=[
                         dbc.Label(
-                            "Number of Cores",
+                            children=self._show_tooltip(
+                                "help-framesize", "Frame Size"),
                             class_name="p-0"
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
                             class_name="p-0"
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
-                                    id="cl-ctrl-core-all",
+                                    id="cl-ctrl-framesize-all",
                                     options=self.CL_ALL_DISABLED,
                                     options=self.CL_ALL_DISABLED,
-                                    inline=False,
+                                    inline=True,
                                     switch=False
                                     switch=False
-                                )
+                                ),
                             ],
                             width=3
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
                             ],
                             width=3
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
-                                    id="cl-ctrl-core",
+                                    id="cl-ctrl-framesize",
                                     inline=True,
                                     switch=False
                                 )
                                     inline=True,
                                     switch=False
                                 )
@@ -457,28 +516,29 @@ class Layout:
                     ]
                 ),
                 dbc.Row(
                     ]
                 ),
                 dbc.Row(
-                    id="row-ctrl-framesize",
+                    id="row-ctrl-core",
                     class_name="gy-1",
                     children=[
                         dbc.Label(
                     class_name="gy-1",
                     children=[
                         dbc.Label(
-                            "Frame Size",
+                            children=self._show_tooltip(
+                                "help-cores", "Number of Cores"),
                             class_name="p-0"
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
                             class_name="p-0"
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
-                                    id="cl-ctrl-framesize-all",
+                                    id="cl-ctrl-core-all",
                                     options=self.CL_ALL_DISABLED,
                                     options=self.CL_ALL_DISABLED,
-                                    inline=True,
+                                    inline=False,
                                     switch=False
                                     switch=False
-                                ),
+                                )
                             ],
                             width=3
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
                             ],
                             width=3
                         ),
                         dbc.Col(
                             children=[
                                 dbc.Checklist(
-                                    id="cl-ctrl-framesize",
+                                    id="cl-ctrl-core",
                                     inline=True,
                                     switch=False
                                 )
                                     inline=True,
                                     switch=False
                                 )
@@ -491,7 +551,8 @@ class Layout:
                     class_name="gy-1",
                     children=[
                         dbc.Label(
                     class_name="gy-1",
                     children=[
                         dbc.Label(
-                            "Test Type",
+                            children=self._show_tooltip(
+                                "help-ttype", "Test Type"),
                             class_name="p-0"
                         ),
                         dbc.Col(
                             class_name="p-0"
                         ),
                         dbc.Col(
@@ -535,6 +596,11 @@ class Layout:
                 dbc.Row(
                     class_name="gy-1",
                     children=[
                 dbc.Row(
                     class_name="gy-1",
                     children=[
+                        dbc.Label(
+                            class_name="gy-1",
+                            children=self._show_tooltip(
+                                "help-time-period", "Time Period"),
+                        ),
                         dcc.DatePickerRange(
                             id="dpr-period",
                             className="d-flex justify-content-center",
                         dcc.DatePickerRange(
                             id="dpr-period",
                             className="d-flex justify-content-center",
@@ -547,7 +613,7 @@ class Layout:
                                 datetime.utcnow() - timedelta(
                                     days=self.time_period),
                             end_date=datetime.utcnow(),
                                 datetime.utcnow() - timedelta(
                                     days=self.time_period),
                             end_date=datetime.utcnow(),
-                            display_format="D MMMM YY"
+                            display_format="D MMM YY"
                         )
                     ]
                 ),
                         )
                     ]
                 ),
@@ -681,13 +747,17 @@ class Layout:
         else:
             return list()
 
         else:
             return list()
 
+    @staticmethod
+    def _get_date(s_date: str) -> datetime:
+        return datetime(int(s_date[0:4]), int(s_date[5:7]), int(s_date[8:10]))
+
     def callbacks(self, app):
 
     def callbacks(self, app):
 
-        def _generate_plotting_arrea(args: tuple) -> tuple:
+        def _generate_plotting_area(figs: tuple, url: str) -> tuple:
             """
             """
 
             """
             """
 
-            (fig_tput, fig_lat) = args
+            (fig_tput, fig_lat) = figs
 
             row_fig_tput = self.PLACEHOLDER
             row_fig_lat = self.PLACEHOLDER
 
             row_fig_tput = self.PLACEHOLDER
             row_fig_lat = self.PLACEHOLDER
@@ -701,15 +771,43 @@ class Layout:
                     )
                 ]
                 row_btn_dwnld = [
                     )
                 ]
                 row_btn_dwnld = [
-                    dcc.Loading(children=[
-                        dbc.Button(
-                            id="btn-download-data",
-                            children=["Download Data"],
-                            class_name="me-1",
-                            color="info"
-                        ),
-                        dcc.Download(id="download-data")
-                    ]),
+                    dbc.Col(  # Download
+                        width=2,
+                        children=[
+                            dcc.Loading(children=[
+                                dbc.Button(
+                                    id="btn-download-data",
+                                    children=self._show_tooltip(
+                                        "help-download", "Download Data"),
+                                    class_name="me-1",
+                                    color="info"
+                                ),
+                                dcc.Download(id="download-data")
+                            ]),
+                        ]
+                    ),
+                    dbc.Col(  # Show URL
+                        width=10,
+                        children=[
+                            dbc.InputGroup(
+                                class_name="me-1",
+                                children=[
+                                    dbc.InputGroupText(
+                                        style=self.URL_STYLE,
+                                        children=self._show_tooltip(
+                                            "help-url", "URL", "input-url")
+                                    ),
+                                    dbc.Input(
+                                        id="input-url",
+                                        readonly=True,
+                                        type="url",
+                                        style=self.URL_STYLE,
+                                        value=url
+                                    )
+                                ]
+                            )
+                        ]
+                    )
                 ]
             if fig_lat:
                 row_fig_lat = [
                 ]
             if fig_lat:
                 row_fig_lat = [
@@ -771,19 +869,43 @@ class Layout:
             Input("dpr-period", "end_date"),
             Input("btn-sel-remove", "n_clicks"),
             Input("btn-sel-remove-all", "n_clicks"),
             Input("dpr-period", "end_date"),
             Input("btn-sel-remove", "n_clicks"),
             Input("btn-sel-remove-all", "n_clicks"),
+            Input("url", "href")
         )
         def _update_ctrl_panel(cp_data: dict, store_sel: list, list_sel: list,
             dd_dut: str, dd_phy: str, dd_area: str, dd_test: str, cl_core: list,
             cl_core_all: list, cl_framesize: list, cl_framesize_all: list,
             cl_testtype: list, cl_testtype_all: list, btn_add: int,
             d_start: str, d_end: str, btn_remove: int,
         )
         def _update_ctrl_panel(cp_data: dict, store_sel: list, list_sel: list,
             dd_dut: str, dd_phy: str, dd_area: str, dd_test: str, cl_core: list,
             cl_core_all: list, cl_framesize: list, cl_framesize_all: list,
             cl_testtype: list, cl_testtype_all: list, btn_add: int,
             d_start: str, d_end: str, btn_remove: int,
-            btn_remove_all: int) -> tuple:
+            btn_remove_all: int, href: str) -> tuple:
             """
             """
 
             """
             """
 
-            d_start = datetime(int(d_start[0:4]), int(d_start[5:7]),
-                int(d_start[8:10]))
-            d_end = datetime(int(d_end[0:4]), int(d_end[5:7]), int(d_end[8:10]))
+            def _gen_new_url(parsed_url: dict, store_sel: list,
+                    start: datetime, end: datetime) -> str:
+
+                if parsed_url:
+                    new_url = url_encode({
+                        "scheme": parsed_url["scheme"],
+                        "netloc": parsed_url["netloc"],
+                        "path": parsed_url["path"],
+                        "params": {
+                            "store_sel": store_sel,
+                            "start": start,
+                            "end": end
+                        }
+                    })
+                else:
+                    new_url = str()
+                return new_url
+
+
+            ctrl_panel = self.ControlPanel(cp_data)
+
+            d_start = self._get_date(d_start)
+            d_end = self._get_date(d_end)
+
+            # Parse the url:
+            parsed_url = url_decode(href)
 
             row_fig_tput = no_update
             row_fig_lat = no_update
 
             row_fig_tput = no_update
             row_fig_lat = no_update
@@ -791,17 +913,13 @@ class Layout:
             row_card_sel_tests = no_update
             row_btns_sel_tests = no_update
 
             row_card_sel_tests = no_update
             row_btns_sel_tests = no_update
 
-            ctrl_panel = self.ControlPanel(cp_data)
-
             trigger_id = callback_context.triggered[0]["prop_id"].split(".")[0]
 
             if trigger_id == "dd-ctrl-dut":
                 try:
             trigger_id = callback_context.triggered[0]["prop_id"].split(".")[0]
 
             if trigger_id == "dd-ctrl-dut":
                 try:
+                    dut = self.spec_tbs[dd_dut]
                     options = sorted(
                     options = sorted(
-                        [
-                            {"label": v, "value": v}
-                                for v in self.spec_tbs[dd_dut].keys()
-                        ],
+                        [{"label": v, "value": v}for v in dut.keys()],
                         key=lambda d: d["label"]
                     )
                     disabled = False
                         key=lambda d: d["label"]
                     )
                     disabled = False
@@ -816,6 +934,7 @@ class Layout:
                     "dd-ctrl-area-value": str(),
                     "dd-ctrl-area-options": list(),
                     "dd-ctrl-area-disabled": True,
                     "dd-ctrl-area-value": str(),
                     "dd-ctrl-area-options": list(),
                     "dd-ctrl-area-disabled": True,
+                    "dd-ctrl-test-value": str(),
                     "dd-ctrl-test-options": list(),
                     "dd-ctrl-test-disabled": True,
                     "cl-ctrl-core-options": list(),
                     "dd-ctrl-test-options": list(),
                     "dd-ctrl-test-disabled": True,
                     "cl-ctrl-core-options": list(),
@@ -831,14 +950,13 @@ class Layout:
                     "cl-ctrl-testtype-all-value": list(),
                     "cl-ctrl-testtype-all-options": self.CL_ALL_DISABLED,
                 })
                     "cl-ctrl-testtype-all-value": list(),
                     "cl-ctrl-testtype-all-options": self.CL_ALL_DISABLED,
                 })
-            if trigger_id == "dd-ctrl-phy":
+            elif trigger_id == "dd-ctrl-phy":
                 try:
                     dut = ctrl_panel.get("dd-ctrl-dut-value")
                 try:
                     dut = ctrl_panel.get("dd-ctrl-dut-value")
+                    phy = self.spec_tbs[dut][dd_phy]
                     options = sorted(
                     options = sorted(
-                        [
-                            {"label": self.label(v), "value": v}
-                                for v in self.spec_tbs[dut][dd_phy].keys()
-                        ],
+                        [{"label": self.label(v), "value": v}
+                            for v in phy.keys()],
                         key=lambda d: d["label"]
                     )
                     disabled = False
                         key=lambda d: d["label"]
                     )
                     disabled = False
@@ -850,6 +968,7 @@ class Layout:
                     "dd-ctrl-area-value": str(),
                     "dd-ctrl-area-options": options,
                     "dd-ctrl-area-disabled": disabled,
                     "dd-ctrl-area-value": str(),
                     "dd-ctrl-area-options": options,
                     "dd-ctrl-area-disabled": disabled,
+                    "dd-ctrl-test-value": str(),
                     "dd-ctrl-test-options": list(),
                     "dd-ctrl-test-disabled": True,
                     "cl-ctrl-core-options": list(),
                     "dd-ctrl-test-options": list(),
                     "dd-ctrl-test-disabled": True,
                     "cl-ctrl-core-options": list(),
@@ -869,11 +988,9 @@ class Layout:
                 try:
                     dut = ctrl_panel.get("dd-ctrl-dut-value")
                     phy = ctrl_panel.get("dd-ctrl-phy-value")
                 try:
                     dut = ctrl_panel.get("dd-ctrl-dut-value")
                     phy = ctrl_panel.get("dd-ctrl-phy-value")
+                    area = self.spec_tbs[dut][phy][dd_area]
                     options = sorted(
                     options = sorted(
-                        [
-                            {"label": v, "value": v}
-                                for v in self.spec_tbs[dut][phy][dd_area].keys()
-                        ],
+                        [{"label": v, "value": v} for v in area.keys()],
                         key=lambda d: d["label"]
                     )
                     disabled = False
                         key=lambda d: d["label"]
                     )
                     disabled = False
@@ -905,19 +1022,17 @@ class Layout:
                 dut = ctrl_panel.get("dd-ctrl-dut-value")
                 phy = ctrl_panel.get("dd-ctrl-phy-value")
                 area = ctrl_panel.get("dd-ctrl-area-value")
                 dut = ctrl_panel.get("dd-ctrl-dut-value")
                 phy = ctrl_panel.get("dd-ctrl-phy-value")
                 area = ctrl_panel.get("dd-ctrl-area-value")
-                cores = self.spec_tbs[dut][phy][area][dd_test]["core"]
-                fsizes = self.spec_tbs[dut][phy][area][dd_test]["frame-size"]
-                ttypes = self.spec_tbs[dut][phy][area][dd_test]["test-type"]
+                test = self.spec_tbs[dut][phy][area][dd_test]
+                cores = test["core"]
+                fsizes = test["frame-size"]
+                ttypes = test["test-type"]
                 if dut and phy and area and dd_test:
                 if dut and phy and area and dd_test:
-                    core_opts = [
-                        {"label": v, "value": v} for v in sorted(cores)
-                    ]
-                    framesize_opts = [
-                        {"label": v, "value": v} for v in sorted(fsizes)
-                    ]
-                    testtype_opts = [
-                        {"label": v, "value": v}for v in sorted(ttypes)
-                    ]
+                    core_opts = [{"label": v, "value": v}
+                        for v in sorted(cores)]
+                    framesize_opts = [{"label": v, "value": v}
+                        for v in sorted(fsizes)]
+                    testtype_opts = [{"label": v, "value": v}
+                        for v in sorted(ttypes)]
                     ctrl_panel.set({
                         "dd-ctrl-test-value": dd_test,
                         "cl-ctrl-core-options": core_opts,
                     ctrl_panel.set({
                         "dd-ctrl-test-value": dd_test,
                         "cl-ctrl-core-options": core_opts,
@@ -1036,23 +1151,23 @@ class Layout:
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
                     row_card_sel_tests = self.STYLE_ENABLED
                     row_btns_sel_tests = self.STYLE_ENABLED
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
                     row_card_sel_tests = self.STYLE_ENABLED
                     row_btns_sel_tests = self.STYLE_ENABLED
-                    ctrl_panel.set(ctrl_panel.defaults)
+                    if self.CLEAR_ALL_INPUTS:
+                        ctrl_panel.set(ctrl_panel.defaults)
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                     row_fig_tput, row_fig_lat, row_btn_dwnld = \
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                     row_fig_tput, row_fig_lat, row_btn_dwnld = \
-                        _generate_plotting_arrea(
-                            graph_trending(
-                                self.data, store_sel, self.layout, d_start,
-                                d_end
-                            )
+                        _generate_plotting_area(
+                            graph_trending(self.data, store_sel, self.layout,
+                                d_start, d_end),
+                            _gen_new_url(parsed_url, store_sel, d_start, d_end)
                         )
             elif trigger_id == "dpr-period":
                 row_fig_tput, row_fig_lat, row_btn_dwnld = \
                         )
             elif trigger_id == "dpr-period":
                 row_fig_tput, row_fig_lat, row_btn_dwnld = \
-                    _generate_plotting_arrea(
-                        graph_trending(
-                            self.data, store_sel, self.layout, d_start, d_end
-                        )
+                    _generate_plotting_area(
+                        graph_trending(self.data, store_sel, self.layout,
+                            d_start, d_end),
+                        _gen_new_url(parsed_url, store_sel, d_start, d_end)
                     )
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
                     )
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
@@ -1062,9 +1177,7 @@ class Layout:
                 row_card_sel_tests = self.STYLE_DISABLED
                 row_btns_sel_tests = self.STYLE_DISABLED
                 store_sel = list()
                 row_card_sel_tests = self.STYLE_DISABLED
                 row_btns_sel_tests = self.STYLE_DISABLED
                 store_sel = list()
-                ctrl_panel.set({
-                        "cl-selected-options": list()
-                })
+                ctrl_panel.set({"cl-selected-options": list()})
             elif trigger_id == "btn-sel-remove":
                 _ = btn_remove
                 if list_sel:
             elif trigger_id == "btn-sel-remove":
                 _ = btn_remove
                 if list_sel:
@@ -1075,11 +1188,10 @@ class Layout:
                     store_sel = new_store_sel
                 if store_sel:
                     row_fig_tput, row_fig_lat, row_btn_dwnld = \
                     store_sel = new_store_sel
                 if store_sel:
                     row_fig_tput, row_fig_lat, row_btn_dwnld = \
-                        _generate_plotting_arrea(
-                            graph_trending(
-                                self.data, store_sel, self.layout, d_start,
-                                d_end
-                            )
+                        _generate_plotting_area(
+                            graph_trending(self.data, store_sel, self.layout,
+                                d_start, d_end),
+                            _gen_new_url(parsed_url, store_sel, d_start, d_end)
                         )
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                         )
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
@@ -1091,9 +1203,41 @@ class Layout:
                     row_card_sel_tests = self.STYLE_DISABLED
                     row_btns_sel_tests = self.STYLE_DISABLED
                     store_sel = list()
                     row_card_sel_tests = self.STYLE_DISABLED
                     row_btns_sel_tests = self.STYLE_DISABLED
                     store_sel = list()
-                    ctrl_panel.set({
-                            "cl-selected-options": list()
-                    })
+                    ctrl_panel.set({"cl-selected-options": list()})
+            elif trigger_id == "url":
+                # TODO: Add verification
+                url_params = parsed_url["params"]
+                if url_params:
+                    store_sel = literal_eval(
+                        url_params.get("store_sel", list())[0])
+                    d_start = self._get_date(url_params.get("start", list())[0])
+                    d_end = self._get_date(url_params.get("end", list())[0])
+                    if store_sel:
+                        row_fig_tput, row_fig_lat, row_btn_dwnld = \
+                            _generate_plotting_area(
+                                graph_trending(
+                                    self.data, store_sel, self.layout, d_start,
+                                    d_end
+                                ),
+                                _gen_new_url(
+                                    parsed_url, store_sel, d_start, d_end
+                                )
+                            )
+                        row_card_sel_tests = self.STYLE_ENABLED
+                        row_btns_sel_tests = self.STYLE_ENABLED
+                        ctrl_panel.set({
+                            "cl-selected-options": self._list_tests(store_sel)
+                        })
+                    else:
+                        row_fig_tput = self.PLACEHOLDER
+                        row_fig_lat = self.PLACEHOLDER
+                        row_btn_dwnld = self.PLACEHOLDER
+                        row_card_sel_tests = self.STYLE_DISABLED
+                        row_btns_sel_tests = self.STYLE_DISABLED
+                        store_sel = list()
+                        ctrl_panel.set({
+                                "cl-selected-options": list()
+                        })
 
             if ctrl_panel.get("cl-ctrl-core-value") and \
                     ctrl_panel.get("cl-ctrl-framesize-value") and \
 
             if ctrl_panel.get("cl-ctrl-core-value") and \
                     ctrl_panel.get("cl-ctrl-framesize-value") and \
@@ -1101,9 +1245,7 @@ class Layout:
                 disabled = False
             else:
                 disabled = True
                 disabled = False
             else:
                 disabled = True
-            ctrl_panel.set({
-                "btn-ctrl-add-disabled": disabled
-            })
+            ctrl_panel.set({"btn-ctrl-add-disabled": disabled})
 
             ret_val = [
                 ctrl_panel.panel, store_sel,
 
             ret_val = [
                 ctrl_panel.panel, store_sel,