support for saving stats to a pdf

This commit is contained in:
Damien Elmes 2017-01-13 17:36:26 +10:00
parent e6adc3c195
commit ed07a147f9
2 changed files with 37 additions and 40 deletions

View file

@ -113,23 +113,29 @@ class CollectionStats(object):
self.type = type
from .statsbg import bg
txt = self.css % bg
txt += self.todayStats()
txt += self.dueGraph()
txt += self.repsGraph()
txt += self.introductionGraph()
txt += self.ivlGraph()
txt += self.hourGraph()
txt += self.easeGraph()
txt += self.cardGraph()
txt += self.footer()
txt += self._section(self.todayStats())
txt += self._section(self.dueGraph())
txt += self.repsGraphs()
txt += self._section(self.introductionGraph())
txt += self._section(self.ivlGraph())
txt += self._section(self.hourGraph())
txt += self._section(self.easeGraph())
txt += self._section(self.cardGraph())
txt += self._section(self.footer())
return "<script>%s\n</script><center>%s</center>" % (
anki.js.jquery+anki.js.plot, txt)
def _section(self, txt):
return "<div class=section>%s</div>" % txt
css = """
<style>
h1 { margin-bottom: 0; margin-top: 1em; }
.pielabel { text-align:center; padding:0px; color:white; }
body {background-image: url(data:image/png;base64,%s); }
@media print {
.section { page-break-inside: avoid; padding-top: 5mm; }
}
</style>
"""
@ -297,19 +303,19 @@ group by day order by day""" % (self._limit(), lim),
return txt
def repsGraph(self):
def repsGraphs(self):
if self.type == 0:
days = 30; chunk = 1
elif self.type == 1:
days = 52; chunk = 7
else:
days = None; chunk = 30
return self._repsGraph(self._done(days, chunk),
return self._repsGraphs(self._done(days, chunk),
days,
_("Review Count"),
_("Review Time"))
def _repsGraph(self, data, days, reptitle, timetitle):
def _repsGraphs(self, data, days, reptitle, timetitle):
if not data:
return ""
d = data
@ -328,13 +334,13 @@ group by day order by day""" % (self._limit(), lim),
(4, colRelearn, _("Relearn")),
(1, colLearn, _("Learn")),
(5, colCram, _("Cram"))))
txt = self._title(
txt1 = self._title(
reptitle, _("The number of questions you have answered."))
txt += plot("reps", repdata, ylabel=_("Answers"), ylabel2=_(
txt1 += plot("reps", repdata, ylabel=_("Answers"), ylabel2=_(
"Cumulative Answers"))
(daysStud, fstDay) = self._daysStudied()
rep, tot = self._ansInfo(repsum, daysStud, fstDay, _("reviews"))
txt += rep
txt1 += rep
# time
(timdata, timsum) = self._splitRepData(d, (
(8, colMature, _("Mature")),
@ -348,12 +354,12 @@ group by day order by day""" % (self._limit(), lim),
else:
t = _("Hours")
convHours = True
txt += self._title(timetitle, _("The time taken to answer the questions."))
txt += plot("time", timdata, ylabel=t, ylabel2=_("Cumulative %s") % t)
txt2 = self._title(timetitle, _("The time taken to answer the questions."))
txt2 += plot("time", timdata, ylabel=t, ylabel2=_("Cumulative %s") % t)
rep, tot2 = self._ansInfo(
timsum, daysStud, fstDay, _("minutes"), convHours, total=tot)
txt += rep
return txt
txt2 += rep
return self._section(txt1) + self._section(txt2)
def _ansInfo(self, totd, studied, first, unit, convHours=False, total=None):
if not totd:

View file

@ -4,7 +4,8 @@
from aqt.qt import *
import os, time
from aqt.utils import saveGeom, restoreGeom, maybeHideClose, showInfo, addCloseShortcut
from aqt.utils import saveGeom, restoreGeom, maybeHideClose, addCloseShortcut, \
tooltip
import aqt
# Deck Stats
@ -25,9 +26,9 @@ class DeckStats(QDialog):
f = self.form
f.setupUi(self)
restoreGeom(self, self.name)
b = f.buttonBox.addButton(_("Save Image"),
b = f.buttonBox.addButton(_("Save PDF"),
QDialogButtonBox.ActionRole)
b.clicked.connect(self.browser)
b.clicked.connect(self.saveImage)
b.setAutoDefault(False)
f.groups.clicked.connect(lambda: self.changeScope("deck"))
f.groups.setShortcut("g")
@ -39,14 +40,13 @@ class DeckStats(QDialog):
addCloseShortcut(self)
self.refresh()
self.show()
print("fixme: save image support in deck stats")
def reject(self):
saveGeom(self, self.name)
QDialog.reject(self)
def browser(self):
name = time.strftime("-%Y-%m-%d@%H-%M-%S.png",
def _imagePath(self):
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf",
time.localtime(time.time()))
name = "anki-"+_("stats")+name
desktopPath = QStandardPaths.writableLocation(
@ -54,21 +54,12 @@ class DeckStats(QDialog):
if not os.path.exists(desktopPath):
os.mkdir(desktopPath)
path = os.path.join(desktopPath, name)
p = self.form.web.page()
oldsize = p.viewportSize()
p.setViewportSize(p.mainFrame().contentsSize())
image = QImage(p.viewportSize(), QImage.Format_ARGB32)
painter = QPainter(image)
p.mainFrame().render(painter)
painter.end()
isOK = image.save(path, "png")
if isOK:
showInfo(_("An image was saved to your desktop."))
else:
showInfo(_("""\
Anki could not save the image. Please check that you have permission to write \
to your desktop."""))
p.setViewportSize(oldsize)
return path
def saveImage(self):
path = self._imagePath()
self.form.web.page().printToPdf(path)
tooltip(_("A PDF file was saved to your desktop."))
def changePeriod(self, n):
self.period = n