import io
import os
import urllib.request

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
%matplotlib inline
import numpy as np
import pandas as pd

from supersight import Dashboard, Plots_gatherer

"""
Explanation: 
End of explanation
"""


plots = Plots_gatherer()

"""
Explanation: 1. Create a collection of plots
The main goal of supersight is to gather your plots and organize these plots within a mini web site.
Actually, you can embed any svg plots but this tool was designed to work with MatPlotlib.  
We start by creating a plots gatherer object.
It will contain our plots for easy retrieval:
End of explanation
"""


graph = plt.figure()
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, 'o', color='black');

buf = io.BytesIO()
plt.savefig(buf, format='svg')
plots.add_plot("first graph", buf)

"""
Explanation: Let's generate a simple plot :
End of explanation
"""


graph = plt.figure()
plt.plot(x, y, '-ok')

buf = io.BytesIO()
plt.savefig(buf, format='svg')
plots.add_plot("second graph", buf)

"""
Explanation: Once your are happy with it, supersight requires you to save your plot in  BytesIO objects.
SVG format is advised since it is lightweight and vector-based.
The three last lines are required to save your plot in a way supersight can handle.
We will make a new plot :
End of explanation
"""


graph = plt.figure()
plt.scatter(np.random.randn(100), np.random.randn(100));

buf = io.BytesIO()
plt.savefig(buf, format='svg')
plots.add_plot("third graph", buf)

"""
Explanation: And a third graph for the example :
End of explanation
"""


logo = open("logo_small.svg", "rb")
logo_buf = io.BytesIO(logo.read())
plots.add_plot("logo", logo_buf)
logo.close()

"""
Explanation: Below is a hack to load external svg in our mini site :
End of explanation
"""


data=pd.read_csv("https://s3.eu-central-1.amazonaws.com/camo-bucket/misc_to_link/data_sample.csv")

df1 = data.head() # a classic df

# a simple pivot table
df2 = pd.pivot_table(data, index = 'Gender',
                     columns = ['Smoking'],
                     aggfunc = np.average)

"""
Explanation: Let's add some pandas dataframes as SuperSight can also display data tables within pages :
End of explanation
"""


ds = Dashboard()

"""
Explanation: 2. Create a dashboard
Once your plots are saved in BytesIO objects you can start making a dashboard by initiating a Dashboard object :
End of explanation
"""


ds.add_section("Section 1")
# We just created a section named Section 1. Pick a custom name that describe an underlying idea of your plots.
ds.sections["Section 1"].add_page("Page 1")


ds.add_section("Section 2")
# We just created a section named Section 2. We said we wanted two pages in this section :
ds.sections["Section 2"].add_page("Interesting Page")
ds.sections["Section 2"].add_page("Great Page") # name it as you want !

"""
Explanation: By default, the mini site comes with a home page. We will add two sections. The first section will contain only one page and the second will contain two pages.
As a convention a single-page section is composed of a page named "Page 1".
End of explanation
"""


ds.sections["Home"].pages["Home"].layout = [(12,)]

ds.sections["Home"].pages["Home"].add_element(name = "logo", plot_object = plots.get_plot("logo"))


"""
Explanation: Each page is organised following a classic Bootstrap grid. Users can display elements on this grid. The default grid is [(6, 6), (6, 6), (6, 6)]. It means the page displays three rows with two elements on each row.
Of course, this layout can be overridden. For the Home page we will display the supersight logo.
According to the Bootstrap grid system the layout for a single row and a single element is [(12,)].
End of explanation
"""


ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 1", plot_object = plots.get_plot("first graph"))
ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 2", plot_object = plots.get_plot("first graph"))

ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 3", plot_object = plots.get_plot("second graph"))
ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 4", plot_object = plots.get_plot("second graph"))

ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 5", plot_object = plots.get_plot("third graph"))
ds.sections["Section 1"].pages["Page 1"].add_element(name = "plot 6", plot_object = plots.get_plot("third graph"))
# add comments :
ds.sections["Section 1"].pages["Page 1"].elements["plot 3"].add_comment_below("This plot will convince you !")

"""
Explanation: In section 1, the default grid can stay (hence six plots). Users can populate the grid with their plots. This process populate the grid from left to right and from top to bottom :
End of explanation
"""


ds.sections["Section 1"].pages["Page 1"].elements["plot 6"].add_comment_below("""This one is not bad either ! <br>
You can also use MathJax : $x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$""")

"""
Explanation: Users can also use MathJax to dsiplay equations in comments :
End of explanation
"""


ds.sections["Section 2"].pages["Interesting Page"].layout = [(8, 4), (12,), (4, 4, 4)]

ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 1", plot_object = plots.get_plot("third graph"), heading = None)
ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 2", plot_object = plots.get_plot("first graph"), heading = None)

ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 3", plot_object = plots.get_plot("second graph"), heading = "Interesting Heading")

ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 4", plot_object = plots.get_plot("third graph"), heading = None)
ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 5", plot_object = plots.get_plot("third graph"), heading = None)
ds.sections["Section 2"].pages["Interesting Page"].add_element(name = "plot 6", plot_object = plots.get_plot("third graph"), heading = None)

dummy ="""One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a 
horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, 
slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready 
to slide off any moment. His many legs, pitifully thin compared with the size of the rest of him, waved about 
helplessly as he looked. "What's happened to me?" he thought. It wasn't a dream. His room, a proper human room 
although a little too small, lay peacefully between its four familiar walls. A collection of textile samples 
lay spread out on the table - Samsa was a travelling salesman - 
and above it there hung a picture that he had recently cut out of an illustrated magazine and housed"""

ds.sections["Section 2"].pages["Interesting Page"].elements["plot 1"].add_comment_above(dummy)
ds.sections["Section 2"].pages["Interesting Page"].elements["plot 2"].add_comment_below(dummy[:277])

"""
Explanation: Now we can try to vary the layout. For instance on the first row we will display a plot two third the width.
On the second row we can display a unique plot with a heading.
And then three small plots on the last row.
End of explanation
"""


ds.sections["Section 2"].pages["Great Page"].layout = [(8, 4), (6,6), (12,), (12,), (12,)]
ds.sections["Section 2"].pages["Great Page"].add_element(name = "info", heading = "Contact Information", 
                                                         comment_below = "camille.moatti@gmail.com <br> +33 (0) X XX XX XX XX", 
                                                         comment_above = "<br>Camille Moatti")
ds.sections["Section 2"].pages["Great Page"].add_element(name = "text", plot_object = plots.get_plot("logo"))

ds.sections["Section 2"].pages["Great Page"].add_element(name = "small table")
ds.sections["Section 2"].pages["Great Page"].elements["small table"].add_table(df1)

ds.sections["Section 2"].pages["Great Page"].add_element(name = "small table 2")
ds.sections["Section 2"].pages["Great Page"].elements["small table 2"].add_table(df1)

ds.sections["Section 2"].pages["Great Page"].add_element(name = "small table 3")
ds.sections["Section 2"].pages["Great Page"].elements["small table 3"].add_table(df1)

ds.sections["Section 2"].pages["Great Page"].add_element(name = "pivot table")
ds.sections["Section 2"].pages["Great Page"].elements["pivot table"].add_table(df2)

df2

df3 = pd.DataFrame(np.random.randn(50, 4), columns=list('ABCD'))
df3

d = dict(selector="th",
    props=[('text-align', 'center')])

newdf = df3.style.bar(subset=['A', 'B'], align='mid', color=['#d65f5f', '#5fba7d']).format("{:.2}%").set_properties(**{'text-align': 'center'}).set_table_styles([d])
newdf

ds.sections["Section 2"].pages["Great Page"].add_element(name = "styled table")
ds.sections["Section 2"].pages["Great Page"].elements["styled table"].add_table(newdf, isStyled = True)

ds.render()

"""
Explanation: To finish, we can display text and tables on the "great page" !
End of explanation
"""


