The final version is different from what we planned in two ways: first, it contains additional values calculated once in the varlist; second, it carries an option to specify the labels’ increment per row. This latter feature turns out to be essential; otherwise, a graph may have more rows than fit on a display or on a sheet of paper.
This new feature requires a change to the
function, to add
vertical-step to it. The function looks like
;;; 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)))
The values for the maximum height of graph and the width of a symbol
are computed by
print-graph in its
let expression; so
graph-body-print must be changed to accept them.
;;; 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")))
Finally, the code for the
;;; 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)) ;;
heightis 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)))