ILinePlotGen.py revision 67527ddea39e858c957997356a16bd8e3819f359
18741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# $Copyright:
28741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# ----------------------------------------------------------------
38741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# This confidential and proprietary software may be used only as
48741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# authorised by a licensing agreement from ARM Limited
58741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh#  (C) COPYRIGHT 2015 ARM Limited
68741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh#       ALL RIGHTS RESERVED
78741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# The entire notice above must be reproduced on all authorised
88741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# copies and copies may only be made to the extent permitted
98741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# by a licensing agreement from ARM Limited.
108741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# ----------------------------------------------------------------
118741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# File:        ILinePlotGen.py
128741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# ----------------------------------------------------------------
138741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh# $
148741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh#
158741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh"""This module is reponsible for creating a layout
168741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhof plots as a 2D axes and handling corener cases
178741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhand deleting empty plots
188741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh"""
198741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
208741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhfrom cr2.plotter import AttrConf
218741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport uuid
228741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport json
238741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport os
248741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhfrom IPython.display import display, HTML
258741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
26e1a703051d7cf345003f0ed4cfa7c25a76b0105cKapileshwar Singh
278741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhif not AttrConf.PLOTTER_IPYTHON:
288741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    raise ImportError("No Ipython Environment found")
298741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
30e1a703051d7cf345003f0ed4cfa7c25a76b0105cKapileshwar Singh# Install resources
31e1a703051d7cf345003f0ed4cfa7c25a76b0105cKapileshwar Singhfrom cr2.plotter import Utils
324aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar SinghUtils.iplot_install("ILinePlot")
33e1a703051d7cf345003f0ed4cfa7c25a76b0105cKapileshwar Singh
348741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
358741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhclass ILinePlotGen(object):
368741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
378741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    """Cols is the number of columns to draw
388741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh       rows are calculated as 1D - 2D transformation
398741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh       the same transformation is used to index the
408741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh       axes array
418741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    """
428741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
438741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _add_graph_cell(self, fig_name):
448741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add a HTML table cell to hold the plot"""
458741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
468741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        width = int(self._attr["width"] / self._cols)
47211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh        div_js = """
484aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            <script>
494aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            var ilp_req = require.config( {
504aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh
5107ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                paths: {
5207ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "dygraph-sync": "/static/plotter_scripts/ILinePlot/synchronizer",
5307ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "dygraph": "/static/plotter_scripts/ILinePlot/dygraph-combined",
5407ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "ILinePlot": "/static/plotter_scripts/ILinePlot/ILinePlot",
5507ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                },
5607ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh
574aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                shim: {
5807ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "dygraph-sync": ["dygraph"],
5907ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "ILinePlot": {
604aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh
6107ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                        "deps": ["dygraph-sync", "dygraph" ],
624aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                        "exports":  "ILinePlot"
634aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                    }
644aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                }
654aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            });
6607ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                ilp_req(["require", "ILinePlot"], function() {
67211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh                ILinePlot.generate('""" + fig_name + """');
68211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh            });
69211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh            </script>
70211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh        """
71211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh
72c4abeeed1f450cbe153228de5a46dc0c1b488a8eKapileshwar Singh        cell = '<td style="border-style: hidden;"><div class="ilineplot" id="{0}" style="width: \
73211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh{1}px; height: {2}px;">{3}</div></td>'.format(fig_name,
748741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                                           width,
75211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh                                           self._attr["height"], div_js)
768741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
778741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(cell)
788741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
798741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _add_legend_cell(self, fig_name):
808741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add HTML table cell for the legend"""
818741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
828741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        width = int(self._attr["width"] / self._cols)
838741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        legend_div_name = fig_name + "_legend"
848741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        cell = '<td style="border-style: hidden;"><div style="text-align:right; \
858741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhwidth: {0}px; height: auto;"; id="{1}"></div></td>'.format(width,
868741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                                                           legend_div_name)
878741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
888741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(cell)
898741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
908741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _begin_row(self):
918741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add the opening tag for HTML row"""
928741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
938741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append("<tr>")
948741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
958741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _end_row(self):
968741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add the closing tag for the HTML row"""
978741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
988741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append("</tr>")
998741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1008741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _generate_fig_name(self):
1018741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Generate a unique figure name"""
1028741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1038741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_name = "fig_" + uuid.uuid4().hex
1048741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_map[self._fig_index] = fig_name
1058741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_index += 1
1068741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        return fig_name
1078741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1088741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _init_html(self):
1098741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Initialize HTML code for the plots"""
1108741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1118741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        width = self._attr["width"]
1128741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        table = '<table style="width: {0}px; border-style: hidden;">'.format(
1138741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            width)
1148741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(table)
1158741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1168741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        for _ in range(self._rows):
1178741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._begin_row()
1188741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1198741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            legend_figs = []
1208741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            for _ in range(self._cols):
1218741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                fig_name = self._generate_fig_name()
1228741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                legend_figs.append(fig_name)
1238741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                self._add_graph_cell(fig_name)
1248741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1258741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._end_row()
1268741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._begin_row()
1278741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1288741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            for l_fig in legend_figs:
1298741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                self._add_legend_cell(l_fig)
1308741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1318741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._end_row()
1328741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
133bd75d5c3abd977e41ce8c9f7e4740a552a239932Kapileshwar Singh    def __init__(self, cols, num_plots, **kwargs):
1348741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """
1358741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            Args:
1368741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                cols (int): Number of plots in a single line
1378741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                num_plots (int): Total Number of Plots
1388741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """
1398741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1408741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._cols = cols
141bd75d5c3abd977e41ce8c9f7e4740a552a239932Kapileshwar Singh        self._attr = kwargs
1428741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html = []
1438741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self.num_plots = num_plots
1448741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_map = {}
1458741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_index = 0
1468741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1478741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._single_plot = False
1488741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        if self.num_plots == 0:
1498741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            raise RuntimeError("No plots for the given constraints")
1508741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1518741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        if self.num_plots < self._cols:
1528741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._cols = self.num_plots
1538741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._rows = (self.num_plots / self._cols)
1548741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1558741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        if self.num_plots % self._cols != 0:
1568741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._rows += 1
1578741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1588741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._attr["width"] = AttrConf.HTML_WIDTH
1598741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._attr["height"] = AttrConf.HTML_HEIGHT
1608741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._init_html()
1618741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1628741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def add_plot(self, plot_num, data_frame, title=""):
1638741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add a plot to for a corresponding index"""
1648741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1658741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_name = self._fig_map[plot_num]
1668741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params = {}
1678741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["data"] = json.loads(data_frame.to_json())
1688741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["name"] = fig_name
1698741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["rangesel"] = False
1708741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["logscale"] = False
1718741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["title"] = title
1728741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["step_plot"] = self._attr["step_plot"]
173bd75d5c3abd977e41ce8c9f7e4740a552a239932Kapileshwar Singh        fig_params["fill_graph"] = self._attr["fill"]
1748741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
17567527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh        if "group" in self._attr:
17667527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            fig_params["syncGroup"] = self._attr["group"]
17767527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            if "sync_zoom" in self._attr:
17867527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh                fig_params["syncZoom"] = self._attr["sync_zoom"]
17967527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            else:
18067527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh                fig_params["syncZoom"] = AttrConf.DEFAULT_SYNC_ZOOM
18167527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh
1824462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh        if "ylim" in self._attr:
1834462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh            fig_params["valueRange"] = self._attr["ylim"]
1844462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh
185c4abeeed1f450cbe153228de5a46dc0c1b488a8eKapileshwar Singh        json_file = os.path.join(AttrConf.PLOTTER_STATIC_DATA_DIR, fig_name + ".json")
186c4abeeed1f450cbe153228de5a46dc0c1b488a8eKapileshwar Singh        fh = open(json_file, "w")
187c4abeeed1f450cbe153228de5a46dc0c1b488a8eKapileshwar Singh        json.dump(fig_params, fh)
188c4abeeed1f450cbe153228de5a46dc0c1b488a8eKapileshwar Singh        fh.close()
1898741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1908741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def finish(self):
1918741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Called when the Plotting is finished"""
1928741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1938741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        figs = []
1948741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1958741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        for fig_idx in self._fig_map.keys():
1968741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            figs.append(self._fig_map[fig_idx])
1978741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
198211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh        display(HTML(self.html()))
1998741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2008741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def html(self):
2018741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Return the raw HTML text"""
2028741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2038741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        return "\n".join(self._html)
204