From ca52717cab14caa70be5e0def071007fa712aab8 Mon Sep 17 00:00:00 2001 From: awb99 Date: Sun, 29 Sep 2024 11:27:19 -0500 Subject: [PATCH] pixi bar drawing working (somehow) --- demo/resources/ext/demo-rtable.edn | 1 + demo/resources/public/pixi1.html | 90 ++++++++++++++ demo/resources/public/pixi2.html | 101 ++++++++++++++++ demo/resources/public/pixi3.html | 108 +++++++++++++++++ demo/resources/public/pixi4.html | 126 +++++++++++++++++++ demo/resources/public/pixi5.html | 139 +++++++++++++++++++++ demo/resources/public/pixi6.html | 187 +++++++++++++++++++++++++++++ demo/src/demo/page/pixi.cljs | 42 +++++++ resources/ext/rtable-pixi.edn | 9 ++ src/deps.cljs | 10 +- src/rtable/data/pixi.cljs | 23 ++++ src/rtable/data/pixi/demo.cljs | 34 ++++++ src/rtable/data/pixi/scale.cljs | 33 +++++ src/rtable/render/pixi.cljs | 112 +++++++++++++++++ 14 files changed, 1008 insertions(+), 7 deletions(-) create mode 100644 demo/resources/public/pixi1.html create mode 100644 demo/resources/public/pixi2.html create mode 100644 demo/resources/public/pixi3.html create mode 100644 demo/resources/public/pixi4.html create mode 100644 demo/resources/public/pixi5.html create mode 100644 demo/resources/public/pixi6.html create mode 100644 demo/src/demo/page/pixi.cljs create mode 100644 resources/ext/rtable-pixi.edn create mode 100644 src/rtable/data/pixi.cljs create mode 100644 src/rtable/data/pixi/demo.cljs create mode 100644 src/rtable/data/pixi/scale.cljs create mode 100644 src/rtable/render/pixi.cljs diff --git a/demo/resources/ext/demo-rtable.edn b/demo/resources/ext/demo-rtable.edn index fb20a2f..74e5f14 100644 --- a/demo/resources/ext/demo-rtable.edn +++ b/demo/resources/ext/demo-rtable.edn @@ -23,6 +23,7 @@ "canvas-paint"demo.page.paint/page ; cheetah "cheetah" demo.page.cheetah/page + "pixi" demo.page.pixi/pixi-page } :sci-cljs-ns [demo.helper.ui diff --git a/demo/resources/public/pixi1.html b/demo/resources/public/pixi1.html new file mode 100644 index 0000000..b17d768 --- /dev/null +++ b/demo/resources/public/pixi1.html @@ -0,0 +1,90 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + diff --git a/demo/resources/public/pixi2.html b/demo/resources/public/pixi2.html new file mode 100644 index 0000000..24d3236 --- /dev/null +++ b/demo/resources/public/pixi2.html @@ -0,0 +1,101 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + +s \ No newline at end of file diff --git a/demo/resources/public/pixi3.html b/demo/resources/public/pixi3.html new file mode 100644 index 0000000..5d80753 --- /dev/null +++ b/demo/resources/public/pixi3.html @@ -0,0 +1,108 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + diff --git a/demo/resources/public/pixi4.html b/demo/resources/public/pixi4.html new file mode 100644 index 0000000..4373d1a --- /dev/null +++ b/demo/resources/public/pixi4.html @@ -0,0 +1,126 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + diff --git a/demo/resources/public/pixi5.html b/demo/resources/public/pixi5.html new file mode 100644 index 0000000..adb175e --- /dev/null +++ b/demo/resources/public/pixi5.html @@ -0,0 +1,139 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + diff --git a/demo/resources/public/pixi6.html b/demo/resources/public/pixi6.html new file mode 100644 index 0000000..e42fcb8 --- /dev/null +++ b/demo/resources/public/pixi6.html @@ -0,0 +1,187 @@ + + + + + + Stock Price History with Pixi.js + + + + + + + diff --git a/demo/src/demo/page/pixi.cljs b/demo/src/demo/page/pixi.cljs new file mode 100644 index 0000000..6f647c1 --- /dev/null +++ b/demo/src/demo/page/pixi.cljs @@ -0,0 +1,42 @@ +(ns demo.page.pixi + (:require + [tech.v3.dataset :as tmlds] + [rtable.render.pixi :refer [pixi pixi-ds]] + [demo.helper.ui :refer [link-href link-dispatch sample-selector]])) + + +(def ds + (tmlds/->dataset + {:open [3 4 5 3 4 5 6 7 8 12 5 9] + :high [6 6 6 7 6 7 8 9 10 14 6 10] + :low [3 4 5 3 4 5 6 7 8 12 5 9] + :close [3 4 5 3 4 5 6 7 8 12 5 9]})) + +(defn pixi-page [{:keys [route-params query-params handler] :as route}] + [:div {:class "h-screen w-screen"} ; .grid.grid-cols-2 + [link-href "/" "main"] + ;; new version that provides :style and :class + [:p.bg-red-500.p-3 "rtable.render.pixi"] + [sample-selector + {:test-dataset + [pixi {:style {:width "1000px" + :height "500px"} + :data ds}] + :big-datasset + [pixi-ds {:style {:width "1200px" + :height "800px" + :border "3px solid green"} + :class "bg-red-500" + :charts [{;:bar :candlestick ; :ohlc + :close {:type :line} + :atr-band-mid {:type :point :color "orange"} + :atr-band-lower {:type :line :color "black"} + :atr-band-upper {:type :line :color "black"}} + {:volume :column} + {:low :column}] + :url "/r/bars-1m-full.transit-json"}] + + + + ; + }]]) \ No newline at end of file diff --git a/resources/ext/rtable-pixi.edn b/resources/ext/rtable-pixi.edn new file mode 100644 index 0000000..237de27 --- /dev/null +++ b/resources/ext/rtable-pixi.edn @@ -0,0 +1,9 @@ +{:name "rtable-pixi" + ;build + :lazy true + :depends-on #{:techml-dataset-cljs} + :cljs-namespace [rtable.render.pixi] + :cljs-ns-bindings {'rtable.render.pixi {'pixi rtable.render.pixi/pixi + 'pixi-ds rtable.render.pixi/pixi-ds}} + ; + } diff --git a/src/deps.cljs b/src/deps.cljs index 8742628..43db276 100644 --- a/src/deps.cljs +++ b/src/deps.cljs @@ -2,16 +2,12 @@ {; shadow cljs creates package.json ; based on this dependencies - ; ag grid + ; grids "ag-grid-community" "^25.2.0" "ag-grid-react" "^25.2.0" - - ; cheetah grid "cheetah-grid" "^1.15.0" - - ; highcharts - ;"highcharts" "^11.4.0" + ; charts "highcharts" "^11.4.8" - + "pixi.js" "^8.4.1" ; }} diff --git a/src/rtable/data/pixi.cljs b/src/rtable/data/pixi.cljs new file mode 100644 index 0000000..37535f8 --- /dev/null +++ b/src/rtable/data/pixi.cljs @@ -0,0 +1,23 @@ +(ns rtable.data.pixi + (:require + [clojure.set] + [tick.core :as t] + [promesa.core :as p] + [tech.v3.dataset :as tmlds] + [rtable.data :refer [load-and-transform2 load-dataset]] + )) + +(defn add-epoch [ds] + (tmlds/column-map ds :epoch #(-> % t/instant t/long) [:date])) + +(defn debug-template [template-js] + (set! (.-HHH js/window) template-js)) + +(defmethod load-and-transform2 :pixi [{:keys [url] + :as opts}] + (let [ds-p (load-dataset url)] + (p/then ds-p (fn [ds] + (let [ds (add-epoch ds)] + (-> opts + (dissoc :url) + (assoc :data ds))))))) diff --git a/src/rtable/data/pixi/demo.cljs b/src/rtable/data/pixi/demo.cljs new file mode 100644 index 0000000..e5952e3 --- /dev/null +++ b/src/rtable/data/pixi/demo.cljs @@ -0,0 +1,34 @@ +(ns rtable.data.pixi.demo + (:require + ["pixi.js" :as pixi :refer [Container Graphics Text]])) + + +(defn add-range-text [stage] + (let [text (Text. (clj->js {:text "range-pos" + ;:style {:fill "white" :fontSize 16} + }))] + (set! (.-x text) 50) + (set! (.-y text) 10) + (.addChild stage text))) + + +(defn add-graphics [stage] + (let [graphics (Graphics.)] + ; Rectangle 2 + (.rect graphics 530 50 140 100) + (.fill graphics (clj->js {:color 0xaa4f08})); + (.stroke graphics (clj->js {:width 2 :color 0xffffff})) + + ;Circle + (.circle graphics 100, 250, 50) + (.fill graphics (clj->js {:color 0xde3249 :alpha 1})) + + + (.circle graphics 350, 340, 50) + (.fill graphics (clj->js {:color 0xaa4f08})); + + (.stroke graphics (clj->js {:width 2 :color 0xaa4f08})) + (.moveTo graphics 200 200) + (.lineTo graphics 200 300) + (.lineTo graphics 300 300) + (.addChild stage graphics))) diff --git a/src/rtable/data/pixi/scale.cljs b/src/rtable/data/pixi/scale.cljs new file mode 100644 index 0000000..ea42df5 --- /dev/null +++ b/src/rtable/data/pixi/scale.cljs @@ -0,0 +1,33 @@ +(ns rtable.data.pixi.scale + (:require + [tech.v3.dataset :as tmlds] + [ham-fisted.api :as hamf])) + +(defn true-max + [v] + (->> (hamf/apply-nan-strategy nil v) + (hamf/mmax-key identity))) + +(defn true-min + [v] + (->> (hamf/apply-nan-strategy nil v) + (hamf/mmin-key identity))) + + +(defn scale-bars [ds] + (let [ds (tmlds/select-rows ds (range 200)) + max-price (true-max (:high ds)) + min-price (true-min (:low ds)) + range-price (- max-price min-price) + height 400 + dheight (double height) + scale (fn [p] + (long (* (- 1.0 (/ (- p min-price) range-price)) dheight)))] + ; max-price -> 1 + ; min-price -> 0 -> range -> height + ; (1 - ((p - min-price) / range) ) + (-> ds + (tmlds/column-map :open scale [:open]) + (tmlds/column-map :high scale [:high]) + (tmlds/column-map :low scale [:low]) + (tmlds/column-map :close scale [:close])))) \ No newline at end of file diff --git a/src/rtable/render/pixi.cljs b/src/rtable/render/pixi.cljs new file mode 100644 index 0000000..1187b9c --- /dev/null +++ b/src/rtable/render/pixi.cljs @@ -0,0 +1,112 @@ +(ns rtable.render.pixi + (:require + [taoensso.timbre :refer-macros [info warn error]] + [reagent.core :as reagent] + [promesa.core :as p] + [reagent.dom] + [tech.v3.dataset :as tmlds] + ["pixi.js" :as pixi :refer [Application Container Graphics Text]] + [rtable.data.pixi] ; side effects + [rtable.data :as d] + [rtable.data.pixi.scale :refer [scale-bars]] + [rtable.data.pixi.demo :refer [add-graphics]] + )) + +(defn pixi-app [node ds] + (let [app (Application.) + app-p (.init app (clj->js {:width 800 + :height 400 + :background "#1099bb"}))] + (p/then + app-p + (fn [r] + (let [canvas (.-canvas app) + stage (.-stage app) + container (Container.)] + (.appendChild node canvas) + [stage container]))))) + + +(defn add-bar [graphics idx row] + (let [{:keys [high low]} row + bar-width 8 + x (+ (* idx bar-width) (/ bar-width 2)) + height (abs (- high low)) + ] + ;(.moveTo graphics x high) + ;(.lineTo graphics x low) + (.stroke graphics (clj->js {:width 2 :color 0xffffff})) + (.fill graphics (clj->js {:color 0xaa4f08})); + + ; (.rect graphics 530 50 140 100) + (println "adding bar x: " x " y: " low " width: " bar-width " height: " height) + (.rect graphics + x low + bar-width + height) + (.fill graphics (clj->js {:color 0xaa4f08})); + (.stroke graphics (clj->js {:width 2 :color 0xffffff})))) + + + +(defn draw-bars [container ds] + (let [ds (scale-bars ds) + rows (tmlds/rows ds) + graphics (Graphics.)] + (println "scaled ds:") + (println ds) + (println "container: " container) + + (doall (map-indexed (partial add-bar graphics) rows)) + (.addChild container graphics) + (println "draw-bars done."))) + + +(defn pixi-render [container ds] + (draw-bars container ds) + (println "pixi-render done.") + nil) + + +(defn pixi-impl + [{:keys [style class data] + :or {style {} + class ""}}] + ; https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md + (let [container-a (atom nil)] + (reagent/create-class + {:display-name "pixi-reagent" + :reagent-render (fn [{:keys [style class data] + :or {style {} + class ""}}] ;; remember to repeat parameters + [:div {:style style + :class class}]) + :component-did-mount (fn [this] ; oldprops oldstate snapshot + ;(println "c-d-m: " this) + ;(info (str "jsrender init data: " data)) + (let [c-p (pixi-app (reagent.dom/dom-node this) data)] + (p/then c-p + (fn [[stage container]] + (reset! container-a container) + ;(add-range-text stage) + (add-graphics stage) + ;(pixi-render container data) + (pixi-render stage data) + (.addChild stage container))) + + nil)) + :component-did-update (fn [this old-argv] + (let [new-argv (rest (reagent/argv this)) + [arg1] new-argv + {:keys [data]} arg1 + container @container-a] + ;(println "component did update: " this "argv: " new-argv) + ;(pixi-render container data) + nil))}))) + +(defn pixi + [opts] + [pixi-impl opts]) + +(defn pixi-ds [opts] + [d/loading-ui opts :pixi pixi]) \ No newline at end of file