diff --git a/anki/graphs.py b/anki/graphs.py
index c4b9700c6..6105262b6 100644
--- a/anki/graphs.py
+++ b/anki/graphs.py
@@ -24,31 +24,30 @@ class Graphs(object):
self.deck = deck
self._stats = None
self.selective = selective
+ self.type = 0
def report(self, type=0):
# 0=days, 1=weeks, 2=months
# period-dependent graphs
- txt = self.dueGraph(type)
- txt += self.repsGraph(type)
- txt += self.ivlGraph(type)
+ self.type = type
+ txt = self.dueGraph()
+ txt += self.repsGraph()
+ txt += self.ivlGraph()
# other graphs
txt += self.easeGraph()
- return "
%s" % (anki.js.all, txt)
+ return "%s" % (anki.js.all, txt)
# Due and cumulative due
######################################################################
- def dueGraph(self, type):
- if type == 0:
- start = 0; end = 30; chunk = 1
- elif type == 1:
+ def dueGraph(self):
+ if self.type == 0:
+ start = 0; end = 30; chunk = 1;
+ elif self.type == 1:
start = 0; end = 52; chunk = 7
- elif type == 2:
+ elif self.type == 2:
start = 0; end = None; chunk = 30
- return self._dueGraph(self._due(start, end, chunk), _("Forecast"))
-
- def _dueGraph(self, data, title):
- d = data
+ d = self._due(start, end, chunk)
yng = []
mtr = []
tot = 0
@@ -58,12 +57,12 @@ class Graphs(object):
mtr.append((day[0], day[2]))
tot += day[1]+day[2]
totd.append((day[0], tot))
- txt = self._graph(id="due", title=title, data=[
+ txt = self._graph(id="due", title=_("Forecast"), data=[
dict(data=mtr, color=colMature, label=_("Mature")),
dict(data=yng, color=colYoung, label=_("Young")),
dict(data=totd, color=colCum, label=_("Cumulative"), yaxis=2,
bars={'show': False}, lines=dict(show=True), stack=False)
- ], conf=dict(
+ ], info=_("The number of reviews due in the future."), conf=dict(
xaxis=dict(tickDecimals=0),
yaxes=[dict(), dict(position="right")]))
return txt
@@ -75,7 +74,7 @@ class Graphs(object):
if end is not None:
lim += " and day < %d" % end
return self.deck.db.all("""
-select (due-:today+1)/:chunk as day,
+select (due-:today)/:chunk as day,
sum(case when ivl < 21 then 1 else 0 end), -- yng
sum(case when ivl >= 21 then 1 else 0 end) -- mtr
from cards
@@ -88,10 +87,10 @@ group by day order by day""" % (self._limit(), lim),
# Reps and time spent
######################################################################
- def repsGraph(self, type):
- if type == 0:
+ def repsGraph(self):
+ if self.type == 0:
days = 30; chunk = 1
- elif type == 1:
+ elif self.type == 1:
days = 52; chunk = 7
else:
days = None; chunk = 30
@@ -107,9 +106,9 @@ group by day order by day""" % (self._limit(), lim),
yaxes=[dict(), dict(position="right")])
if days is not None:
conf['xaxis']['min'] = -days
- def plot(id, title, data, ylabel):
+ def plot(id, title, data, ylabel, info):
return self._graph(id, title=title,
- data=data, conf=conf, ylabel=ylabel)
+ data=data, conf=conf, ylabel=ylabel, info=info)
# reps
(repdata, repsum) = self._splitRepData(d, (
(3, colMature, _("Mature")),
@@ -117,7 +116,10 @@ group by day order by day""" % (self._limit(), lim),
(4, colRelearn, _("Relearn")),
(1, colLearn, _("Learn")),
(5, colCram, _("Cram"))))
- txt = plot("reps", reptitle, repdata, ylabel=_("Answers"))
+ txt = plot("reps", reptitle, repdata, ylabel=_("Answers"),
+ info=_("""\
+The number of cards you have answered. Answering the same card twice \
+counts as two answers."""))
# time
(timdata, timsum) = self._splitRepData(d, (
(8, colMature, _("Mature")),
@@ -125,7 +127,8 @@ group by day order by day""" % (self._limit(), lim),
(9, colRelearn, _("Relearn")),
(6, colLearn, _("Learn")),
(10, colCram, _("Cram"))))
- txt += plot("time", timetitle, timdata, ylabel=_("Hours"))
+ txt += plot("time", timetitle, timdata, ylabel=_("Hours"), info=_("""\
+Time spent answering cards."""))
return txt
def _splitRepData(self, data, spec):
@@ -179,11 +182,11 @@ group by day order by day""" % lim,
# Intervals
######################################################################
- def ivlGraph(self, type):
- (ivls, all) = self._ivls(type)
+ def ivlGraph(self):
+ (ivls, all) = self._ivls()
tot = 0
totd = []
- if not all:
+ if not ivls or not all:
return ""
for (grp, cnt) in ivls:
tot += cnt
@@ -193,13 +196,16 @@ group by day order by day""" % lim,
dict(data=totd, color=colCum, label=_("% Total"), yaxis=2,
bars={'show': False}, lines=dict(show=True), stack=False)
], conf=dict(
- yaxes=[dict(), dict(position="right", max=105)]))
+ yaxes=[dict(), dict(position="right", max=105)]),
+ info=_("""\
+Intervals in the review queue. New cards and cards in (re)learning \
+are not included."""))
return txt
- def _ivls(self, type):
- if type == 0:
+ def _ivls(self):
+ if self.type == 0:
chunk = 1; lim = " and grp <= 30"
- elif type == 1:
+ elif self.type == 1:
chunk = 7; lim = " and grp <= 52"
else:
chunk = 30; lim = ""
@@ -230,11 +236,12 @@ select count() from cards where queue = 2 %s""" % self._limit()))
ticks = [[1,1],[2,2],[3,3],
[6,1],[7,2],[8,3],[9,4],
[11, 1],[12,2],[13,3],[14,4]]
- txt = self._graph(id="ease", title=_("Eases"), data=[
- dict(data=d['lrn'], color=easesNewC, label=_("Learning")),
- dict(data=d['yng'], color=easesYoungC, label=_("Young")),
- dict(data=d['mtr'], color=easesMatureC, label=_("Mature")),
- ], type="barsLine", conf=dict(
+ txt = self._graph(id="ease", title=_("Answer Buttons"), data=[
+ dict(data=d['lrn'], color=colLearn, label=_("Learning")),
+ dict(data=d['yng'], color=colYoung, label=_("Young")),
+ dict(data=d['mtr'], color=colMature, label=_("Mature")),
+ ], type="barsLine", info=_("""\
+The number of times you have pressed each answer button."""), conf=dict(
xaxis=dict(ticks=ticks, min=0, max=15)),
ylabel=_("Answers"))
return txt
@@ -254,13 +261,17 @@ order by thetype, ease""")
######################################################################
def _graph(self, id, title, data, conf={}, width=600, height=200,
- type="bars", ylabel=_("Cards")):
+ type="bars", ylabel=_("Cards"), timeTicks=True, info=""):
# display settings
conf['legend'] = {'container': "#%sLegend" % id}
conf['series'] = dict(stack=True)
if not 'yaxis' in conf:
conf['yaxis'] = {}
conf['yaxis']['labelWidth'] = 40
+ if 'xaxis' not in conf:
+ conf['xaxis'] = {}
+ if timeTicks:
+ conf['timeTicks'] = (_("d"), _("w"), _("m"))[self.type]
if type == "bars":
conf['series']['bars'] = dict(
show=True, barWidth=0.8, align="center", fill=0.7, lineWidth=0)
@@ -276,16 +287,27 @@ order by thetype, ease""")
%(ylab)s |
+
|
-
|
+
+
+
+ %(info)s
+ |
""" % dict(
id=id, title=title, w=width, h=height, tw=width+100, ylab=ylabel,
- data=simplejson.dumps(data),
- conf=simplejson.dumps(conf)))
+ info=info,
+ data=simplejson.dumps(data), conf=simplejson.dumps(conf)))
def _limit(self):
if self.selective: