Skip to content

Commit

Permalink
WIP: draw main histogram.
Browse files Browse the repository at this point in the history
  • Loading branch information
lynaghk committed Aug 18, 2012
1 parent c9c54c9 commit c3201fc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 86 deletions.
149 changes: 68 additions & 81 deletions src/cljs/vcfvis/histogram.cljs
@@ -1,7 +1,6 @@
(ns vcfvis.histogram
(:use-macros [c2.util :only [pp p bind!]]
[reflex.macros :only [computed-observable constrain!]]
[clojure.core.match.js :only [match]])
[reflex.macros :only [constrain!]])
(:use [c2.core :only [unify]]
[c2.maths :only [irange extent]])
(:require [vcfvis.core :as core]
Expand All @@ -16,104 +15,92 @@

(def margin "left/right margin" 20)
(def inter-hist-margin "vertical margin between stacked histograms" 20)
(def axis-height 20)
(def axis-height (js/parseFloat (dom/style "#hist-axis" :height)))

(def height
"height available to histogram facet grid"
(js/parseFloat (dom/style "#histograms" :height)))

(def width
"Width of histogram facet grid"
(js/parseFloat (dom/style "#histograms" :width)))


(def !selected-extent (atom [0 1]))
;;Range selector
(let [$tt (-> (dom/select "#range-selector")
(dom/style :width width))
tt (double-range/init! $tt #(reset! !selected-extent %))]

(constrain!
(dom/style $tt :visibility
(if (seq @core/!vcfs) "visible" "hidden")))

;;possible todo: use pubsub bus rather than side-effecting fn.
(defn update-range-selector! [[min max] bin-width]
(doto tt
(.setMinimum min) (.setMaximum max)
(.setStep bin-width) (.setMinExtent bin-width) (.setBlockIncrement bin-width)
(.setValueAndExtent min (- max min)))))

(constrain!
(let [{:keys [bin-width range]} @core/!metric]
(update-range-selector! range bin-width)))

;;Whenever the range sliders move, we're looking at a new subset of the data, so reset the buttons
(add-watch !selected-extent :reset-analysis-status-buttons
(fn [_ _ _ _] (data/reset-statuses!)))


(defn histograms* [vcfs x-scale]
(let [metric-id (@core/!metric :id)
metrics (map #(core/vcf-metric % metric-id) vcfs)
max-val (apply max (flatten (map :vals metrics)))
height (- (/ (- height axis-height) (count vcfs))
inter-hist-margin)
y (scale/linear :domain [0 max-val]
:range [0 height])
;;The bin width is the same for a given metric across all samples
bin-width (:bin-width (core/vcf-metric (first vcfs) metric-id))
dx (- (x-scale bin-width) (x-scale 0))]

[:div.span12
(unify vcfs
(fn [vcf]
[:div.histogram
[:span.label (vcf :filename)]
(case (get @data/!analysis-status (vcf :filename))
:completed [:button.btn {:properties {:disabled true}} "Completed"]
:running [:button.btn {:properties {:disabled true}} "Running..."]
nil [:button.btn {:properties {:disabled false}} "Export subset"])
[:svg {:width (+ width (* 2 margin)) :height (+ height inter-hist-margin)}
[:g {:transform (svg/translate [margin margin])}
[:g.distribution {:transform (str (svg/translate [0 height])
(svg/scale [1 -1]))}
(map-indexed (fn [idx v]
[:rect {:x (* dx idx) :width dx
:height (y v)}])
((core/vcf-metric vcf metric-id) :vals))]]]])
:force-update? true)]))


#_(bind! "#histograms"
(- (js/parseFloat (dom/style "#histograms" :width))
(* 2 margin)))


;; (def !selected-extent (atom [0 1]))
;; ;;Range selector
;; (let [$tt (-> (dom/select "#range-selector")
;; (dom/style :width width))
;; tt (double-range/init! $tt #(reset! !selected-extent %))]

;; (constrain!
;; (dom/style $tt :visibility
;; (if (seq @core/!vcfs) "visible" "hidden")))

;; ;;possible todo: use pubsub bus rather than side-effecting fn.
;; (defn update-range-selector! [[min max] bin-width]
;; (doto tt
;; (.setMinimum min) (.setMaximum max)
;; (.setStep bin-width) (.setMinExtent bin-width) (.setBlockIncrement bin-width)
;; (.setValueAndExtent min (- max min)))))

;; (constrain!
;; (let [{:keys [bin-width range]} @core/!metric]
;; (update-range-selector! range bin-width)))

;; ;;Whenever the range sliders move, we're looking at a new subset of the data, so reset the buttons
;; (add-watch !selected-extent :reset-analysis-status-buttons
;; (fn [_ _ _ _] (data/reset-statuses!)))




(defn histogram* [vcf scale-x metric]
(let [height (- height axis-height)
{:keys [dimension binned bin-width]} (get-in vcf [:cf (metric :id)])
scale-y (scale/linear :domain [0 (aget (first (.top binned 1)) "value")]
:range [0 height])
dx (- (scale-x bin-width) (scale-x 0))]

[:div.histogram
[:span.label (vcf :file-url)]

[:svg {:width (+ width (* 2 margin)) :height (+ height inter-hist-margin)}
[:g {:transform (svg/translate [margin margin])}
[:g.distribution {:transform (str (svg/translate [0 height])
(svg/scale [1 -1]))}
(for [d (.all binned)]
(let [x (aget d "key"), count (aget d "value")]
[:rect.bar {:x (scale-x x)
:width (- (scale-x (+ x bin-width))
(scale-x x))
:height (scale-y count)}]))]]]]))




(bind! "#main-hist"
(let [vcfs @core/!vcfs]
(if (seq vcfs)
(let [metric (core/vcf-metric (first vcfs)
(@core/!metric :id))
(let [metric @core/!metric
metric-extent (metric :range)
{:keys [ticks]} (ticks/search metric-extent
:clamp? true :length width)
x (scale/linear :domain metric-extent
:range [0 width])]
[:div#main-hist
[:div#histograms

[:div#histograms

;;histogram distributions
(histograms* vcfs x)
;;histogram distributions
(histogram* (first vcfs) x metric)]

;;x-axis
[:div.span12
[:div#hist-axis
[:div.axis.abscissa
[:svg {:width (+ width (* 2 margin)) :height axis-height}
[:g {:transform (svg/translate [margin 2])}
(svg/axis x ticks :orientation :bottom
:formatter (partial gstr/format "%.1f"))]]]]])
;;If no VCFs, clear everything
[:div#histograms])))

(event/on "#histograms" "button" :click
(fn [{:keys [filename]}]
(let [metric-id (name (@core/!metric :id))]
(data/filter-analysis
{:file-url filename
:metrics {metric-id @!selected-extent}}))))
[:div#main-hist
[:div#histograms]
[:div#hist-axis]])))
6 changes: 4 additions & 2 deletions src/cljs/vcfvis/main.cljs
Expand Up @@ -8,8 +8,10 @@

(add-watch controls/file-selector :load-metrics
(fn [files]
(doseq [f files]
(data/load-vcf f (partial swap! core/!vcfs conj)))))
(if (seq files)
(doseq [f files]
(data/load-vcf f (partial swap! core/!vcfs conj)))
(reset! core/!vcfs []))))

;;Request file list from server
(data/load-context (partial reset! core/!context))
9 changes: 6 additions & 3 deletions src/haml/index.haml
Expand Up @@ -29,10 +29,13 @@
.container

%section
#histograms
#range-selector
.row
.span12
#main-hist
#histograms
#hist-axis
#range-selector

%section
.row.controls
.span8
.well
Expand Down
3 changes: 3 additions & 0 deletions src/sass/_histogram.sass
Expand Up @@ -3,6 +3,9 @@
#histograms
width: 100%
height: 400px

#hist-axis
height: 30px
.histogram
box-sizing: border-box
border: 1px solid black
Expand Down

0 comments on commit c3201fc

Please sign in to comment.