Mae向きなブログ

Mae向きな情報発信を続けていきたいと思います。

15. グラフを描く準備

グラフを表示する関数で、横棒のグラフを描くバージョンを作りなさい。

解答を以下に載せていますが,行の途中にポイントがある場合は,グラフがきれいに表示されません。
原因は,横棒を表示してから,forward-line関数で次の行に移動するのですが,次の行の行頭に移動してしまうためです。from-positionの真下に移動する方法がまだ理解できていません。

それから,list2str関数を作ったのですが,これは,

(" " " " "*" "*" "*")

のようなリストを

"  ***"

という文字列に変換するためのものです。emacs lispに同等の機能を持つ関数はあるのでしょうか?

(defvar graph-symbol "*"
  "String used as symbol in graph, usually an asterisk.")

(defvar graph-blank " "
  "String used as blank in graph, usually a blank space.
graph-blank must be the same number of columns wide
as graph-symbol.")

(defun column-of-graph (max-graph-height actual-height) 
  (let ((insert-list nil)
        (number-of-top-blanks
         (- max-graph-height actual-height)))

    ;; graph-symbols を詰める
    (while (> actual-height 0)                
      (setq insert-list (cons graph-symbol insert-list))
      (setq actual-height (1- actual-height)))

    ;; graph-blanks を詰める
    (while (> number-of-top-blanks 0) 
      (setq insert-list (cons graph-blank insert-list))
      (setq number-of-top-blanks
            (1- number-of-top-blanks)))

    ;; リスト全体を返す
    insert-list))

(defun graph-body-print (numbers-list)
  (let ((height (apply 'max numbers-list))
        (symbol-width (length graph-blank))
        from-position)

    (while numbers-list
      (setq from-position (point))
      (insert 
       (list2str 
	(nreverse (column-of-graph height (car numbers-list)))))
      (goto-char from-position)
      (forward-line)
      ;; 各桁ごとのグラフの描写
      (sit-for 0)               
      (setq numbers-list (cdr numbers-list)))
    (insert "\n")
    ))

(defun list2str (lst)
  (let ((tmp nil))
    (while lst
      (setq tmp (concat tmp (car lst)))
      (setq lst (cdr lst)))
    tmp))

;(graph-body-print '(1 2 3 4 6 4 3 5 7 6 5 2 3))