[hamster-applet] dynamic totals.
- From: Toms Baugis <tbaugis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [hamster-applet] dynamic totals.
- Date: Sun, 7 Nov 2010 22:53:23 +0000 (UTC)
commit 60e1fe49831de3395f8dff138c9a6c6b3f572f86
Author: Toms Bauģis <toms baugis gmail com>
Date: Sun Nov 7 22:27:58 2010 +0000
dynamic totals.
data/report_template.html | 298 ++++++++++++++++++++++++++-------------------
src/hamster/reports.py | 116 ++++--------------
2 files changed, 196 insertions(+), 218 deletions(-)
---
diff --git a/data/report_template.html b/data/report_template.html
index e5700cd..5e09779 100644
--- a/data/report_template.html
+++ b/data/report_template.html
@@ -14,8 +14,19 @@
body {
font-family: "Droid Sans", "Liberation Sans", "Helvetica", "Arial", sans-serif;
font-size: 12px;
- padding: 12px;
+ padding: 0;
+ margin: 0;
color: #303030;
+ background: #eee;
+ }
+
+ #content {
+ width: 700px;
+ padding: 24px 12px;
+ margin:0px auto;
+ background: #f6f6f6;
+ border-right: 2px solid #bbb;
+ border-left: 1px solid #bbb;
}
th, td {
@@ -59,16 +70,21 @@
height: 100%;
}
+ #date_chart {
+ width: 100%;
+ overflow: auto;
+ overflow-y: hidden;
+ height: 80px;
+ }
+
#date_chart table {
width: 100%;
+ height: 90%;
border-collapse: collapse;
margin-bottom: 4px;
}
- #date_chart table tr {
- vertical-align: bottom;
- }
-
+ #date_chart table tr {vertical-align: bottom;}
#date_chart table td {
padding: 0;
padding-right: 1px;
@@ -78,8 +94,8 @@
width: 100%;
background-color: #ccc;
border-radius: 0;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
}
.duration {
@@ -94,6 +110,10 @@
background: #eee;
}
+
+ #date_facts tr:td {
+ padding-left: 24px;
+ }
</style>
<style type="text/css" media="print">
@@ -213,7 +233,7 @@
if (bar_height < 1)
bar.height("1px");
else
- bar.height(bar_height)
+ bar.height(bar_height +"%")
col.append(bar);
row.append(col);
@@ -245,136 +265,166 @@
})
+
+ populateFactTable();
+
+
+ $(".by_day_controls input").click(function(){
+ populateFactTable();
+ });
});
+
+
+ function populateFactTable() {
+ // fill fact rows
+ var table = $("#date_facts");
+ table.empty();
+
+ var dateFacts = $date_facts;
+
+ // determine if we will be doing any internal counting
+ var keys = [];
+ if ($("#show_activities").attr("checked"))
+ keys.push("activity");
+
+ if ($("#show_categories").attr("checked"))
+ keys.push("category");
+
+ if ($("#show_tags").attr("checked"))
+ keys.push("tags");
+
+
+
+ for (var i in dateFacts) {
+ var dateString = dateFacts[i][0];
+ var dateTotal = 0;
+
+ var factTotals = {}
+ for (var j in dateFacts[i][1]) {
+ var fact = dateFacts[i][1][j];
+ fact.tags = fact.tags.join(", ");
+
+ if (keys.length > 0) {
+ var key = [];
+ for (var k in keys) {
+ key.push(fact[keys[k]])
+ }
+
+ key = key.join(" - ");
+ factTotals[key] = factTotals[key] || 0;
+ factTotals[key] += fact.delta;
+ }
+
+
+ dateTotal += fact.delta;
+ }
+
+ dateTotal = Math.round(dateTotal / 60 / 60 * 10) / 10;
+ table.append("<tr><th>" + dateString + "</th><th>" + dateTotal +"</th></tr>");
+
+ for (var key in factTotals) {
+ keyTotal = Math.round(factTotals[key] / 60 / 60 * 10) / 10;
+ table.append("<tr><td>" + key + "</td><td>" + keyTotal +"</td></tr>");
+ }
+
+
+ }
+ }
</script>
</head>
<body>
-<h1>$title <span class="duration">(<totals_activity>$total_duration</totals_activity>)</span></h1>
+<div id="content">
+ <h1>$title <span class="duration">($grand_total)</span></h1>
-<div id="date_chart"></div>
+ <div id="date_chart"></div>
-<a id="activity_log_link" href="javascript: false">Show activity log</a>
-<div id="activity_log">
- <h2>$activity_log_title</h2>
- <table>
- <tr>
- <th>$header_date</th>
- <th>$header_activity</th>
- <th>$header_category</th>
- <th>$header_tags</th>
- <th>$header_start</th>
- <th>$header_end</th>
- <th>$header_duration</th>
- <th>$header_description</th>
- </tr>
- <all_activities>
+ <a id="activity_log_link" href="javascript: false">Show activity log</a>
+ <div id="activity_log">
+ <h2>$activity_log_title</h2>
+ <table>
<tr>
- <td>
- <!-- there is also date_iso -->
- $date
- </td>
- <td>$activity</td>
- <td>$category</td>
- <td>$tags</td>
- <td>
- <!-- there is also start_iso -->
- $start
- </td>
- <td>
- <!-- there is also end_iso -->
- $end
- </td>
- <td>
- <!-- there is also duration_decimal and duration_minutes -->
- $duration
- </td>
- <td>$description</td>
+ <th>$header_date</th>
+ <th>$header_activity</th>
+ <th>$header_category</th>
+ <th>$header_tags</th>
+ <th>$header_start</th>
+ <th>$header_end</th>
+ <th>$header_duration</th>
+ <th>$header_description</th>
</tr>
- </all_activities>
- </table>
-</div>
-
-
+ <all_activities>
+ <tr>
+ <td>
+ <!-- there is also date_iso -->
+ $date
+ </td>
+ <td>$activity</td>
+ <td>$category</td>
+ <td>$tags</td>
+ <td>
+ <!-- there is also start_iso -->
+ $start
+ </td>
+ <td>
+ <!-- there is also end_iso -->
+ $end
+ </td>
+ <td>
+ <!-- there is also duration_decimal and duration_minutes -->
+ $duration
+ </td>
+ <td>$description</td>
+ </tr>
+ </all_activities>
+ </table>
+ </div>
-<table>
- <tr style="vertical-align: top">
- <td style="width: 100%">
- <h2>$totals_by_day_title</h2>
- <div class="by_day_controls">
- $show_prompt
- <input type="checkbox" id="show_details" checked="checked"></input>
- <label for="show_details">$activity_totals_heading</label>
+ <table>
+ <tr style="vertical-align: top">
+ <td style="width: 100%">
+
+ <h2>$totals_by_day_title</h2>
+
+ <div class="by_day_controls">
+ $show_prompt
+ <input type="checkbox" id="show_activities" checked="checked"></input>
+ <label for="show_details">$activity_totals_heading</label>
+
+ <input type="checkbox" id="show_categories" checked="checked"></input>
+ <label for="show_totals">$category_totals_heading</label>
+
+ <input type="checkbox" id="show_tags" checked="checked"></input>
+ <label for="show_totals">$tag_totals_heading</label>
+ </div>
+
+ <table id="date_facts"></table>
+ </td>
+ <td>
+ <div>
+ <h2>Categories</h2>
+ <div id="category_chart"></div>
+ </div>
+ <div>
+ <h2>Activities</h2>
+ <div id="activity_chart"></div>
+ </div>
+ <div>
+ <h2>Tags</h2>
+ <div id="tag_chart"></div>
+ </div>
+ </td>
+ </tr>
+ </table>
- <input type="checkbox" id="show_totals" checked="checked"></input>
- <label for="show_totals">$category_totals_heading</label>
- </div>
- <table>
- <tr>
- <th>Date</th>
- <th class="by_date_row">$activity_totals_heading</th>
- <th class="by_date_total_row">$category_totals_heading</th>
- </tr>
- <by_date>
- <tr valign="top">
- <td>$date</td>
- <td class="by_date_row">
- <table width="100%">
- <by_date_activity>
- <tr>
- <td>$activity ($category)</td>
- <td style="text-align: right">
- <!-- there is also duration_decimal and duration_minutes -->
- $duration
- </td>
- </tr>
- </by_date_activity>
- </table>
- </td>
- <td class="by_date_total_row">
- <table width="100%">
- <by_date_category>
- <tr>
- <td>$category</td>
- <td style="text-align: right">
- <!-- there is also duration_decimal and duration_minutes -->
- $duration
- </td>
- </tr>
- </by_date_category>
- </table>
- </td>
- </tr>
- <tr><td colspan="3"> </td></tr>
- </by_date>
- </table>
- </td>
- <td>
- <div>
- <h2>Categories</h2>
- <div id="category_chart"></div>
- </div>
- <div>
- <h2>Activities</h2>
- <div id="activity_chart"></div>
- </div>
- <div>
- <h2>Tags</h2>
- <div id="tag_chart"></div>
- </div>
- </td>
- </tr>
-</table>
-
-
-
-<p class="template-instructions">
- <a href="file:///$data_dir/report_template.html">$show_template</a>.
- $template_instructions.
-</p>
+ <p class="template-instructions">
+ <a href="file:///$data_dir/report_template.html">$show_template</a>.
+ $template_instructions.
+ </p>
+</div>
</body>
</html>
diff --git a/src/hamster/reports.py b/src/hamster/reports.py
index 152fe6a..5e8bfb5 100644
--- a/src/hamster/reports.py
+++ b/src/hamster/reports.py
@@ -211,9 +211,6 @@ class HTMLWriter(ReportWriter):
self.fact_row_template = self._extract_template('all_activities')
self.by_date_row_template = self._extract_template('by_date_activity')
- self.by_date_total_row_template = self._extract_template("by_date_category")
- self.by_activity_category_row_template = self._extract_template("by_activity_category")
- self.totals_row_template = self._extract_template("totals_activity")
self.by_date_template = self._extract_template('by_date')
@@ -266,105 +263,38 @@ class HTMLWriter(ReportWriter):
def _finish(self, report, facts):
- # group by date
- name_category = lambda fact: (fact.category, fact.activity)
+ # group by date
by_date = []
for date, date_facts in itertools.groupby(facts, lambda fact:fact.date):
- by_name = sorted(date_facts, key=name_category)
-
- by_date_rows = []
- for (category, activity), ac_facts in itertools.groupby(by_name, name_category):
- duration = dt.timedelta()
- for fact in ac_facts:
- duration += fact.delta
-
-
- by_date_rows.append(Template(self.by_date_row_template).safe_substitute(
- dict(activity = activity,
- category = category,
- duration = stuff.format_duration(duration),
- duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
- )
- ))
-
- by_date_total_rows = []
- for category, c_facts in itertools.groupby(by_name, lambda fact:fact.category):
- duration = dt.timedelta()
- for fact in c_facts:
- duration += fact.delta
-
-
- by_date_total_rows.append(Template(self.by_date_total_row_template).safe_substitute(
- dict(category = category,
- duration = stuff.format_duration(duration),
- duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
- )
- ))
-
-
- res = Template(self.by_date_template).safe_substitute(
- dict(date = fact.date.strftime(
- # date column format for each row in HTML report
- # Using python datetime formatting syntax. See:
- # http://docs.python.org/library/time.html#time.strftime
- C_("html report","%b %d, %Y")),
- by_date_activity_rows = "\n".join(by_date_rows),
- by_date_category_rows = "\n".join(by_date_total_rows)
- ))
- by_date.append(res)
-
- by_activity_category_rows = []
- # group by activity
- name_category = lambda fact: (fact.category)
- name_activity = lambda fact: (fact.activity)
-
- total_duration = None
- by_category = sorted(facts, key=name_category)
- for category, category_facts in itertools.groupby(by_category, lambda fact:fact.category):
- by_activity = sorted(category_facts, key=name_activity)
-
- for (activity), ac_facts in itertools.groupby(by_activity, name_activity):
- duration = dt.timedelta()
- for fact in ac_facts:
- duration += fact.delta
-
- by_activity_category_rows.append(Template(self.by_activity_category_row_template).safe_substitute(
- dict(activity = activity,
- category = category,
- duration = stuff.format_duration(duration),
- duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
- )
- ))
- if (total_duration):
- total_duration += duration
- else:
- total_duration = duration
-
- by_totals_rows = []
- if (len(by_activity_category_rows) > 0):
- by_totals_rows.append(Template(self.totals_row_template).safe_substitute(
- dict(total_duration = stuff.format_duration(total_duration),
- total_duration_minutes = "%d" % (stuff.duration_minutes(total_duration)),
- total_duration_decimal = "%.2f" % (stuff.duration_minutes(total_duration) / 60.0),
- total_row = _("Total")
- )
- ))
+ by_date.append((date, [dict(fact) for fact in date_facts]))
+ by_date = dict(by_date)
+
+ date_facts = []
+ date = self.start_date
+ while date <= self.end_date:
+ str_date = date.strftime(
+ # date column format for each row in HTML report
+ # Using python datetime formatting syntax. See:
+ # http://docs.python.org/library/time.html#time.strftime
+ C_("html report","%b %d, %Y"))
+ date_facts.append([str_date, by_date.get(date, [])])
+ date += dt.timedelta(days=1)
data = dict(
title = self.title,
+ #grand_total = _("%s hours") % ("%.1f" % (total_duration.seconds / 60.0 / 60 + total_duration.days * 24)),
+
totals_by_day_title = _("Totals by Day"),
activity_log_title = _("Activity Log"),
totals_title = _("Totals"),
- activity_totals_heading = _("totals by activity"),
- category_totals_heading = _("totals by category"),
+ activity_totals_heading = _("activities"),
+ category_totals_heading = _("categories"),
+ tag_totals_heading = _("tags"),
- show_prompt = _("Show:"),
+ show_prompt = _("Distinguish:"),
header_date = _("Date"),
header_activity = _("Activity"),
@@ -382,11 +312,9 @@ class HTMLWriter(ReportWriter):
start_date = timegm(self.start_date.timetuple()),
end_date = timegm(self.end_date.timetuple()),
facts = [dict(fact) for fact in facts],
+ date_facts = date_facts,
- all_activities_rows = "\n".join(self.fact_rows),
- by_date_rows = "\n".join(by_date),
- by_activity_category_rows = "\n".join(by_activity_category_rows),
- totals_activity_rows = "\n".join(by_totals_rows)
+ all_activities_rows = "\n".join(self.fact_rows)
)
report.write(Template(self.main_template).safe_substitute(data))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]