diff --git a/README.md b/README.md index 6e19d7a..ffe7d64 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,51 @@ -Need to plot some data from Common Lisp? This will solve your problem -by making a pretty plot in your web browser, effectively using that -browser as a display for your chart. It uses a cute Javascript -plotting widget known as flot. But it can do much more; you can push -arbitrary content to a webpage, and by using other Javascript widgets -lots of other things are possible; including maps, rich text editors, -syntax highlighting, etc. etc. +`plot-window` provides Javascript code and content push capability to a web browser using websockets. `plot-window` goes a step further by providing tooling for using and interacting with Javascript and Javascript libraries. Javscript interaction is done usin parenscript providing a holistic interaction between Lisp and the browser. + + Examples have been provided for working with the following libraries: + * flot - Plotting + * d3js - Plotting + * mapstraction - Openstreet Maps Mapping + * nice-edit - Rich text editor + * syntax-highlighter - Syntax highlighting + +Getting Started +--------------- First: clone this repository (to ~/.quicklisp/local-projects for example), -then having assured that ASDF can find it (say by resetting ASDF's source respository -(asdf:clear-source-registry)), and then load and run the application as so: +then having assured that ASDF can find it (say by resetting ASDF's source respository `(asdf:clear-source-registry)`) + +`plot-window` requires version 0.2.5 of cl-interpol. Until the Quicklisp pull from the cl-interpol upstream, you will need to clone cl-interpol from it's github repository https://github.com/edicl/cl-interpol.git. +``` +git clone https://github.com/edicl/cl-interpol.git +``` + +The plot-window can be loaded and ran as so: ```common-lisp > (ql:quickload "plot-window") -> (cl-user:initialize-application) +> (in-package :pw) +> (pw:initialize-application) ``` Second: Visit http://localhost:8765/ in a quality web browser. I've only tried chrome. The resulting page becomes your REPL's display window. -Third: Load up an example, in this case a plot widget: `(ql:quickload "plot-window-flot")` - +Third: Load up an example, in this case a plot widget: ```common-lisp -> (pw:plot (loop for i below 50 collect (list i (random 20)))) +> (ql:quickload "plot-window-flot")` +> (flot-example-1) +> (plot (loop for i below 50 collect (list i (random 20)))) ``` -You can clear the window with `(ps:clear-display-window)`, and you can add single elements to the page using `(ps:add-element "

Hi there

")` +You can clear the window with `(clear-display-window)`, and you can add single elements to the page using `(pw:add-element "

Hi there

")` A number of examples are in the example's subdirectory. Each of these has it's on asd. You may load them all via `(ql:quickload "plot-window-examples")`. And once they are all loaded you can run a little demo: `(ql:demo t)` +Generated Javascript modules are stored in the static directory this location set with the parameter `*where-to-store-js-module-files*`. It is set by default to the ASDF system relative path of `plot-window`. + Magic ----- The chart is drawn by [flot](http://www.flotcharts.org/), a javascript -library. The page is rendered via Hunchentoot. The dynamic updating +library. The page is rendered via -Hunchentoot. The dynamic updating is done via websockets (with the help of [clws](http://www.cliki.net/clws)). A tangle of javascript glues it all together, and that's implemented using parenscript. Various diff --git a/main.lisp b/main.lisp index 51aa36e..6d0f9c5 100644 --- a/main.lisp +++ b/main.lisp @@ -2,7 +2,7 @@ ;;;; Starting our Servers -(defun cl-user::initialize-application (&key (port 8765)) +(defun initialize-application (&key (port 8765)) (start-web-server :port port) (start-clws-server) (start-and-register-json-rpc-resource)) diff --git a/packages.lisp b/packages.lisp index f7b666f..c3c8fd8 100644 --- a/packages.lisp +++ b/packages.lisp @@ -15,7 +15,7 @@ #:make-css-var #:pt #:px) (:nicknames "PW") (:export - ;; also cl-user:initalize-application + #:initialize-application #:plot)) (unless (named-readtables:find-readtable :cl-interpol) diff --git a/ps-modules.lisp b/ps-modules.lisp index 2d409ae..8ef29be 100644 --- a/ps-modules.lisp +++ b/ps-modules.lisp @@ -183,7 +183,7 @@ ;;;; -(defparameter *where-to-store-js-module-files* "/Users/bhyde/w/plot-window/static/") +(defparameter *where-to-store-js-module-files* (namestring (asdf:system-relative-pathname 'plot-window "static/"))) (defgeneric update-js-module-file-if-necessary (m) (:documentation "Compile time hook which provides an oportunity to regenerate the javascript file.")) diff --git a/ps-utilities.lisp b/ps-utilities.lisp index 84702cb..a755bba 100644 --- a/ps-utilities.lisp +++ b/ps-utilities.lisp @@ -83,7 +83,7 @@ body after the given number of milliseconds." "Avoid the need to use a unique read table." (assert (stringp str)) (with-input-from-string (s str) - (cl-interpol::interpol-reader s #\? nil))) + (cl-interpol:interpol-reader s #\? nil :recursive-p nil))) (defmacro interpolate (str) (interp% str)) diff --git a/servers.lisp b/servers.lisp index dc365f8..ed78390 100644 --- a/servers.lisp +++ b/servers.lisp @@ -81,8 +81,8 @@ ;;;; JSON messaging over that web socket. -(defvar *current-websocket-client*) -(defvar *last-websocket-client*) +(defvar *current-websocket-client* nil) +(defvar *last-websocket-client* nil) (defvar *json-rcp-handlers* (make-hash-table :test #'equalp)) (defmacro define-json-message-handler (name (&rest parameters) &body body)