1e81fdcb135d0325e3bc22fae0583555d20aae280Brendan Jackman#    Copyright 2015-2017 ARM Limited
28741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh#
3aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# Licensed under the Apache License, Version 2.0 (the "License");
4aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# you may not use this file except in compliance with the License.
5aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# You may obtain a copy of the License at
6aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino#
7aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino#     http://www.apache.org/licenses/LICENSE-2.0
8aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino#
9aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# Unless required by applicable law or agreed to in writing, software
10aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# distributed under the License is distributed on an "AS IS" BASIS,
11aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# See the License for the specific language governing permissions and
13aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# limitations under the License.
14aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino#
15aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino
1666451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh"""This is helper module for :mod:`trappy.plotter.ILinePlot`
1766451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singhfor adding HTML and javascript necessary for interactive
1866451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singhplotting. The Linear to 2-D co-ordination transformations
1966451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singhare done by using the functionality in
2066451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh:mod:`trappy.plotter.PlotLayout`
218741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh"""
228741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
23435457c8af9d69383ba45e0bd7da022d967a8deaJavi Merinofrom trappy.plotter import AttrConf
248741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport uuid
257f6a6d7c1b9b1418b03a8246947c19e254b519aeJavi Merinofrom collections import OrderedDict
268741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport json
278741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhimport os
2853de9b352977814c37608788cc1df83fc6485371Kapileshwar Singhfrom trappy.plotter import IPythonConf
29f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merinofrom trappy.plotter.ColorMap import to_dygraph_colors
308741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
31e1a703051d7cf345003f0ed4cfa7c25a76b0105cKapileshwar Singh
3253de9b352977814c37608788cc1df83fc6485371Kapileshwar Singhif not IPythonConf.check_ipython():
338741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    raise ImportError("No Ipython Environment found")
348741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
35fd5fe5f7938465e38af92f33287e7ad6549951eaKapileshwar Singhfrom IPython.display import display, HTML
36fd5fe5f7938465e38af92f33287e7ad6549951eaKapileshwar Singh
375c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singhdef df_to_dygraph(data_frame):
385c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    """Helper function to convert a :mod:`pandas.DataFrame` to
395c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    dygraph data
405c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh
415c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    :param data_frame: The DataFrame to be converted
425c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    :type data_frame: :mod:`pandas.DataFrame`
435c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    """
445c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh
455c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    values = data_frame.values.tolist()
465c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    data = [[x] for x in data_frame.index.tolist()]
475c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh
485c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    for idx, (_, val) in enumerate(zip(data, values)):
495c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        data[idx] += val
505c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh
515c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    return {
525c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        "data": data,
535c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        "labels": ["index"] + data_frame.columns.tolist(),
545c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    }
558741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
568741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singhclass ILinePlotGen(object):
5766451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    """
5866451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    :param num_plots: The total number of plots
5966451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    :type num_plots: int
6066451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh
6166451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    The linear co-ordinate system :math:`[0, N_{plots}]` is
6266451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    mapped to a 2-D coordinate system with :math:`N_{rows}`
6366451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    and :math:`N_{cols}` such that:
648741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
6566451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh    .. math::
6666451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh
6766451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        N_{rows} = \\frac{N_{cols}}{N_{plots}}
688741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    """
698741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
70f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino    def _add_graph_cell(self, fig_name, color_map):
718741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add a HTML table cell to hold the plot"""
728741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
73f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino        colors_opt_arg = ", " + to_dygraph_colors(color_map) if color_map else ""
74f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino
757c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino        graph_js = ''
76215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino        lib_urls =  [IPythonConf.DYGRAPH_COMBINED_URL, IPythonConf.DYGRAPH_SYNC_URL,
77215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino                     IPythonConf.UNDERSCORE_URL]
78215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino        for url in lib_urls:
797c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino            graph_js += '<!-- TRAPPY_PUBLISH_SOURCE_LIB = "{}" -->\n'.format(url)
80215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino
817c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino        graph_js += """
824aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            <script>
83215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino            /* TRAPPY_PUBLISH_IMPORT = "plotter/js/ILinePlot.js" */
84215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino            /* TRAPPY_PUBLISH_REMOVE_START */
854aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            var ilp_req = require.config( {
864aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh
8707ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                paths: {
8853de9b352977814c37608788cc1df83fc6485371Kapileshwar Singh                    "dygraph-sync": '""" + IPythonConf.add_web_base("plotter_scripts/ILinePlot/synchronizer") + """',
8953de9b352977814c37608788cc1df83fc6485371Kapileshwar Singh                    "dygraph": '""" + IPythonConf.add_web_base("plotter_scripts/ILinePlot/dygraph-combined") + """',
9053de9b352977814c37608788cc1df83fc6485371Kapileshwar Singh                    "ILinePlot": '""" + IPythonConf.add_web_base("plotter_scripts/ILinePlot/ILinePlot") + """',
91324d33688bde12601302cbad42e3487c37364817Kapileshwar Singh                    "underscore": '""" + IPythonConf.add_web_base("plotter_scripts/ILinePlot/underscore-min") + """',
9207ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                },
9307ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh
944aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                shim: {
9507ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "dygraph-sync": ["dygraph"],
9607ac8dd8c8093d432390078dab4dce61906e421dKapileshwar Singh                    "ILinePlot": {
974aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh
98324d33688bde12601302cbad42e3487c37364817Kapileshwar Singh                        "deps": ["dygraph-sync", "dygraph", "underscore"],
994aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                        "exports":  "ILinePlot"
1004aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                    }
1014aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh                }
1024aa15c0de680a339ba3e7acf300aaa089f3eb4caKapileshwar Singh            });
103215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino                /* TRAPPY_PUBLISH_REMOVE_STOP */
104215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino                ilp_req(["require", "ILinePlot"], function() { /* TRAPPY_PUBLISH_REMOVE_LINE */
105f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino                ILinePlot.generate(""" + fig_name + "_data" + colors_opt_arg + """);
106215d9fffd7b77a10c8106c539bb1235847cafdf6Javi Merino            }); /* TRAPPY_PUBLISH_REMOVE_LINE */
107211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh            </script>
108211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh        """
109211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh
1107c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino        cell = '<td style="border-style: hidden;"><div class="ilineplot" id="{}"></div></td>'.format(fig_name)
1118741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1128741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(cell)
1137c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino        self._js.append(graph_js)
1148741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1158741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _add_legend_cell(self, fig_name):
1168741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add HTML table cell for the legend"""
1178741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1188741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        legend_div_name = fig_name + "_legend"
1199b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio        cell = '<td style="border-style: hidden;"><div style="text-align:center" id="{}"></div></td>'.format(legend_div_name)
1208741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1218741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(cell)
1228741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1238741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _begin_row(self):
1248741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add the opening tag for HTML row"""
1258741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1268741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append("<tr>")
1278741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1288741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _end_row(self):
1298741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Add the closing tag for the HTML row"""
1308741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1318741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append("</tr>")
1328741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1337c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh    def _end_table(self):
1347c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh        """Add the closing tag for the HTML table"""
1357c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh
1367c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh        self._html.append("</table>")
1377c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh
1388741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def _generate_fig_name(self):
1398741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Generate a unique figure name"""
1408741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1418741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_name = "fig_" + uuid.uuid4().hex
1428741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_map[self._fig_index] = fig_name
1438741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_index += 1
1448741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        return fig_name
1458741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
146f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino    def _init_html(self, color_map):
1478741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Initialize HTML code for the plots"""
1488741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
149b9e8f11cfd24c71e4634a3b23ba3704841e636d9Kapileshwar Singh        table = '<table style="border-style: hidden;">'
1508741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html.append(table)
151b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio        if self._attr["title"]:
152b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio            cell = '<caption style="text-align:center; font: 24px sans-serif bold; color: black">{}</caption>'.format(self._attr["title"])
153b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio            self._html.append(cell)
1548741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1558741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        for _ in range(self._rows):
1568741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._begin_row()
1578741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            legend_figs = []
1588377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio            for _ in range(self._attr["per_line"]):
1598741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                fig_name = self._generate_fig_name()
1608741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                legend_figs.append(fig_name)
161f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino                self._add_graph_cell(fig_name, color_map)
1628741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1638741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._end_row()
1648741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._begin_row()
1658741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1668741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            for l_fig in legend_figs:
1678741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh                self._add_legend_cell(l_fig)
1688741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1698741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._end_row()
1708741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1717c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh        self._end_table()
1727c32bc41bcd9e96c06bb70339334489cb93c663cKapileshwar Singh
1738377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio    def __init__(self, num_plots, **kwargs):
1748741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
175bd75d5c3abd977e41ce8c9f7e4740a552a239932Kapileshwar Singh        self._attr = kwargs
1768741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._html = []
1777c1bbd549ab76cff58409d91bcb4749cc06d4d15Javi Merino        self._js = []
178535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        self._js_plot_data = []
1798741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self.num_plots = num_plots
1808741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_map = {}
1818741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._fig_index = 0
1828741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1838741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._single_plot = False
1848741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        if self.num_plots == 0:
1858741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            raise RuntimeError("No plots for the given constraints")
1868741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1878377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio        if self.num_plots < self._attr["per_line"]:
1888377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio            self._attr["per_line"] = self.num_plots
1898377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio        self._rows = (self.num_plots / self._attr["per_line"])
1908741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1918377bdc6856e004ecc6554008a9e0f556a05b579Michele Di Giorgio        if self.num_plots % self._attr["per_line"] != 0:
1928741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh            self._rows += 1
1938741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1948741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        self._attr["height"] = AttrConf.HTML_HEIGHT
195f4261b4fbb05ab7e27d89fa2f607773cdf4355b2Javi Merino        self._init_html(kwargs.pop("colors", None))
1968741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
1977ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh    def _check_add_scatter(self, fig_params):
1987ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        """Check if a scatter plot is needed
1997ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        and augment the fig_params accordingly"""
2007ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh
2017ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        if self._attr["scatter"]:
2027ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh            fig_params["drawPoints"] = True
2037ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh            fig_params["strokeWidth"] = 0.0
2047ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        else:
2057ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh            fig_params["drawPoints"] = False
2067ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh            fig_params["strokeWidth"] = AttrConf.LINE_WIDTH
2077ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh
2087ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        fig_params["pointSize"] = self._attr["point_size"]
2097ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh
2105c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh    def add_plot(self, plot_num, data_frame, title="", test=False):
21166451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        """Add a plot for the corresponding index
21266451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh
21366451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        :param plot_num: The linear index of the plot
21466451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        :type plot_num: int
21566451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh
2165c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        :param data_frame: The data for the plot
2175c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        :type data_frame: :mod:`pandas.DataFrame`
21866451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh
21966451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        :param title: The title for the plot
22066451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        :type title: str
22166451b48f106e10658bdce2bd49c852f844db6faKapileshwar Singh        """
2228741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2235c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        datapoints = sum(len(v) for _, v in data_frame.iteritems())
224d2d686c76246c2187cea62236685fbe4730e7584Javi Merino        if datapoints > self._attr["max_datapoints"]:
225d2d686c76246c2187cea62236685fbe4730e7584Javi Merino            msg = "This plot is too big and will probably make your browser unresponsive.  If you are happy to wait, pass max_datapoints={} to view()".\
226d2d686c76246c2187cea62236685fbe4730e7584Javi Merino                  format(datapoints + 1)
227d2d686c76246c2187cea62236685fbe4730e7584Javi Merino            raise ValueError(msg)
228d2d686c76246c2187cea62236685fbe4730e7584Javi Merino
2298741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_name = self._fig_map[plot_num]
2308741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params = {}
2315c53c1f76cb60be8cf1d6c43b54a3f04eae10d6cKapileshwar Singh        fig_params["data"] = df_to_dygraph(data_frame)
2328741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["name"] = fig_name
2338741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["rangesel"] = False
2348741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["logscale"] = False
2358741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["title"] = title
2368741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        fig_params["step_plot"] = self._attr["step_plot"]
237bd75d5c3abd977e41ce8c9f7e4740a552a239932Kapileshwar Singh        fig_params["fill_graph"] = self._attr["fill"]
238e2ede1f52665ff9ca6ed5177528b2f150ef16a35Brendan Jackman        if "fill_alpha" in self._attr:
239e2ede1f52665ff9ca6ed5177528b2f150ef16a35Brendan Jackman            fig_params["fill_alpha"] = self._attr["fill_alpha"]
240e2ede1f52665ff9ca6ed5177528b2f150ef16a35Brendan Jackman            fig_params["fill_graph"] = True
241b9e8f11cfd24c71e4634a3b23ba3704841e636d9Kapileshwar Singh        fig_params["per_line"] = self._attr["per_line"]
242b9e8f11cfd24c71e4634a3b23ba3704841e636d9Kapileshwar Singh        fig_params["height"] = self._attr["height"]
2438741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2447ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh        self._check_add_scatter(fig_params)
2457ab82627f892036d7eeb04af3d282a329f8d04cdKapileshwar Singh
24667527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh        if "group" in self._attr:
24767527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            fig_params["syncGroup"] = self._attr["group"]
24867527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            if "sync_zoom" in self._attr:
24967527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh                fig_params["syncZoom"] = self._attr["sync_zoom"]
25067527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh            else:
25167527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh                fig_params["syncZoom"] = AttrConf.DEFAULT_SYNC_ZOOM
25267527ddea39e858c957997356a16bd8e3819f359Kapileshwar Singh
2534462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh        if "ylim" in self._attr:
2544462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh            fig_params["valueRange"] = self._attr["ylim"]
2554462468766dabe30a7c58c655807c4c2ede0fdccKapileshwar Singh
256c972b86eac3c41c14b4063f0a4c79b371ebe739cKapileshwar Singh        if "xlim" in self._attr:
257c972b86eac3c41c14b4063f0a4c79b371ebe739cKapileshwar Singh            fig_params["dateWindow"] = self._attr["xlim"]
258c972b86eac3c41c14b4063f0a4c79b371ebe739cKapileshwar Singh
259535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        fig_data = "var {}_data = {};".format(fig_name, json.dumps(fig_params))
260535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino
261535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        self._js_plot_data.append("<script>")
262535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        self._js_plot_data.append(fig_data)
263535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        self._js_plot_data.append("</script>")
2648741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2658741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def finish(self):
2668741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Called when the Plotting is finished"""
2678741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
268211860fe53efaa299db6ff6c9b28816bcb5902d4Kapileshwar Singh        display(HTML(self.html()))
2698741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
2708741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh    def html(self):
2718741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh        """Return the raw HTML text"""
2728741ef170bc7fcc772837fd2db3df2f8d74b6c10Kapileshwar Singh
273535b3bd3ff699415798dbf1e9cf9e3bc3f56c3b2Javi Merino        return "\n".join(self._html + self._js_plot_data + self._js)
274