最終版は、当初の計画とは2点異なります。第一に、varlist内で一度だけ計算された追加の値が含まれている点です。第二に、行ごとのラベルの増分を指定するオプションが備わっている点です。後者の機能は不可欠であることが判明しました。そうでなければ、グラフの行数がディスプレイや用紙に収まりきらない可能性があります。
この新機能では、Y-axis-column 関数に vertical-step を追加する変更が必要です。関数は以下のようになっています。
;;; Final version.
(defun Y-axis-column
(height width-of-label &optional vertical-step)
"Construct list of labels for Y axis.
HEIGHT is maximum height of graph.
WIDTH-OF-LABEL is maximum width of label.
VERTICAL-STEP, an option, is a positive integer
that specifies how much a Y axis label increments
for each line. For example, a step of 5 means
that each line is five units of the graph."
(let (Y-axis
(number-per-line (or vertical-step 1)))
(while (> height 1)
(if (zerop (% height Y-axis-label-spacing))
;; Insert label.
(setq Y-axis
(cons
(Y-axis-element
(* height number-per-line)
width-of-label)
Y-axis))
;; Else, insert blanks.
(setq Y-axis
(cons
(make-string width-of-label ? )
Y-axis)))
(setq height (1- height)))
;; Insert base line.
(setq Y-axis (cons (Y-axis-element
(or vertical-step 1)
width-of-label)
Y-axis))
(nreverse Y-axis)))
グラフの最大高さとシンボルの幅の値は、print-graph の let 式で計算されるため、graph-body-print
をそれらを受け付けるように変更する必要があります。
;;; Final version.
(defun graph-body-print (numbers-list height symbol-width)
"Print a bar graph of the NUMBERS-LIST.
The numbers-list consists of the Y-axis values.
HEIGHT is maximum height of graph.
SYMBOL-WIDTH is number of each column."
(let (from-position)
(while numbers-list
(setq from-position (point))
(insert-rectangle
(column-of-graph height (car numbers-list)))
(goto-char from-position)
(forward-char symbol-width)
;; Draw graph column by column. (sit-for 0) (setq numbers-list (cdr numbers-list))) ;; Place point for X axis labels. (forward-line height) (insert "\n")))
最後に、print-graph関数のコードです:
;;; Final version.
(defun print-graph
(numbers-list &optional vertical-step)
"Print labeled bar graph of the NUMBERS-LIST.
The numbers-list consists of the Y-axis values.
Optionally, VERTICAL-STEP, a positive integer, specifies how much a Y axis label increments for each line. For example, a step of 5 means that each row is five units."
(let* ((symbol-width (length graph-blank))
;; height is both the largest number
;; and the number with the most digits.
(height (apply 'max numbers-list))
(height-of-top-line
(if (zerop (% height Y-axis-label-spacing))
height
;; else
(* (1+ (/ height Y-axis-label-spacing))
Y-axis-label-spacing)))
(vertical-step (or vertical-step 1))
(full-Y-label-width
(length
(concat
(number-to-string
(* height-of-top-line vertical-step))
Y-axis-tic))))
(print-Y-axis
height-of-top-line full-Y-label-width vertical-step)
(graph-body-print
numbers-list height-of-top-line symbol-width)
(print-X-axis numbers-list)))