Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/sparql-results-html-chart.lisp

KindCoveredAll%
expression0180 0.0
branch012 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 ;;; solutions serialized in an html document as a d3+rickshaw graph.
6
 ;;; each data sequence is one statistics property
7
 
8
 ;;; no reading
9
 
10
 ;;; writing -  bindings only
11
 
12
 (defgeneric write-sparql-results+html+chart+rickshaw (results stream)
13
   (:documentation "Encode the result field to the stream as a table in an html document.
14
  The results are one solutions per 'tr' element, with each binding in a 'td'.
15
  The first element is a 'hr', which specifies the variable names.
16
  If a string is blank, empty td element appears.")
17
   
18
   (:method ((result symbol) (stream t))
19
     (error "Boolean results cannt be encoded as a graph."))
20
   
21
   (:method ((results cons) (stream t))
22
     ;; rewrite three dimensions - the topic / repository, temporal and data
23
     ;; determine the tmporal bounds
24
     ;; isolate per topoc relying on the original sorting
25
     ;; emit x,z sequences for each topic where the x is the relative univarlas time
26
     
27
     (let* ((dimensions (first results))
28
            (solutions (rest results))
29
            (count 0)
30
            (base-time (encode-universal-time 0 0 0 1 1 1970 0))
31
            )
32
       (flet ((x-position (date)
33
                (let ((ut (date-time-universal-time (spocq.e:date-time date))))
34
                  (- ut base-time)))
35
              (y-position (value)
36
                (float value))
37
              (dimension-color (dimension)
38
                (or (and (boundp dimension) (getf (symbol-value dimension) :color))
39
                    "palette.color()")))
40
         
41
         (flet ((write-head (stream)
42
                  (format stream "
43
 <link type='text/css' rel='stylesheet' href='/styles/rickshaw.min.css'>
44
 <script src='/scripts/d3.v2.js'></script> 
45
 <script src='/scripts/d3.layout.min.js'></script>
46
         <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'></script>
47
         <script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js'></script>
48
 <script src='/scripts/rickshaw.min.js'></script>"))
49
                (write-body (stream)
50
                  (format stream "
51
 <div id='chart_container'>
52
   <style type='text/css'>
53
    <!-- label { display: inline-block; width: 80px; text-align: right; }-->
54
   </style>
55
   <div style='display: inline-block; vertical-align: top; margin: 10px; border: solid gray 1px;'>")
56
                  (write-query-parameter-form stream (task-property *task* :query-parameters)
57
                                              :input nil)
58
                  (format stream "~%~4t<div id='legend' style='margin-top: 10px; background-color:silver;'></div>")
59
                  (format stream "
60
   </div>
61
   <div style='display: inline-block;  vertical-align: top; margin: 10px;'>
62
     <div id='y_axis' style='display: inline-block; width: 40px; vertical-align: top;'></div>
63
     <div id='chart' style='display: inline-block; vertical-align: top;'></div>
64
     <div id='slider'></div>
65
   </div>
66
 </div>
67
 
68
 <script>
69
 var palette = new Rickshaw.Color.Palette();
70
 var graph = new Rickshaw.Graph ( {
71
     element: document.querySelector('#chart'),
72
     renderer: 'scatterplot',
73
     width: 1024,
74
     height: 512,
75
     series: [")
76
                  (loop for i from 0
77
                        for name in (rest dimensions)
78
                        do (progn
79
                             ;; (format stream "~%{ color: '~a', name: '~a',  data: [" (dimension-color name) name)
80
                             (format stream "~%{ color: ~a, name: '~a',  data: [" (dimension-color name) name)
81
                             (loop for solution in solutions
82
                                   for date = (pop solution)
83
                                   for value = (nth i solution)
84
                                   for x from 0
85
                                   do (progn (when (and (plusp x) (zerop (mod x 10)))
86
                                               (format stream "~%~27T"))
87
                                             (format stream "{ x: ~d, y: ~d}, "
88
                                                     (x-position date) (y-position value))
89
                                             (incf count)))
90
                             (format stream " ] },")))
91
                  (format stream "] });
92
 var legend = new Rickshaw.Graph.Legend ( {
93
                element: document.querySelector('#legend'),
94
                graph: graph } );
95
 var shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
96
     graph: graph,
97
     legend: legend
98
 });
99
 /* mucks with he scatterplot style
100
 var slider = new Rickshaw.Graph.RangeSlider({
101
     graph: graph,
102
     element: document.querySelector('#slider')
103
 });*/
104
 var x_axis = new Rickshaw.Graph.Axis.Time( { graph: graph } );
105
 var y_axis = new Rickshaw.Graph.Axis.Y( {
106
         graph: graph,
107
         orientation: 'left',
108
         tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
109
         element: document.getElementById('y_axis'),
110
 } );
111
 graph.renderer.dotSize = 1;
112
 graph.render();
113
 </script>")))
114
           (setf solutions (sort solutions #'spocq.e:< :key #'first))
115
           (write-sparql-results-html stream :head #'write-head :body #'write-body)))
116
       (terpri stream)
117
       (incf-stat *statements-returned* count)))
118
   
119
   (:method ((results boolean-generator) (stream t))
120
     (error "Boolean results cannt be encoded as a graph."))
121
   
122
   (:method ((results solution-generator) (stream t))
123
     (let* ((dimensions (solution-generator-dimensions results))
124
            (channel (solution-generator-channel results))
125
            (variable-count (length dimensions)))
126
       (write-sparql-results+html+chart+rickshaw (cons dimensions
127
                                                    (let ((solutions nil))
128
                                                      (loop for page = (get-field-page channel)
129
                                                            until (null page)
130
                                                            do (if (= variable-count (array-dimension page 1))
131
                                                                 (let ((solution-count (array-dimension page 0)))
132
                                                                   (dotimes (page-index solution-count)
133
                                                                     (push (loop for value-index from 0 below variable-count
134
                                                                                 collect (let ((term-id (aref page page-index value-index)))
135
                                                                                           (unless (= term-id +null-term-id+)
136
                                                                                             (term-number-object term-id))))
137
                                                                           solutions)))
138
                                                                 (log-warn "field width mismatch: ~s : ~s."
139
                                                                           dimensions (array-dimension page 1))))
140
                                                      (nreverse solutions)))
141
                                              stream))))
142
 
143
 
144
 
145
 ;;;;;;;
146
 
147
 (defmethod send-response-message (operation (message-body t) (stream t)
148
                                             (content-type mime:application/VND.DYDRA.SPARQL-RESULTS+HTML+CHART+RICKSHAW))
149
   "Given a MESSAGE, and a STREAM with the application/sparql-results+html+chart CONTENT-TYPE,
150
  encode the results as a timeseries graph in which each variable is projected onto one polyline trace.
151
  The times are normalized to that of the first sample, the values are encoded as decimals."
152
 
153
   (when *encoding-trace-output*
154
     (setf stream (make-broadcast-stream *encoding-trace-output* stream)))
155
   (let ((*package* *spocq-reader-package*))
156
     (write-sparql-results+html+chart+rickshaw message-body stream)))
157
 
158
 (defmethod send-response-message (operation (message-body t) (stream t)
159
                                             (content-type mime:application/VND.DYDRA.SPARQL-RESULTS+HTML+CHART))
160
   "delegate to chart+rickshaw"
161
 
162
   (send-response-message operation message-body stream mime:application/VND.DYDRA.SPARQL-RESULTS+HTML+CHART+RICKSHAW))
163
 
164
 (defmethod send-response-message (operation (message-body t) (stream t)
165
                                             (content-type mime:application/VND.DYDRA.SPARQL-RESULTS+HTML+D3))
166
   "delegate to chart+rickshaw"
167
 
168
   (send-response-message operation message-body stream mime:application/VND.DYDRA.SPARQL-RESULTS+HTML+CHART+RICKSHAW))
169
 
170
 
171
 #|
172
 (let ((?::count '(:color "red"))
173
       (?::time '(:color "green"))
174
       (now (get-universal-time)))
175
   (declare (special ?::count ?::time))
176
   (send-response-message :test
177
                          `((?::date ?::count ?::time)
178
                            (,(universal-time-date-time now) 1 20)
179
                            (,(universal-time-date-time (+ now 1)) 2 21)
180
                            (,(universal-time-date-time (+ now 2)) 3 22))
181
                          *trace-output*
182
                          mime:application/sparql-results+html+chart))
183
 |#
184