;;; chart.el --- Draw charts (bar charts, etc) -*- lexical-binding: t -*-
-;; Copyright (C) 1996, 1998-1999, 2001, 2004-2005, 2007-2013 Free
+;; Copyright (C) 1996, 1998-1999, 2001, 2004-2005, 2007-2016 Free
;; Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; with all the bitmaps you want to use.
(require 'eieio)
+(eval-when-compile (require 'cl-generic))
;;; Code:
(define-obsolete-variable-alias 'chart-map 'chart-mode-map "24.1")
:group 'eieio
:type 'boolean)
+(declare-function x-display-color-cells "xfns.c" (&optional terminal))
+
(defvar chart-face-list
- (if (if (fboundp 'display-color-p)
- (display-color-p)
- window-system)
+ (if (display-color-p)
(let ((cl chart-face-color-list)
(pl chart-face-pixmap-list)
(faces ())
(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."
- (with-current-buffer (get-buffer-create (format "*%s*" (oref obj title)))
- (chart-mode)
- (setq chart-local-object obj)
- (current-buffer)))
-
(defclass chart ()
((title :initarg :title
:initform "Emacs Chart")
)
"Superclass for all charts to be displayed in an Emacs buffer.")
-(defmethod initialize-instance :AFTER ((obj chart) &rest _fields)
+(defun chart-new-buffer (obj)
+ "Create a new buffer NAME in which the chart OBJ is displayed.
+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)))
+
+(cl-defmethod initialize-instance :after ((obj chart) &rest _fields)
"Initialize the chart OBJ being created with FIELDS.
Make sure the width/height is correct."
(oset obj x-width (- (window-width) 10))
:initform vertical))
"Subclass for bar charts (vertical or horizontal).")
-(defmethod chart-draw ((c chart) &optional buff)
+(cl-defmethod chart-draw ((c chart) &optional buff)
"Start drawing a chart object C in optional BUFF.
Erases current contents of buffer."
(save-excursion
(message "Rendering chart...done")
))
-(defmethod chart-draw-title ((c chart))
+(cl-defmethod chart-draw-title ((c chart))
"Draw a title upon the chart.
Argument C is the chart object."
(chart-display-label (oref c title) 'horizontal 0 0 (window-width)
(oref c title-face)))
-(defmethod chart-size-in-dir ((c chart) dir)
+(cl-defmethod chart-size-in-dir ((c chart) dir)
"Return the physical size of chart C in direction DIR."
(if (eq dir 'vertical)
(oref c y-width)
(oref c x-width)))
-(defmethod chart-draw-axis ((c chart))
+(cl-defmethod chart-draw-axis ((c chart))
"Draw axis into the current buffer defined by chart C."
(let ((ymarg (oref c y-margin))
(xmarg (oref c x-margin))
ymarg (+ ymarg xlen)))
)
-(defmethod chart-axis-draw ((a chart-axis) &optional dir margin zone start end)
+(cl-defmethod chart-axis-draw ((a chart-axis) &optional dir margin zone start end)
"Draw some axis for A in direction DIR with MARGIN in boundary.
ZONE is a zone specification.
START and END represent the boundary."
1 0))
start end (oref a name-face)))
-(defmethod chart-translate-xpos ((c chart) x)
+(cl-defmethod chart-translate-xpos ((c chart) x)
"Translate in chart C the coordinate X into a screen column."
(let ((range (oref (oref c x-axis) bounds)))
(+ (oref c x-margin)
(float (- (cdr range) (car range))))))))
)
-(defmethod chart-translate-ypos ((c chart) y)
+(cl-defmethod chart-translate-ypos ((c chart) y)
"Translate in chart C the coordinate Y into a screen row."
(let ((range (oref (oref c y-axis) bounds)))
(+ (oref c x-margin)
(float (- (cdr range) (car range)))))))))
)
-(defmethod chart-axis-draw ((a chart-axis-range) &optional dir margin zone _start _end)
+(cl-defmethod chart-axis-draw ((a chart-axis-range) &optional dir margin zone _start _end)
"Draw axis information based upon a range to be spread along the edge.
A is the chart to draw. DIR is the direction.
MARGIN, ZONE, START, and END specify restrictions in chart space."
- (call-next-method)
+ (cl-call-next-method)
;; We prefer about 5 spaces between each value
(let* ((i (car (oref a bounds)))
(e (cdr (oref a bounds)))
(setq i (+ i j))))
)
-(defmethod chart-translate-namezone ((c chart) n)
+(cl-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 direction."
(+ m -1 (round (* lpn (+ 1.0 (float n))))))
))
-(defmethod chart-axis-draw ((a chart-axis-names) &optional dir margin zone _start _end)
+(cl-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 is the direction of the chart.
Optional arguments MARGIN, ZONE, START and END specify boundaries of the drawing."
- (call-next-method)
+ (cl-call-next-method)
;; We prefer about 5 spaces between each value
(let* ((i 0)
(s (oref a items))
s (cdr s))))
)
-(defmethod chart-draw-data ((c chart-bar))
+(cl-defmethod chart-draw-data ((c chart-bar))
"Display the data available in a bar chart C."
(let* ((data (oref c sequences))
(dir (oref c direction))
(setq data (cdr data))))
)
-(defmethod chart-add-sequence ((c chart) &optional seq axis-label)
+(cl-defmethod chart-add-sequence ((c chart) &optional seq axis-label)
"Add to chart object C the sequence object SEQ.
If AXIS-LABEL, then the axis stored in C is updated with the bounds of SEQ,
or is created with the bounds of SEQ."
(if (stringp (car (oref seq data)))
(let ((labels (oref seq data)))
(if (not axis)
- (setq axis (make-instance chart-axis-names
+ (setq axis (make-instance 'chart-axis-names
:name (oref seq name)
:items labels
:chart c))
(let ((range (cons 0 1))
(l (oref seq data)))
(if (not axis)
- (setq axis (make-instance chart-axis-range
+ (setq axis (make-instance 'chart-axis-range
:name (oref seq name)
:chart c)))
(while l
;;; Charting optimizers
-(defmethod chart-trim ((c chart) max)
+(cl-defmethod chart-trim ((c chart) max)
"Trim all sequences in chart C to be at most MAX elements long."
(let ((s (oref c sequences)))
(while s
(setq s (cdr s))))
)
-(defmethod chart-sort ((c chart) pred)
+(cl-defmethod chart-sort ((c chart) pred)
"Sort the data in chart C using predicate PRED.
See `chart-sort-matchlist' for more details."
(let* ((sl (oref c sequences))
(defun chart-sort-matchlist (namelst numlst pred)
"Sort NAMELST and NUMLST (both sequence objects) based on predicate PRED.
-PRED should be the equivalent of '<, except it must expect two
+PRED should be the equivalent of `<', except it must expect two
cons cells of the form (NAME . NUM). See `sort' for more details."
;; 1 - create 1 list of cons cells
(let ((newlist nil)
(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.
-Create it going in direction DIR ['horizontal 'vertical] with TITLE
+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 chart's max element display to MAX, and sort lists with
SORT-PRED if desired."
- (let ((nc (make-instance chart-bar
+ (let ((nc (make-instance 'chart-bar
:title title
:key-label "8-m" ; This is a text key pic
:direction dir
))
(iv (eq dir 'vertical)))
(chart-add-sequence nc
- (make-instance chart-sequece
+ (make-instance 'chart-sequece
:data namelst
:name nametitle)
(if iv 'x-axis 'y-axis))
(chart-add-sequence nc
- (make-instance chart-sequece
+ (make-instance 'chart-sequece
:data numlst
:name numtitle)
(if iv 'y-axis 'x-axis))