The final version (Programming in Emacs Lisp)

Next: , Up: Printing the Whole Graph [Contents][Index]


Changes for the Final Version

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 Y-axis-column function, to add vertical-step to it. The function looks like this:

;;; 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 print-graph function:

;;; 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)))

Next: Testing print-graph, Up: Printing the Whole Graph [Contents][Index]

AltStyle によって変換されたページ (->オリジナル) /