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)))) |