-
Notifications
You must be signed in to change notification settings - Fork 1
/
api.clj
102 lines (90 loc) · 3.08 KB
/
api.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(ns scicloj.viz.api
(:require [aerial.hanami.common :as hc]
[aerial.hanami.templates :as ht]
[scicloj.viz.templates :as vt]
[scicloj.viz.dataset] ; making sure datasets behave nicely in rendering
[tech.v3.dataset :as tmd]
[scicloj.kindly.api :as kindly]
[scicloj.kindly.kind :as kind]
[scicloj.tempfiles.api :as tempfiles]
[clojure.string :as string])
(:refer-clojure :exclude [type]))
(def map-of-templates {"point" ht/point-chart
"boxplot" vt/boxplot-chart})
(defn viz
[base-options & args]
(let [arg1 (first args)
additional-options (cond (nil? arg1) {}
(map? arg1) (apply merge args)
(keyword? arg1) (apply hash-map args))
options (merge base-options
additional-options)
typ (:type options)]
(-> (apply hc/xform
(if (map? typ) typ
;; else -- lookup in cagalogue
(map-of-templates (name typ)))
(apply concat (dissoc options :type)))
(kindly/consider kind/vega))))
(defn path->file-extension [path]
(-> path
(string/split #"\.")
last
(->> (str "."))))
(defn as-url
[data]
(cond (string? data)
;; either a route or a path to a file
(if (string/starts-with? data "http")
;; already a url!
data
;; else -- a path
(let [{:keys [path route]} (tempfiles/tempfile!
(path->file-extension data))]
;; TODO -- do it more efficiently
(->> data
slurp
(spit path))
route))
(instance? tech.v3.dataset.impl.dataset.Dataset data)
;; a tmd dataset
(let [{:keys [path route]} (tempfiles/tempfile! ".csv")]
(tmd/write! data path)
route)))
(defn data
"Pass the data as either url/file path (string) or dataset"
[data]
(cond (string? data)
{:UDATA (as-url data)}
(instance? tech.v3.dataset.impl.dataset.Dataset data)
{:UDATA (as-url data)}
(or (and (sequential? data)
(every? map? data))
(and (map? data)
(every? sequential? data)))
{:UDATA (-> data
tmd/->dataset
as-url)}
:else {:DATA data}))
(defn type
[viz-map, type]
(assoc viz-map :type type))
(defn- set-coordinates
([viz-map, field-name, {:keys [type] :as options}, field-key]
(merge viz-map
{field-key (name field-name)}
(when type {(keyword (str (name field-key) "TYPE")) type})
(dissoc options :type))))
(defn x
([viz-map, field-name]
(x viz-map field-name {}))
([viz-map, field-name, options]
(set-coordinates viz-map field-name options :X)))
(defn y
([viz-map, field-name]
(y viz-map field-name {}))
([viz-map, field-name, options]
(set-coordinates viz-map field-name options :Y)))
(defn color
[viz-map, color]
(assoc viz-map :COLOR color))