                              :request-t request-t
                              :response-t (time/now)}
                             query-range)))))
-
-(defn range-ending-at-current-window [ end-t ]
-  (range-ending-at end-t (parse-query-window @query-window)))
-
-(defn series-data-channel [ series-name query-range-channel ]
-  (let [channel (chan)]
-    (go-loop []
-      (when-let [ query-range  (<! query-range-channel)]
-        (fetch-series-data series-name query-range #(put! channel %))
-        (recur)))
-    channel))
-
-(defn subscribe-plot-data [ series series-state ]
-  (let [update-out-chan (chan)
-        channel (series-data-channel series update-out-chan) ]
-    (sub update-pub :range update-out-chan)    
-    (go-loop []
-      (when-let [ data (<! channel) ]
-        (swap! series-state assoc :series-data data)
-        (recur)))))
 
 (defn series-tsplot-view [ series series-data series-range ]
   (let [dom-node (reagent/atom nil)]

  (ajax-get "/series-names" then))

(defn fetch-series-data [ series-name query-range then ]
  (let [ request-t (time/now) ]
    (ajax-get (str "/data/" series-name) query-range
              #(then (merge {:series-data %

                    {:width (.-clientWidth node)
                     :height (.-clientHeight node)})]])})))

(defn range-ending-at-current-window [ end-t ]
  (range-ending-at end-t (parse-query-window @query-window)))

(defn subscribe-plot-data [ series-name series-state-atom ]
  (let [control-channel (chan)]
    (go-loop [ last-query-range nil ]
      (when-let [ query-range (<! control-channel) ]
        (when (not (= query-range last-query-range))
          (swap! series-state-atom assoc :series-data
                 (<! (<<< fetch-series-data series-name query-range))))
        (recur query-range)))
    control-channel))

(defn series-tsplot [ series-name ]
  (let [dom-node (reagent/atom nil)
        series-state (reagent/atom {})
        series-data-loop (reagent/atom nil)]
    (reagent/create-class
     {:display-name (str "series-tsplot-" series-name)

      :component-did-mount
      (fn [ this ]
        (reset! series-data-loop (subscribe-plot-data series-name series-state))
        (put! @series-data-loop (range-ending-at-current-window @current-time)))

      :component-will-update
      (fn [ this new-argv ]
        (when @series-data-loop
          (put! @series-data-loop (range-ending-at-current-window @current-time))))
      
      :reagent-render
      (fn [ & rest ]
        [series-tsplot-view series-name (:series-data @series-state)
         (range-ending-at-current-window @current-time)])})))

(defn- remove-series [ series-name ]
  (swap! dashboard-state merge
