Namespaces that uses the Nashorn javascript engine to invoke some shared javascript code that we use to determine the background color of pulse table cells | (ns metabase.channel.render.js.color (:require [clojure.java.io :as io] [metabase.channel.render.js.engine :as js.engine] [metabase.formatter] [metabase.util.i18n :refer [trs]] [metabase.util.json :as json] [metabase.util.malli :as mu]) (:import (metabase.formatter NumericWrapper))) |
(set! *warn-on-reflection* true) | |
(def ^:private js-file-path "frontend_shared/color_selector.js") | |
(def ^:private ^{:arglists '([])} js-engine ;; As of 2024/05/13, a single color selector js engine takes 3.5 MiB of memory (js.engine/threadlocal-fifo-memoizer (fn [] (let [file-url (io/resource js-file-path)] (assert file-url (trs "Can''t find JS color selector at ''{0}''" js-file-path)) (doto (js.engine/context) (js.engine/load-resource js-file-path)))) 5)) | |
This is a pretty loose schema, more as a safety net as we have a long feedback loop for this being broken as it's
being handed to the JS color picking code. Currently it just needs column names from | (def ^:private QueryResults [:map [:cols [:sequential [:map [:name :string]]]] [:rows [:sequential [:sequential :any]]]]) |
Returns a curried javascript function (object) that can be used with | (mu/defn make-color-selector [{:keys [cols rows]} :- QueryResults viz-settings] ;; Ideally we'd convert everything to JS data before invoking the function below, but converting rows would be ;; expensive. The JS code is written to deal with `rows` in it's native Nashorn format but since `cols` and ;; `viz-settings` are small, pass those as JSON so that they can be deserialized to pure JS objects once in JS ;; code (js.engine/execute-fn-name (js-engine) "makeCellBackgroundGetter" rows (json/encode cols) (json/encode viz-settings))) |
Get the correct color for a cell in a pulse table. Returns color as string suitable for use CSS, e.g. a hex string or
| (defn get-background-color ^String [color-selector cell-value column-name row-index] (let [cell-value (if (instance? NumericWrapper cell-value) (:num-value cell-value) cell-value)] (.asString (js.engine/execute-fn color-selector cell-value row-index column-name)))) |