diff --git a/root/opt/mailstats/css/mailstats.css b/root/opt/mailstats/css/mailstats.css index c01c85f..7a82179 100644 --- a/root/opt/mailstats/css/mailstats.css +++ b/root/opt/mailstats/css/mailstats.css @@ -8,7 +8,20 @@ tr.row-total, tr.row-percent , td.col-15, td.col-16 { font-weight: bold; } +table { + box-shadow: 0 6px 10px rgba(0, 0, 0, 0.1); + border-collapse: collapse; +} +.headerpanel { + box-shadow: 0 6px 10px rgba(0, 0, 0, 0.1); + border:1px solid; + width:98%; +} + +.innerheaderpanel { + padding:10px; +} tr,td,th { border:1px solid; @@ -31,7 +44,12 @@ tfoot tr { background-color:darkgrey; } -tbody tr:nth-child(odd) {background-color: #dfdfdf} +.stripes tbody tr:nth-child(odd) {background-color: #dfdfdf} + +.no-stripes tbody tr:nth-child(odd) { + background-color: transparent; /* or whatever background color you want */ +} + div.linksattop { display: flex; @@ -50,6 +68,38 @@ div.divshowindex { a.nextlink { text-align: right; } +/* Basic styling for the tab container */ +.tab-container { + display: flex; + border-bottom: 1px solid #ccc; + margin-bottom: 10px; +} + +/* Styling for the tabs */ +.tab { + padding: 10px 20px; + cursor: pointer; + border: 1px solid #ccc; + border-bottom: none; + background-color: #f1f1f1; +} + +/* Styling for the active tab */ +.tab-active { + background-color: #ffffff; + border-top: 2px solid #007bff; + font-weight: bold; +} + +/* Hide all content sections by default */ +.tab-content { + display: none; +} + +/* Display the active content section */ +.tab-content-active { + display: block; +} .cssclass1 {background-color:#ffff99;} .cssclass2 {background-color:lightcoral;} @@ -64,4 +114,36 @@ a.nextlink { .cssclass11 {background-color:lightslategray;} .cssclass12 {background-color:lightsteelblue;} -p.cssvalid,p.htmlvalid {float:left;margin-right:20px) +p.cssvalid,p.htmlvalid {float:left;margin-right:20px} + +.maintable {} + +.subtables { + display: flex; + flex-wrap: nowrap; /* Use wrap if you want the tables to wrap to the next line when the screen is too narrow */ + gap: 10px; /* Optional: Adds space between the tables */ +} +.subtables > div { + flex: 1; /* Equal width tables, remove or adjust based on your preference */ + margin-left:10px; +} + +.footer {} + +.iframe-container { + width: 100%; + height: 500px; /* Adjust as needed */ + border: none; +} + +.parent-container { + width: 100%; + display: flex; + justify-content: center; + align-items: center; +} + + + + + diff --git a/root/usr/bin/mailstats.py b/root/usr/bin/mailstats.py index cce7ad9..b039c48 100644 --- a/root/usr/bin/mailstats.py +++ b/root/usr/bin/mailstats.py @@ -334,8 +334,8 @@ def create_heatmap(data2d, xLabels, yLabels, save_path='heatmap.html'): graph_html = fig.to_html(full_html=False) return graph_html - -def create_line_chart(data2d, xLabels,yLabels, save_path='line_chart.html'): + +def create_line_chart(data2d, xLabels, yLabels, save_path='line_chart.html'): fig = go.Figure() excluded_columns = ["Count", "PERCENT", "TOTALS"] @@ -350,12 +350,16 @@ def create_line_chart(data2d, xLabels,yLabels, save_path='line_chart.html'): if len(yLabels) != sanitized_data.shape[0]: raise ValueError("The length of yLabels must match the number of rows in the data.") + # Remove rows with all zero elements and the corresponding categories + nonzero_rows_indices = np.where(~np.all(sanitized_data == 0, axis=0))[0] # find rows with non-zero elements + sanitized_data = sanitized_data[:, nonzero_rows_indices] + filtered_xLabels = [filtered_xLabels[i] for i in nonzero_rows_indices] # update filtered_xLabels for i, category in enumerate(filtered_xLabels): fig.add_trace(go.Scatter( mode='lines+markers', name=category, - x=[f'Hour {j}' for j in range(sanitized_data.shape[0])], + x= [f'{j:02d}:00' for j in range(sanitized_data.shape[0])], y=sanitized_data[:, i] )) @@ -365,12 +369,14 @@ def create_line_chart(data2d, xLabels,yLabels, save_path='line_chart.html'): yaxis=dict(title='Count'), legend_title_text='Category' ) - + fig.write_html(save_path) # Write it to a var and return the string graph_html = fig.to_html(full_html=False) return graph_html + + def save_summaries_to_db(date_str, hour, parsed_data):