dc5553

Create reports with Google Charts

Jan 9th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.58 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*
  3.  
  4. from time import gmtime, strftime
  5. import webbrowser
  6.  
  7. class ReportMaker:
  8.    
  9.     """This class creates tables and Google charts from data passed as a python dictionary. Formats vary by report/chart type"""
  10.  
  11.     def createPieChart(self,data_dict):
  12.        
  13.         """\nCreates a Google Charts Pie Chart with a properly formatted dictionary (see below):
  14.        {
  15.        "Creating a nice Chart":
  16.            [
  17.            ["Name","Visits"],
  18.            ["Joe",50],
  19.            ["Bob",28],
  20.            ["Steve", 82]
  21.            ],
  22.        "Creating another nice Chart":
  23.            [
  24.            ["Tool","Inventory"],
  25.            ["Hammer",15],
  26.            ["Screwdriver",7],
  27.            ["Saw", 5]
  28.            ]}
  29.        """
  30.        
  31.         dtg = strftime("%d_%b_%Y_%H%M", gmtime())
  32.         myfile = open(dtg+".html","w")
  33.        
  34.         myhtml="""<!DOCTYPE html><head>
  35.            <!-- Latest compiled and minified CSS -->
  36.            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  37.  
  38.            <!-- Latest compiled and minified JavaScript -->
  39.            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  40.            <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>"""
  41.            
  42.         myhtml1 ="""<script type="text/javascript">
  43.            google.charts.load('current', {'packages':['corechart']});
  44.            google.charts.setOnLoadCallback(drawChart);
  45.            
  46.            function drawChart() {
  47.  
  48.                var data = google.visualization.arrayToDataTable("""
  49.                
  50.         myhtml2 = """);
  51.  
  52.                var options = {{
  53.                title: '{0}',
  54.                is3D: true,
  55.                }};
  56.  
  57.                var chart = new google.visualization.PieChart(document.getElementById('{0}'));
  58.  
  59.                chart.draw(data, options);
  60.                }}
  61.                </script>\n\n
  62.                <!- END OF SCRIPT->\n\n"""
  63.  
  64.         myhtml2_5 = """</head>
  65.                    <body><div>""" #start the main div
  66.            
  67.         myhtml3="""<div id="{0}" style="min-height:600px; width:50%; margin:0px; padding:0px; float: {1};"></div>\n\n
  68.                <!- END OF DIV->\n\n""" #start each sub div for individual charts
  69.                
  70.         myfile.write(myhtml)
  71.        
  72.         for chart in data_dict.keys():
  73.             myfile.write(myhtml1 + str(data_dict[chart]).replace('[[[','[[').replace(']]]',']]') + myhtml2.format(chart))
  74.        
  75.         myfile.write(myhtml2_5)
  76.        
  77.         mycounter = 2
  78.         for chart in data_dict.keys():
  79.             if mycounter % 2 == 0:
  80.                 myfile.write(myhtml3.format(chart,"left"))
  81.                 mycounter+=1
  82.             else:
  83.                 myfile.write(myhtml3.format(chart,"right"))
  84.                 myfile.write("<br />")
  85.                 mycounter+=1
  86.        
  87.         myfile.write('</div></body></html>')
  88.        
  89.         print "[!] {0}.html was created".format(dtg)
  90.         webbrowser.open("{0}.html".format(dtg))
  91.                
  92.     def createTable(self, table_dict):
  93.  
  94.         """Creates a number of tables from a properly formatted dictionary containing table values"""
  95.        
  96.         dtg = strftime("%d_%b_%Y_%H%M", gmtime())
  97.         myfile = open(dtg+".html","w")
  98.  
  99.         myhtml_header="""<!DOCTYPE html><head>
  100.            <style>
  101.            h1 {
  102.                display: block;
  103.                font-size: 2em;
  104.                margin-top: 0.67em;
  105.                margin-bottom: 0.67em;
  106.                margin-left: 0;
  107.                margin-right: 0;
  108.                font-weight: bold;
  109.            }
  110.            
  111.            table {
  112.            font-family: arial, sans-serif;
  113.            border-collapse: collapse;
  114.            width: 100%;
  115.            }
  116.  
  117.            td, th {
  118.            border: 1px solid #dddddd;
  119.            text-align: left;
  120.            padding: 8px;
  121.            }
  122.  
  123.            tr:nth-child(even) {
  124.            background-color: #dddddd;
  125.            }
  126.            </style>
  127.        <!-- Latest compiled and minified CSS -->
  128.        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  129.  
  130.        <!-- Latest compiled and minified JavaScript -->
  131.        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  132.        </head><body>
  133.            """
  134.            
  135.         myfile.write(myhtml_header)
  136.         for tb in table_dict.keys():    
  137.             myfile.write("<h1>{0}</h1><table><tr>".format(tb))
  138.        
  139.             for column_header in table_dict[tb][0]:
  140.                 myfile.write("<th>{0}</th>".format(column_header))
  141.        
  142.             myfile.write("</tr>")
  143.        
  144.             for row in table_dict[tb][1]:
  145.                 myfile.write("<tr>")
  146.                 for rowdata in row:
  147.                     try:
  148.                         myfile.write("<td>{0}</td>".format(str(rowdata)))
  149.                     except UnicodeEncodeError:
  150.                         myfile.write("<td>{0}</td>".format("[!] Unicode Error"))
  151.                 myfile.write("</tr>")
  152.             myfile.write("</table><br />")
  153.        
  154.         myfile.write("</body></html>")
  155.         myfile.close()  
  156.        
  157.         print "[!] {0}.html was created".format(dtg)
  158.         webbrowser.open("{0}.html".format(dtg))
  159.      
  160.     def createTimeChart(self, data_dict):
  161.        
  162.         """\nCreates a Google Charts Line Chart with a properly formatted dictionary (see below):
  163.            {
  164.            "Creating another nice Time Chart":
  165.                [
  166.                    [("Day of the Week","string"),("Customers","number"),("Deliveries","number")],
  167.                    ["Monday",25,6],
  168.                    ["Tuesday",38,12],
  169.                    ["Wednesday",12,8],
  170.                    ["Thursday",2,14],
  171.                    ["Friday",5,25]
  172.                ],
  173.            "Creating a nice Time Chart":
  174.                [
  175.                    [("Day of the Week","string"),("Customers","number"),("Deliveries","number")],
  176.                    ["Monday",66,9],
  177.                    ["Tuesday",24,12],
  178.                    ["Wednesday",16,8],
  179.                    ["Thursday",2,18],
  180.                    ["Friday",46,21]                
  181.                ]
  182.            }
  183.        """
  184.        
  185.         #this data in organized wrong. fix the nested lists to remove one level like the second example above
  186.    
  187.         dtg = strftime("%d_%b_%Y_%H%M", gmtime())
  188.         myfile = open(dtg+".html","w")
  189.        
  190.         myhtml = """<!DOCTYPE html><head>
  191.        <!-- Latest compiled and minified CSS -->
  192.        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  193.  
  194.            <!-- Latest compiled and minified JavaScript -->
  195.            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  196.            <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>"""
  197.            
  198.         myhtml1 = """<script type="text/javascript">
  199.                        google.charts.load('current', {
  200.                        packages: ['corechart', 'line']
  201.                        });
  202.                        google.charts.setOnLoadCallback(drawBackgroundColor);
  203.  
  204.                        function drawBackgroundColor() {
  205.                        var data = new google.visualization.DataTable();"""
  206.                
  207.         myhtml1_1 = """var options = {{
  208.                            hAxis: {{
  209.                            title: 'Time',
  210.                            direction: -1,
  211.                            slantedText: true,
  212.                            slantedTextAngle: 75 // here you can even use 180,
  213.                            }},
  214.                            vAxis: {{
  215.                            title: 'Units',
  216.                            scaleType: 'log'
  217.                            }},
  218.                              backgroundColor: '#FFFFFF',
  219.                              height: 700,
  220.                              interpolateNulls: true
  221.                            }};
  222.  
  223.                                var chart = new google.visualization.LineChart(document.getElementById('{0}'));
  224.                                chart.draw(data, options);
  225.                                }}
  226.  
  227.                            </script>\n"""
  228.                                
  229.        
  230.         # start writing the html file
  231.         myfile.write(myhtml)
  232.        
  233.         # iterate over the dictionary for each chart we will create
  234.         for chartName in data_dict.keys():
  235.             myfile.write(myhtml1) # create a JavaScript function for each chart
  236.             for value in range(len(data_dict[chartName][0])): # create the columns one per a line this includes y and x * n values (n=number of lines you want to see)
  237.                 myfile.write("\n\tdata.addColumn('{0}', '{1}');".format(data_dict[chartName][0][value][1],data_dict[chartName][0][value][0]))
  238.             # add the data list, the way python "prints" it works perfect for this JS library
  239.             myfile.write("\ndata.addRows({0});".format(str(data_dict[chartName][1:]).replace("[[[","[[").replace("]]]","]]")))
  240.             myfile.write(myhtml1_1.format(chartName))
  241.            
  242.         myfile.write('</head><body>')# start the body element
  243.        
  244.         # create the div elements that display the charts with header
  245.         for chartName in data_dict.keys():
  246.             myfile.write("\n<div><h2>{0}</h2>\n<!--chart div element here-->\n".format(chartName))    
  247.             myfile.write("<div id='{0}'></div>\n<!--end chart div element here-->\n</div>".format(chartName))
  248.         myfile.write("</body></html>")
  249.         myfile.close()  
  250.        
  251.         print "[!] {0}.html was created".format(dtg)
  252.         webbrowser.open("{0}.html".format(dtg))
  253.          
  254.        
  255. if __name__ == '__main__':
  256.   main()
Add Comment
Please, Sign In to add comment