暗无天日

=============>DarkSun的个人博客

用直方图展示阅读时间分布情况

今天发现了一个Emacs内置库叫 chart,居然可以帮我们在Emacs中画直方图,直接把我震惊了。

这个库的接口非常简单,只有一个函数 chart-bar-quickie,关于用法可以参见它的doc-string

chart-bar-quickie is a compiled Lisp function in ‘chart.el’.

(chart-bar-quickie DIR TITLE NAMELST NAMETITLE NUMLST NUMTITLE &optional MAX
SORT-PRED)

Wash over the complex EIEIO stuff and create a nice bar chart.
Create it going in direction DIR [‘horizontal’ ‘vertical’] with TITLE
using a name sequence NAMELST labeled NAMETITLE with values NUMLST
labeled NUMTITLE.
Optional arguments:
Set the chart’s max element display to MAX, and sort lists with
SORT-PRED if desired.

刚好最近我在尝试记录阅读书籍的时间,于是就想着可以试试直方图展示一下阅读各本书的时间。

有了 chart 做图,那么下面最重要的就是如何获取书籍和阅读时间了。

我把书籍阅读的信息存在 books.org 目录中,其中每个一级标题就是书籍名称。通过查看org的函数列表,我发现一个 org-clock-get-table-data 似乎非常满足我的要求。

org-clock-get-table-data is a compiled Lisp function in
‘elpa/org-plus-contrib-20191209/org-clock.el’.

(org-clock-get-table-data FILE PARAMS)

Get the clocktable data for file FILE, with parameters PARAMS.
FILE is only for identification - this function assumes that
the correct buffer is current, and that the wanted restriction is
in place.
The return value will be a list with the file name and the total
file time (in minutes) as 1st and 2nd elements.  The third element
of this list will be a list of headline entries.  Each entry has the
following structure:

  (LEVEL HEADLINE TAGS TIMESTAMP TIME PROPERTIES)

LEVEL:      The level of the headline, as an integer.  This will be
            the reduced level, so 1,2,3,... even if only odd levels
            are being used.
HEADLINE:   The text of the headline.  Depending on PARAMS, this may
            already be formatted like a link.
TAGS:       The list of tags of the headline.
TIMESTAMP:  If PARAMS require it, this will be a time stamp found in the
            entry, any of SCHEDULED, DEADLINE, NORMAL, or first inactive,
            in this sequence.
TIME:       The sum of all time spend in this tree, in minutes.  This time
            will of cause be restricted to the time block and tags match
            specified in PARAMS.
PROPERTIES: The list properties specified in the ‘:properties’ parameter
            along with their value, as an alist following the pattern
            (NAME . VALUE).

最终的代码如下:

(let* ((org-file "~/我的GTD/books.org")
       (clock-table-data (with-temp-buffer
                           (insert-file-contents-literally org-file)
                           (org-mode)
                           (org-clock-get-table-data "BOOKS"  '(:scope 'file :maxlevel 1))))
       (time-consum-data (nth 2 clock-table-data))
       (books (mapcar #'cadr time-consum-data))
       (books (mapcar (lambda (book)
                        (decode-coding-string book 'utf-8)) books)) ;使用utf-8解析,否则是乱码
       (times (mapcar (lambda (l)
                       (nth 4 l)) time-consum-data)))
  (chart-bar-quickie 'vertical' "阅读时间"
                     books "书籍"
                     times "耗时(分)"))

screenshot-28.png