mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
Merge branch 'master' of https://github.com/sobjornstad/anki
This commit is contained in:
commit
c4fffdda92
2 changed files with 87 additions and 12 deletions
|
@ -117,6 +117,7 @@ class CollectionStats(object):
|
|||
txt += self.todayStats()
|
||||
txt += self.dueGraph()
|
||||
txt += self.repsGraph()
|
||||
txt += self.introductionGraph()
|
||||
txt += self.ivlGraph()
|
||||
txt += self.hourGraph()
|
||||
txt += self.easeGraph()
|
||||
|
@ -254,9 +255,49 @@ group by day order by day""" % (self._limit(), lim),
|
|||
today=self.col.sched.today,
|
||||
chunk=chunk)
|
||||
|
||||
# Reps and time spent
|
||||
# Added, reps and time spent
|
||||
######################################################################
|
||||
|
||||
def introductionGraph(self):
|
||||
if self.type == 0:
|
||||
days = 30; chunk = 1
|
||||
elif self.type == 1:
|
||||
days = 52; chunk = 7
|
||||
else:
|
||||
days = None; chunk = 30
|
||||
return self._introductionGraph(self._added(days, chunk),
|
||||
days, _("Added"))
|
||||
|
||||
def _introductionGraph(self, data, days, title):
|
||||
if not data:
|
||||
return ""
|
||||
d = data
|
||||
conf = dict(
|
||||
xaxis=dict(tickDecimals=0, max=0.5),
|
||||
yaxes=[dict(min=0), dict(position="right",min=0)])
|
||||
if days is not None:
|
||||
conf['xaxis']['min'] = -days+0.5
|
||||
def plot(id, data, ylabel, ylabel2):
|
||||
return self._graph(
|
||||
id, data=data, conf=conf, ylabel=ylabel, ylabel2=ylabel2)
|
||||
# graph
|
||||
(repdata, repsum) = self._splitRepData(d, ((1, colLearn, ""),))
|
||||
txt = self._title(
|
||||
title, _("The number of new cards you have added."))
|
||||
txt += plot("intro", repdata, ylabel=_("Cards"), ylabel2=_("Cumulative Cards"))
|
||||
# total and per day average
|
||||
tot = sum([i[1] for i in d])
|
||||
period = self._periodDays()
|
||||
if not period:
|
||||
# base off date of earliest added card
|
||||
period = self._deckAge('add')
|
||||
i = []
|
||||
self._line(i, _("Total"), _("%i cards") % tot)
|
||||
self._line(i, _("Average"), _("%.01f cards/day") % (float(tot) / period))
|
||||
txt += self._lineTbl(i)
|
||||
|
||||
return txt
|
||||
|
||||
def repsGraph(self):
|
||||
if self.type == 0:
|
||||
days = 30; chunk = 1
|
||||
|
@ -322,15 +363,7 @@ group by day order by day""" % (self._limit(), lim),
|
|||
period = self._periodDays()
|
||||
if not period:
|
||||
# base off earliest repetition date
|
||||
lim = self._revlogLimit()
|
||||
if lim:
|
||||
lim = " where " + lim
|
||||
t = self.col.db.scalar("select id from revlog %s order by id limit 1" % lim)
|
||||
if not t:
|
||||
period = 1
|
||||
else:
|
||||
period = max(
|
||||
1, int(1+((self.col.sched.dayCutoff - (t/1000)) / 86400)))
|
||||
period = self._deckAge('review')
|
||||
i = []
|
||||
self._line(i, _("Days studied"),
|
||||
_("<b>%(pct)d%%</b> (%(x)s of %(y)s)") % dict(
|
||||
|
@ -394,6 +427,27 @@ group by day order by day""" % (self._limit(), lim),
|
|||
bars={'show': False}, lines=dict(show=True), stack=-n))
|
||||
return (ret, alltot)
|
||||
|
||||
def _added(self, num=7, chunk=1):
|
||||
lims = []
|
||||
if num is not None:
|
||||
lims.append("id > %d" % (
|
||||
(self.col.sched.dayCutoff-(num*chunk*86400))*1000))
|
||||
lims.append("did in %s" % self._limit())
|
||||
if lims:
|
||||
lim = "where " + " and ".join(lims)
|
||||
else:
|
||||
lim = ""
|
||||
if self.type == 0:
|
||||
tf = 60.0 # minutes
|
||||
else:
|
||||
tf = 3600.0 # hours
|
||||
return self.col.db.all("""
|
||||
select
|
||||
(cast((id/1000.0 - :cut) / 86400.0 as int))/:chunk as day,
|
||||
count(id)
|
||||
from cards %s
|
||||
group by day order by day""" % lim, cut=self.col.sched.dayCutoff,tf=tf, chunk=chunk)
|
||||
|
||||
def _done(self, num=7, chunk=1):
|
||||
lims = []
|
||||
if num is not None:
|
||||
|
@ -839,6 +893,22 @@ $(function () {
|
|||
def _title(self, title, subtitle=""):
|
||||
return '<h1>%s</h1>%s' % (title, subtitle)
|
||||
|
||||
def _deckAge(self, by):
|
||||
lim = self._revlogLimit()
|
||||
if lim:
|
||||
lim = " where " + lim
|
||||
if by == 'review':
|
||||
t = self.col.db.scalar("select id from revlog %s order by id limit 1" % lim)
|
||||
elif by == 'add':
|
||||
lim = "where did in %s" % ids2str(self.col.decks.active())
|
||||
t = self.col.db.scalar("select id from cards %s order by id limit 1" % lim)
|
||||
if not t:
|
||||
period = 1
|
||||
else:
|
||||
period = max(
|
||||
1, int(1+((self.col.sched.dayCutoff - (t/1000)) / 86400)))
|
||||
return period
|
||||
|
||||
def _periodDays(self):
|
||||
if self.type == 0:
|
||||
return 30
|
||||
|
|
|
@ -41,6 +41,7 @@ class ExportDialog(QDialog):
|
|||
def exporterChanged(self, idx):
|
||||
self.exporter = exporters()[idx][1](self.col)
|
||||
self.isApkg = hasattr(self.exporter, "includeSched")
|
||||
self.isTextNote = hasattr(self.exporter, "includeTags")
|
||||
self.hideTags = hasattr(self.exporter, "hideTags")
|
||||
self.frm.includeSched.setVisible(self.isApkg)
|
||||
self.frm.includeMedia.setVisible(self.isApkg)
|
||||
|
@ -103,7 +104,11 @@ class ExportDialog(QDialog):
|
|||
period = 5000
|
||||
else:
|
||||
period = 3000
|
||||
msg = ngettext("%d card exported.", "%d cards exported.", \
|
||||
if self.isTextNote:
|
||||
msg = ngettext("%d note exported.", "%d notes exported.",
|
||||
self.exporter.count) % self.exporter.count
|
||||
else:
|
||||
msg = ngettext("%d card exported.", "%d cards exported.",
|
||||
self.exporter.count) % self.exporter.count
|
||||
tooltip(msg, period=period)
|
||||
finally:
|
||||
|
|
Loading…
Reference in a new issue