<commit_before>(ns om-data-vis.widget
  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
  (:require [om.core :as om  :include-macros true]
            [cljs.core.async :as async :refer [<! chan put! sliding-buffer close!]]
            [sablono.core :as html :refer-macros [html]]
            [goog.events :as events]))

(defn by-id [id]
  (.getElementById js/document id))

(defn handle-drag-event [cursor owner evt-type e]
  (when (= evt-type :down)
    (om/set-state! owner :pressed true))
  (when (= evt-type :up)
    (om/set-state! owner :pressed false))
  (when (and (= evt-type :move) (om/get-state owner :pressed))
    (om/update! cursor :position {:top (.-clientY e) :left (.-clientX e)})))


(defn draggable [cursor owner {:keys [build-fn id]}]
  (reify
    om/IInitState
    (init-state [_]
      {:mouse-chan (chan (sliding-buffer 1000))
       :pressed false})
    om/IWillMount
    (will-mount [_]
      (let [mouse-chan (om/get-state owner :mouse-chan)]
        (go-loop []
          (let [[evt-type e] (<! mouse-chan)]
            (handle-drag-event cursor owner evt-type e))
          (recur))))
    om/IDidMount
    (did-mount [_]
      (let [node       (by-id id)
            mouse-chan (om/get-state owner :mouse-chan)]
        (events/listen node "mousemove" #(put! mouse-chan [:move %]))
        (events/listen node "mousedown" #(put! mouse-chan [:down %]))
        (events/listen node "mouseup" #(put! mouse-chan [:up %]))))
    om/IRenderState
    (render-state [_ {:keys [mouse-chan]}]
      (html
       (let [{:keys [top left]} (:position cursor)]
         [:div {:id id
                :style {:top (str (- top 40) "px") :left (str (- left 40) "px")
                        :position "absolute" :z-index 100}}
          build-fn])))))<commit_msg>Preserve mouse position relative to the element<commit_after>(ns om-data-vis.widget
  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
  (:require [om.core :as om  :include-macros true]
            [cljs.core.async :as async :refer [<! chan put! sliding-buffer close!]]
            [sablono.core :as html :refer-macros [html]]
            [goog.events :as events]))

(defn by-id [id]
  (.getElementById js/document id))

(defn handle-drag-event [cursor owner evt-type e]
  (when (= evt-type :down)
    (om/set-state! owner :mouse {:offset-top (.-offsetY e)
                                 :offset-left (.-offsetX e)
                                 :pressed true}))
  (when (= evt-type :up)
    (om/set-state! owner [:mouse :pressed] false))
  (when (and (= evt-type :move) (om/get-state owner [:mouse :pressed]))
    (let [{:keys [offset-top offset-left]} (om/get-state owner :mouse)]
      (om/update! cursor :position {:top (- (.-clientY e) offset-top)
                                    :left (- (.-clientX e) offset-left)}))))

(defn draggable [cursor owner {:keys [build-fn id]}]
  (reify
    om/IInitState
    (init-state [_]
      {:mouse-chan (chan (sliding-buffer 1000))
       :mouse {:offset-top 0 :offset-left 0 :pressed false}})
    om/IWillMount
    (will-mount [_]
      (let [mouse-chan (om/get-state owner :mouse-chan)]
        (go-loop []
          (let [[evt-type e] (<! mouse-chan)]
            (handle-drag-event cursor owner evt-type e))
          (recur))))
    om/IDidMount
    (did-mount [_]
      (let [node       (by-id id)
            mouse-chan (om/get-state owner :mouse-chan)]
        (events/listen node "mousemove" #(put! mouse-chan [:move %]))
        (events/listen node "mousedown" #(put! mouse-chan [:down %]))
        (events/listen node "mouseup" #(put! mouse-chan [:up %]))))
    om/IRenderState
    (render-state [_ {:keys [mouse-chan]}]
      (html
       (let [{:keys [top left]} (:position cursor)]
         [:div {:id id
                :style {:top (str top "px") :left (str left "px")
                        :position "absolute" :z-index 100}}
          build-fn])))))
{'fraction_non_alphanumeric': 0.1729150726855394, 'fraction_numerical': 0.00510073960724305, 'mean_word_length': 2.254771784232365, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6793434', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1312, 'n_words': 352}