Skip to content

Commit 005a55b

Browse files
committed
aog wip
1 parent 3153c36 commit 005a55b

File tree

1 file changed

+35
-35
lines changed

1 file changed

+35
-35
lines changed

src/data_visualization/aog_in_clojure_part1.clj

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@
537537
;;
538538
;; **Why compute transforms ourselves?**
539539

540-
;; 1. Consistency - We want the isualizations to match the
540+
;; 1. Consistency - We want the visualizations to match the
541541
;; statistical computations of our Clojure libraries.
542542
;; 2. Efficiency - Especially with browser-based rendering targets,
543543
;; what we wish to pass to the target is summaries (say, 20 histogram bars)
@@ -775,15 +775,17 @@
775775
[:or Layer [:vector Layer]])
776776

777777
(def PlotSpec
778-
"Schema for a complete plot specification.
778+
"Schema for a plot specification (complete or partial).
779779
780-
A plot spec is a map containing:
781-
- Layers: Vector of layer maps
780+
A plot spec is a map that can contain:
781+
- Layers: Vector of layer maps (optional - allows partial specs)
782782
- Plot-level properties: target, width, height
783-
- Plot-level scales (optional)"
783+
- Plot-level scales (optional)
784+
785+
All fields are optional to support composition via =* and =+."
784786
[:map
785-
;; Layers (required)
786-
[:=layers [:vector Layer]]
787+
;; Layers (optional - allows partial specs with just plot-level properties)
788+
[:=layers {:optional true} [:vector Layer]]
787789

788790
;; Plot-level properties (all optional)
789791
[:=target {:optional true} Backend]
@@ -947,15 +949,15 @@
947949
(defn- plot-spec?
948950
"Check if x is a plot spec (map with :=layers or plot-level keys).
949951
950-
Plot specs are maps that can have:
951-
- :=layers key with vector of layer maps
952-
- Plot-level :=... keys like :=target, :=width, :=height"
952+
Plot specs are maps that have at least one key starting with :=
953+
Uses Malli validation as a fallback check for well-formed specs."
953954
[x]
954955
(and (map? x)
955-
(or (contains? x :=layers)
956-
;; Has plot-level keys
957-
(some #(-> % name first (= \=))
958-
(keys x)))))
956+
;; Has at least one := key
957+
(some #(-> % name first (= \=))
958+
(keys x))
959+
;; Validates against PlotSpec schema (additional safety check)
960+
(valid? PlotSpec x)))
959961

960962
;; ### ⚙️ Renderer
961963

@@ -1100,14 +1102,12 @@
11001102
(reduce =* (=* x y) more))))
11011103

11021104
;; Test helper: check if result is a valid layer vector
1103-
(defn- valid-layers? [x]
1104-
(and (vector? x)
1105-
(seq x)
1106-
(every? map? x)
1107-
(every? #(some (fn [[k _]]
1108-
(-> k name first (= \=)))
1109-
%)
1110-
x)))
1105+
(defn- valid-layers?
1106+
"Check if x is a valid vector of layers using Malli validation.
1107+
1108+
Note: This specifically checks for a vector of layers, not a single layer."
1109+
[x]
1110+
(valid? [:vector Layer] x))
11111111

11121112
(defn =+
11131113
"Combine multiple plot specifications for overlay (sum).
@@ -2765,19 +2765,19 @@ iris
27652765

27662766
;; Apply linear regression transform to points.
27672767
;;
2768-
;; Handles both single and grouped regression based on :group key in points.
2768+
;; Handles both single and grouped regression based on `:group` key in points.
27692769
;;
27702770
;; Args:
2771-
;; - layer: Layer map containing transformation specification
2772-
;; - points: Sequence of point maps with :x, :y, and optional :group keys
2771+
;; - `layer`: Layer map containing transformation specification
2772+
;; - `points`: Sequence of point maps with `:x`, `:y`, and optional `:group` keys
27732773
;;
27742774
;; Returns:
2775-
;; - For ungrouped: {:type :regression :points points :fitted [p1 p2]}
2776-
;; - For grouped: {:type :grouped-regression :points points :groups {group-val {:fitted [...] :points [...]}}}
2775+
;; - For ungrouped: `{:type :regression :points points :fitted [p1 p2]}`
2776+
;; - For grouped: `{:type :grouped-regression :points points :groups {group-val {:fitted [...] :points [...]}}}`
27772777
;;
27782778
;; Edge cases:
27792779
;; - Returns original points if regression fails (< 2 points, degenerate data)
2780-
;; - Handles nil fitted values gracefully (skipped during rendering)
2780+
;; - Handles `nil` fitted values gracefully (skipped during rendering)
27812781
(defmethod apply-transform :linear
27822782
[layer points]
27832783
(when-not (seq points)
@@ -3030,19 +3030,19 @@ iris
30303030
;; Apply histogram transform to points.
30313031
;;
30323032
;; Bins continuous x values and counts occurrences per bin.
3033-
;; Handles both single and grouped histograms based on :group key in points.
3033+
;; Handles both single and grouped histograms based on `:group` key in points.
30343034
;;
30353035
;; Args:
3036-
;; - layer: Layer map containing :=bins specification
3037-
;; - points: Sequence of point maps with :x and optional :group keys
3036+
;; - `layer`: Layer map containing `:=bins` specification
3037+
;; - `points`: Sequence of point maps with `:x` and optional `:group` keys
30383038
;;
30393039
;; Returns:
3040-
;; - For ungrouped: {:type :histogram :points points :bars [{:x-min :x-max :x-center :height}...]}
3041-
;; - For grouped: {:type :grouped-histogram :points points :groups {group-val {:bars [...] :points [...]}}}
3040+
;; - For ungrouped: `{:type :histogram :points points :bars [{:x-min :x-max :x-center :height}...]}`
3041+
;; - For grouped: `{:type :grouped-histogram :points points :groups {group-val {:bars [...] :points [...]}}}`
30423042
;;
30433043
;; Edge cases:
3044-
;; - Returns nil bars if compute-histogram fails (empty, non-numeric, or identical values)
3045-
;; - Histogram with nil bars will not render (graceful degradation)
3044+
;; - Returns `nil` bars if `compute-histogram` fails (empty, non-numeric, or identical values)
3045+
;; - Histogram with `nil` bars will not render (graceful degradation)
30463046
(defmethod apply-transform :histogram
30473047
[layer points]
30483048
(when-not (seq points)

0 commit comments

Comments
 (0)