;;; chart.el --- Draw charts (bar charts, etc)
-;; Copyright (C) 1996, 1998, 1999, 2001, 2004, 2005, 2007, 2008, 2009
+;; Copyright (C) 1996, 1998-1999, 2001, 2004-2005, 2007-2011
;; Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
(require 'eieio)
;;; Code:
-(defvar chart-map nil "Keymap used in chart mode.")
-(if chart-map
- ()
- (setq chart-map (make-sparse-keymap))
- )
+(defvar chart-mode-map (make-sparse-keymap) "Keymap used in chart mode.")
+(define-obsolete-variable-alias 'chart-map 'chart-mode-map "24.1")
(defvar chart-local-object nil
"Local variable containing the locally displayed chart object.")
(make-variable-buffer-local 'chart-local-object)
-(defvar chart-face-list nil
- "Faces used to colorize charts.
-List is limited currently, which is ok since you really can't display
-too much in text characters anyways.")
-
(defvar chart-face-color-list '("red" "green" "blue"
"cyan" "yellow" "purple")
"Colors to use when generating `chart-face-list'.
(display-graphic-p))
'("dimple1" "scales" "dot" "cross_weave" "boxes" "dimple3"))
"If pixmaps are allowed, display these background pixmaps.
-Useful if new Emacs is used on B&W display")
+Useful if new Emacs is used on B&W display.")
(defcustom chart-face-use-pixmaps nil
"*Non-nil to use fancy pixmaps in the background of chart face colors."
:group 'eieio
:type 'boolean)
-(if (and (if (fboundp 'display-color-p)
- (display-color-p)
- window-system)
- (not chart-face-list))
- (let ((cl chart-face-color-list)
- (pl chart-face-pixmap-list)
- nf)
- (while cl
- (setq nf (make-face (intern (concat "chart-" (car cl) "-" (car pl)))))
- (if (condition-case nil
- (> (x-display-color-cells) 4)
- (error t))
- (set-face-background nf (car cl))
- (set-face-background nf "white"))
- (set-face-foreground nf "black")
- (if (and chart-face-use-pixmaps
- pl
- (fboundp 'set-face-background-pixmap))
- (condition-case nil
- (set-face-background-pixmap nf (car pl))
- (error (message "Cannot set background pixmap %s" (car pl)))))
- (setq chart-face-list (cons nf chart-face-list))
- (setq cl (cdr cl)
- pl (cdr pl)))))
-
-(defun chart-mode ()
+(defvar chart-face-list
+ (if (if (fboundp 'display-color-p)
+ (display-color-p)
+ window-system)
+ (let ((cl chart-face-color-list)
+ (pl chart-face-pixmap-list)
+ (faces ())
+ nf)
+ (while cl
+ (setq nf (make-face
+ (intern (concat "chart-" (car cl) "-" (car pl)))))
+ (set-face-background nf (if (condition-case nil
+ (> (x-display-color-cells) 4)
+ (error t))
+ (car cl)
+ "white"))
+ (set-face-foreground nf "black")
+ (if (and chart-face-use-pixmaps
+ pl
+ (fboundp 'set-face-background-pixmap))
+ (condition-case nil
+ (set-face-background-pixmap nf (car pl))
+ (error (message "Cannot set background pixmap %s" (car pl)))))
+ (push nf faces)
+ (setq cl (cdr cl)
+ pl (cdr pl)))
+ faces))
+ "Faces used to colorize charts.
+List is limited currently, which is ok since you really can't display
+too much in text characters anyways.")
+
+(define-derived-mode chart-mode fundamental-mode "CHART"
"Define a mode in Emacs for displaying a chart."
- (kill-all-local-variables)
- (use-local-map chart-map)
- (setq major-mode 'chart-mode
- mode-name "CHART")
(buffer-disable-undo)
(set (make-local-variable 'font-lock-global-modes) nil)
- (font-lock-mode -1)
- (run-hooks 'chart-mode-hook)
+ (font-lock-mode -1) ;Isn't it off already? --Stef
)
(defun chart-new-buffer (obj)
"Create a new buffer NAME in which the chart OBJ is displayed.
-Returns the newly created buffer"
- (save-excursion
- (set-buffer (get-buffer-create (format "*%s*" (oref obj title))))
+Returns the newly created buffer."
+ (with-current-buffer (get-buffer-create (format "*%s*" (oref obj title)))
(chart-mode)
(setq chart-local-object obj)
(current-buffer)))
(sequences :initarg :sequences
:initform nil)
)
- "Superclass for all charts to be displayed in an emacs buffer")
+ "Superclass for all charts to be displayed in an Emacs buffer.")
(defmethod initialize-instance :AFTER ((obj chart) &rest fields)
"Initialize the chart OBJ being created with FIELDS.
:initform t)
(name-face :initarg :name-face
:initform 'bold)
- (labels-face :initarg :lables-face
+ (labels-face :initarg :labels-face
:initform 'italic)
(chart :initarg :chart
:initform nil)
((bounds :initarg :bounds
:initform '(0.0 . 50.0))
)
- "Class used to display an axis defined by a range of values")
+ "Class used to display an axis defined by a range of values.")
(defclass chart-axis-names (chart-axis)
((items :initarg :items
:initform nil)
)
- "Class used to display an axis which represents different named items")
+ "Class used to display an axis which represents different named items.")
(defclass chart-sequece ()
((data :initarg :data
(name :initarg :name
:initform "Data")
)
- "Class used for all data in different charts")
+ "Class used for all data in different charts.")
(defclass chart-bar (chart)
((direction :initarg :direction
:initform vertical))
- "Subclass for bar charts. (Vertical or horizontal)")
+ "Subclass for bar charts (vertical or horizontal).")
(defmethod chart-draw ((c chart) &optional buff)
"Start drawing a chart object C in optional BUFF.
-Erases current contents of buffer"
+Erases current contents of buffer."
(save-excursion
(if buff (set-buffer buff))
(erase-buffer)
)
(defmethod chart-axis-draw ((a chart-axis) &optional dir margin zone start end)
- "Draw some axis for A in direction DIR at with MARGIN in boundry.
+ "Draw some axis for A in direction DIR with MARGIN in boundary.
ZONE is a zone specification.
START and END represent the boundary."
(chart-draw-line dir (+ margin (if zone zone 0)) start end)
(defmethod chart-translate-namezone ((c chart) n)
"Return a dot-pair representing a positional range for a name.
The name in chart C of the Nth name resides.
-Automatically compensates for for direction."
+Automatically compensates for direction."
(let* ((dir (oref c direction))
(w (if (eq dir 'vertical) (oref c x-width) (oref c y-width)))
(m (if (eq dir 'vertical) (oref c y-margin) (oref c x-margin)))
(defmethod chart-axis-draw ((a chart-axis-names) &optional dir margin zone start end)
"Draw axis information based upon A range to be spread along the edge.
-Optional argument DIR the direction of the chart.
-Optional argument MARGIN , ZONE, START and END specify boundaries of the drawing."
+Optional argument DIR is the direction of the chart.
+Optional arguments MARGIN, ZONE, START and END specify boundaries of the drawing."
(call-next-method)
;; We prefer about 5 spaces between each value
(let* ((i 0)
(defmethod chart-sort ((c chart) pred)
"Sort the data in chart C using predicate PRED.
-See `chart-sort-matchlist' for more details"
+See `chart-sort-matchlist' for more details."
(let* ((sl (oref c sequences))
(s1 (car sl))
(s2 (car (cdr sl)))
)
(defun chart-sort-matchlist (namelst numlst pred)
- "Sort NAMELST and NUMLST (both SEQUENCE objects) based on predicate PRED.
+ "Sort NAMELST and NUMLST (both sequence objects) based on predicate PRED.
PRED should be the equivalent of '<, except it must expect two
-cons cells of the form (NAME . NUM). See SORT for more details."
+cons cells of the form (NAME . NUM). See `sort' for more details."
;; 1 - create 1 list of cons cells
(let ((newlist nil)
(alst (oref namelst data))
(defun chart-zap-chars (n)
"Zap up to N chars without deleting EOLs."
(if (not (eobp))
- (if (< n (- (save-excursion (end-of-line) (point)) (point)))
+ (if (< n (- (point-at-eol) (point)))
(delete-char n)
- (delete-region (point) (save-excursion (end-of-line) (point))))))
+ (delete-region (point) (point-at-eol)))))
(defun chart-display-label (label dir zone start end &optional face)
"Display LABEL in direction DIR in column/row ZONE between START and END.
(defun chart-draw-line (dir zone start end)
"Draw a line using line-drawing characters in direction DIR.
-Use column or row ZONE between START and END"
+Use column or row ZONE between START and END."
(chart-display-label
(make-string (- end start) (if (eq dir 'vertical) ?| ?\-))
dir zone start end))
(defun 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.
+ "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 charts' max element display to MAX, and sort lists with
+Set the chart's max element display to MAX, and sort lists with
SORT-PRED if desired."
(let ((nc (make-instance chart-bar
:title title
(setq extlst (cons s extlst)
cntlst (cons 1 cntlst)))))
(setq flst (cdr flst)))
- ;; Lets create the chart!
+ ;; Let's create the chart!
(chart-bar-quickie 'vertical "Files Extension Distribution"
extlst "File Extensions"
- cntlst "# of occurances"
+ cntlst "# of occurrences"
10
- '(lambda (a b) (> (cdr a) (cdr b))))
+ (lambda (a b) (> (cdr a) (cdr b))))
))
(defun chart-space-usage (d)
nmlst "File Name"
cntlst "File Size"
10
- '(lambda (a b) (> (cdr a) (cdr b))))
+ (lambda (a b) (> (cdr a) (cdr b))))
))
(defun chart-emacs-storage ()
;(car (nth 5 data)) ; floats are Emacs only
;(cdr (nth 5 data))
)))
- ;; Lets create the chart!
+ ;; Let's create the chart!
(chart-bar-quickie 'vertical "Emacs Runtime Storage Usage"
names "Storage Items"
nums "Objects")))
(if (fboundp 'x-display-list)
(setq names (append names '("x-displays"))
nums (append nums (list (length (x-display-list))))))
- ;; Lets create the chart!
+ ;; Let's create the chart!
(chart-bar-quickie 'vertical "Emacs List Size Chart"
names "Various Lists"
nums "Objects")))
(setcar cell (1+ (car cell))))
(setq nmlst (cons nam nmlst)
cntlst (cons 1 cntlst))))))
- (chart-bar-quickie 'vertical "Username Occurance in RMAIL box"
+ (chart-bar-quickie 'vertical "Username Occurrence in RMAIL box"
nmlst "User Names"
- cntlst "# of occurances"
+ cntlst "# of occurrences"
10
- '(lambda (a b) (> (cdr a) (cdr b))))
+ (lambda (a b) (> (cdr a) (cdr b))))
))