From 392a2256913c3f39398c1affada633707ab87c46 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sat, 22 Feb 2020 19:44:55 +0000 Subject: [PATCH] Inline map data now works too. --- resources/public/css/style.css | 17 +++-- resources/public/index.html | 35 +++++++++- src/geocsv_lite/data.cljs | 115 ++++++++++++++++++++++++--------- 3 files changed, 131 insertions(+), 36 deletions(-) diff --git a/resources/public/css/style.css b/resources/public/css/style.css index de8c37f..4beb199 100644 --- a/resources/public/css/style.css +++ b/resources/public/css/style.css @@ -5,10 +5,6 @@ body { padding-bottom: 4em; } -div#app { - margin-left: 10%; -} - footer { clear: both; font-size: smaller; @@ -33,7 +29,6 @@ footer a { h1, h2, h3, h4, h5, h6 { - width: 100%; margin: 0; padding: 0.5em 10%; text-align: left; @@ -45,6 +40,14 @@ samp { background-color: #b0b0ff; } +#app { + margin-left: 10%; +} + +#app h2 { + width: 60%; +} + #error { background-color: maroon; @@ -60,3 +63,7 @@ samp { margin: 0px; padding-left: 10%; } + +.leaflet-popup-content h5 { + width: 80%; +} diff --git a/resources/public/index.html b/resources/public/index.html index d70e493..48d4385 100644 --- a/resources/public/index.html +++ b/resources/public/index.html @@ -21,6 +21,15 @@ crossorigin=""/ -->

+

+

+

+ Map using inline CSV +

+
+

+ Map using CSV from URL +

@@ -71,7 +80,31 @@ crossorigin=""> diff --git a/src/geocsv_lite/data.cljs b/src/geocsv_lite/data.cljs index c768db1..d761645 100644 --- a/src/geocsv_lite/data.cljs +++ b/src/geocsv_lite/data.cljs @@ -37,6 +37,29 @@ (:uri query) (:uri query)))) +(defn prepare-records + "`data` is expected to be a vector of vectors, where the first vector + contains column headers and the remaining vectors contain records. + Return this as a vector of maps, with each map having keys taken from + the first vector and values taken from one of the subsequent vectors." + [data] + (let [cols (map + #(let [n (when-not + (empty? %) + (when (string? %) + (cs/lower-case + (cs/replace + % #"[^\w\d]+" "-"))))] + (keyword + (if (empty? n) + (gensym) + n))) + (first data))] + (map + (fn [r] (zipmap cols r)) + (rest data)))) + + (defn default-handler "When data is received from a URL, it is received asynchronously. This is the default callback called with the `response` of the HTTP request, @@ -46,46 +69,78 @@ (if (= (:status response) 200) (let [content (:body response) - data (map - #(merge % - {:longitude (js/Number (:longitude %)) - :latitide (js/Number (:latitude %))}) - (js->clj (.-data (.parse js/Papa content (clj->js {:dynamicTyping true}))))) - cols (map - #(let [n (when-not - (empty? %) - (when (string? %) - (cs/lower-case - (cs/replace - % #"[^\w\d]+" "-"))))] - (keyword - (if (empty? n) - (gensym) - n))) - (first data)) - records (map - (fn [r] (zipmap cols (map str r))) - (rest data)) - ] + records (prepare-records + (:data + (js->clj + (.parse js/Papa content + (clj->js {:dynamicTyping true})) + :keywordize-keys true)))] (gis/refresh-map-pins (get-view k) records)) (n/error (str "Bad response from server: " (:status response))))) +(defn get-data-from-uri + "Get data for the view identified by this keyword `k` from this `uri`." + [k uri] + (go (let [response (clj (.parse js/Papa data-source) :keywordize-keys true) + data (if + (empty? (:errors p)) + (:data p) + ;; otherwise, is it JSON? + (try + (js->clj (.parse js/JSON data-source)) + (catch :default _ nil)))] + ;; almost anything can be a valid URL, so it's hard to verify that a given + ;; string is not one. So we will assume that what we've been passed is a + ;; URL unless we've been able to parse valid data out of it. + (js/console.debug "Found records: " (clj->js data)) + (if + ;; it looks like valid data if it's a vector of vectors. + (and (vector? data) (every? vector? data)) + (let [records (prepare-records data)] + (n/message (str "Found " (count records) " records of inline data for map `" k "`")) + (gis/refresh-map-pins (get-view k) (prepare-records data))) + ; else + (get-data-from-uri k data-source)))) + (defn get-data-with-uri-and-handler [uri handler-fn k] (go (let [response (clj (.parse js/Papa data-source) +;; :keywordize-keys true))) + +;; (get-data :inline-csv-map "http://localhost:3449/data/data.csv") +;; (get-data :inline-csv-map data-source) +;; (every? (fn [r] (and (vector? r) (every? vector? r))) (:data (js->clj (.parse js/Papa data-source) +;; :keywordize-keys true))) +;; (every? vector? (:data (js->clj (.parse js/Papa data-source) +;; :keywordize-keys true))) +;; (vector? (first (:data (js->clj (.parse js/Papa data-source) +;; :keywordize-keys true)))) +;; (def p (:data (js->clj (.parse js/Papa data-source) +;; :keywordize-keys true))) +;; (every? vector? p) + +;; (vector? p) +;; (every? vector? p)