This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-07-07
Channels
- # admin-announcements (2)
- # boot (111)
- # capetown (5)
- # cider (15)
- # clara (15)
- # cljs-dev (8)
- # clojure (78)
- # clojure-brasil (1)
- # clojure-dev (2)
- # clojure-greece (25)
- # clojure-hk (1)
- # clojure-russia (5)
- # clojure-seattle (1)
- # clojure-spec (120)
- # clojure-sweden (3)
- # clojure-uk (63)
- # clojurescript (161)
- # data-science (1)
- # datomic (21)
- # editors (43)
- # emacs (3)
- # funcool (1)
- # hoplon (72)
- # instaparse (11)
- # jobs (1)
- # off-topic (2)
- # om (212)
- # onyx (9)
- # other-languages (129)
- # proton (5)
- # re-frame (15)
- # reagent (18)
- # slack-help (4)
- # spacemacs (18)
- # untangled (224)
- # yada (21)
anyone have experience exposing clojurescript modules to javascript via webpack (with or without use of closure-loader)?
@blance: Just read the css string in with a macro and store it in some def
. Then inject the CSS with goog.style
on startup.
hey fellow clojurians, i'm working working on building a linechart with the help of d3 but have a question translating javascript into clojurescript code relevant snippets: js
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
and that's my cljs code
(defn create-svg-value-line [data]
(-> (js/d3.svg.line)
(.x (clj->js (:date data) ))
(.y (clj->js (:close data)))
ideas suggestions will be accepted thanksfully
@dev-hartmann: x
and y
in cljs would be
(def x (-> js/d3
.-time
.scale
(.range #js [0 width])))
regarding create-svg-value-line
, I am assuming that data
is a cljs data structure rather than a js one.
I think you are missing calls to x
and y
(the two scales) in your create-svg-value-line
@turbopape: Hope I'm not being annoying (as opposed to "showing pleasant enthusiasm"), but still no TOC nor sample. 😕 https://www.packtpub.com/web-development/learning-clojurescript
@ rohit
@rohit: thnaks a lot, got that defined, but how du i call them with data in the create-svg-line function,x and y defs i mean
@dev-hartmann: i think you were almost there. (.x (x (clj->js (:date data))))
. note that extra call to x
.
ah, now i get it
@dev-hartmann: just double check what is data
. i have a feeling that its a js
datastructure and in that case, the code won’t work.
no, it's a clojure map
@dev-hartmann: another thing, if (:date data)
returns a primitive data type, then you don’t need to a clj->js
on it.
@rohit: thank you very much
still having issues
(def chart-margins {:top 20 :right 20 :bottom 30 :left 50})
(def days ["Mo" "Di" "Mi" "Do" "Fr" "Sa" "So"])
(defn calc-width [base-width {:keys [left right]}]
(- base-width left right))
(defn calc-height [base-height {:keys [top bottom]}]
(- base-height top bottom))
(defn calc-x [width ordinal-domain]
(-> (js/d3.scale.ordinal)
(.domain (clj->js ["Mo" "Di" "Mi" "Do" "Fr" "Sa" "So"] ))
(.rangePoints (clj->js [0 width]))))
(defn calc-y [height]
(-> (js/d3.scale.linear)
(.range (clj->js [height 0]))
(.domain (clj->js [0 500]))))
(defn calculate-axis [axis-def orientation]
(-> (js/d3.svg.axis)
(.scale axis-def)
(.orient orientation)))
(defn create-svg-value-line [identifier y-scale x-scale data]
(-> (js/d3.svg.line)
(.x (x-scale (clj->js (((keyword identifier) data)))))
(.y (y-scale (clj->js (:day data))))))
(defn create-line-chart-svg [id height x y]
(-> (js/d3.select id)
(.append "g" )
(.attr "class" "y-axis")
(.call (clj->js y) )
(.append "g" )
(.attr "class" "x-axis")
(.attr (clj->js ["transform" (str "(translate(0," height ")")]))
(.call (clj->js x))))
(defn create-panel-svg [base-width base-height id]
(let [height (calc-height base-height chart-margins)
width (calc-width base-width chart-margins)
y-scale (calc-y height)
x-scale (calc-x width days)
y-axis (calculate-axis y-scale "left")
x-axis (calculate-axis x-scale "bottom")]
[:svg {:id "line-chart" :width 1000 :height 200}
[:g {:transform (str "translate(" (/ 1000 2) "," (/ 200 2) ") scale(1) rotate(0,200,200)")}
[:path {:d ((create-svg-value-line "vuln-high" y-scale x-scale dummy-data))}]
[:text {:font-size "80px" :fill "white" :text-anchor "middle" :y 20 }]]]
(create-line-chart-svg id height x-axis y-axis)))
at the moment it looks very ugly, sry, but i'm in desperate experimenting mode -.-
forgot dummy data
))
@dev-hartmann: no problems.
(def dummy-data [ {:vuln-high 50 :day "Mo"} {:vuln-high 50 :day "Di"} {:vuln-high 50 :day "Mi"}])
@dev-hartmann: btw, are you using #C0620C0C8?
Yes i EMAN
Mean :face_with_rolling_eyes:
@dev-hartmann: in that case, i think the approach you are taking may not be a good one. jump onto #C0620C0C8. also look at http://zachcp.org/blog/2015/reagent-d3/
you will need to use a form-3 react component. https://github.com/day8/re-frame/wiki/Creating%20Reagent%20Components#form-3-a-class-with-life-cycle-methods
@aengelberg: Your re-seq
issue may have been exacerbated by a lack of locals clearing. For more see http://blog.fikesfarm.com/posts/2016-01-15-clojurescript-head-holding.html
@rohit: yeah, i know what mean, i just wanted to get the graph done with dummy data first, to see if i got everything right and then put all of that into a reagent component. but thee blogpost looks promissing, so i'll try that
@dev-hartmann: cool.
@rohit: btw did you see anything else, that did prevent my code from working? still couldn't find whats going wrong
@dev-hartmann: actually i can’t figure out how you are running it etc. if you can share a project or something, i can have a look
@rohit: damn, i can't it's a work project
@dev-hartmann: i understand that. my 2 cent advice: remove all the code and then start adding code which works till you reach points of failure.
@rohit: thanks again! your help is very much appreciated. almost done with the component
@dev-hartmann: sweet. :thumbsup::skin-tone-4:
(defn line-chart-compnent [id bwidth bheight]
(reagent/create-class
{:reagent-render (fn [] [:div [:svg {:id id :width bwidth :height bheight}]])
:component-did-mount (fn []
(let [d3data (clj->js dummy-data)
height (calc-height bheight chart-margins)
width (calc-width bwidth chart-margins)
y-scale (calc-y height)
x-scale (calc-x width days)
y-axis (calculate-axis y-scale "left")
x-axis (calculate-axis x-scale "bottom")]
(.. js/d3
(select id)
(append "g")
(attr "transform" (str "translate(" (/ 1000 2) "," (/ 200 2) ") scale(1) rotate(0,200,200)"))
(append "path")
(attr "d" (create-svg-value-line "vuln-high" y-scale x-scale d3data))
(append "g")
(attr "class" "x-axis")
(call x-axis )
(append "g")
(attr "class" "y-axis")
(call y-axis ))))}))
that's the component btw
interestingly that one doesn't get rendered at all :thinking_face:
As an aside, because I've seen people do this a lot. Your use of "id" for referring to the svg isn't necessary.
thought of that too, thank you very much!
(-> (dom-node this) (.childNodes) (first))
might be a more specific way of referring to what you intend.
@rohit: i guess i found the issue:
(defn create-svg-value-line [identifier y-scale x-scale data]
(-> (js/d3.svg.line)
(.x (x-scale (((keyword identifier) data))))
(.y (y-scale ((:day data))))))
that function gives me the error: component.cljs?rel=1467895555146:47 Uncaught TypeError: Cannot read property 'call' of null
@dev-hartmann: you may have an extra pair of parens around arguments to the two scales
@rohit: that's very true 😉 now i get component.cljs?rel=1467896362930:52 Uncaught TypeError: Cannot read property 'x' of undefined
@dev-hartmann: try writing (js/d3.svg.line)
more idiomatically
(defn create-svg-value-line [identifier y-scale x-scale data]
(-> js/d3
.-svg
.line
(.x (x-scale (fn [d] ((keyword identifier) d)) data))
(.y (y-scale (fn [d](:day d)) data))))
now i get cannot d3.inc.js:8124 Uncaught TypeError: Cannot read property 'length' of undefined
@dev-hartmann: now you are very much in d3 land.
is that a good or bad thing 😛
@dev-hartmann: just a different problem. 😉
btw, if i am doing deep js interop, i always look at the js clojurescript compiler generates
i guess you meant this
return d3.svg.line().x(cljs.core.clj__GT_js.call(null,(function (d){
return x_scale.call(null,cljs.core.keyword.call(null,identifier),d).call(null);
}).call(null,data))).y(cljs.core.clj__GT_js.call(null,(function (d){
return y_scale.call(null,new cljs.core.Keyword(null,"day","day",-274800446).cljs$core$IFn$_invoke$arity$1(d));
}).call(null,data)));
right?
what it should resemble is this
var valueline = d3.svg.line()
.x(function(d) {
return x_scale(d[identifier]); })
.y(function(d) {
return y_scale(d.day);});
@dev-hartmann: this sounds like you’re passing something to D3 which is not array-like
@dnolen: it's an array of maps
@dnolen: point taken 😉
@dnolen: being a noob sucks. how exactly would i do that?
lein-cljsbuild
thanks!
#js [#js {:vuln-high 50, :day Mo} #js {:vuln-high 50, :day Di} #js {:vuln-high 50, :day Mi}]... that's what mit data looks like
seems about right, javascript array and javascript maps inside
and not this code looks about right
frontend.dashboard.component.create_svg_value_line = (function frontend$dashboard$component$create_svg_value_line(identifier, y_scale, x_scale, data) {
cljs.core.println.call(null , data);
return d3.svg.line().x((function(d) {
return x_scale.call(null , cljs.core.keyword.call(null , identifier).call(null , d));
}
).call(null , data)).y((function(d) {
return y_scale.call(null , new cljs.core.Keyword(null ,"day","day",-274800446).cljs$core$IFn$_invoke$arity$1(d));
}
).call(null , data));
but still i get d3.inc.js:8124 Uncaught TypeError: Cannot read property 'length' of undefined
@dev-hartmann: whats data
like?
#js [#js {:vuln-high 50, :day Mo} #js {:vuln-high 50, :day Di} #js {:vuln-high 50, :day Mi}]
that's it
(def dummy-data [
{:vuln-high 50 :day "Mo"}
{:vuln-high 50 :day "Di"}
{:vuln-high 50 :day "Mi"}])
that's the original clojure map
and i do
let [d3data (clj->js dummy-data)]
to get it
@dev-hartmann: ok. if its a js object then you can’t do a lookup by keyword for the scales.
like here
(defn create-svg-value-line [identifier y-scale x-scale data]
(-> js/d3
.-svg
.line
(.x (x-scale (fn [d] ((keyword identifier) d)) data))
(.y (y-scale (fn [d](:day d)) data))))
ah, ok that makes sense
that's how the code creating the scales
(defn calc-x [width]
(-> js/d3
.-scale
.ordinal
(.domain #js ["Mo" "Di" "Mi" "Do" "Fr" "Sa" "So"] )
(.rangePoints #js [0 width])))
(defn calc-y [height]
(-> js/d3
.-scale
.linear
(.range #js [height 0])
(.domain #js [0 500])))
(defn calculate-axis [axis-def orientation]
(-> js/d3
.-svg
.axis
(.scale axis-def)
(.orient orientation)))
the js created looks pretty much like the example code i found
@dev-hartmann: thats good! 🙂
(defn create-svg-value-line [identifier y-scale x-scale data]
(-> js/d3
.-svg
.line
(.x (fn [d](x-scale (goog.object/get d identifier ) )) data)
(.y (fn [d](y-scale (goog.object/get d "day" ) )) data)))
but still i get d3.inc.js:8124 Uncaught TypeError: Cannot read property 'length' of undefined
that's kinda hard to get, but thank you both @rohit and @dnolen for helping out!
@dev-hartmann: no worries.
@dev-hartmann: i’ve created a very simple example of creating a svg line using d3 here: https://github.com/ducky427/testd3
And i can See what i did wrong spot on ;)
Thx! Will try it when i hit The Train
@dev-hartmann: sweet!
@rohit: works! I get path etc ;)
Anyone has strong opinions for clojurescript configuration ? I have seen https://www.martinklepsch.org/posts/parameterizing-clojurescript-builds.html and https://github.com/adzerk-oss/env (but I already use environ)
personally I don't like having the cljs build depend on env variables
it introduces a hidden build-time dependency, and it's hard to figure out for new team members
I know that's how many people do it though, so take this with a grain of salt
how about prepending a javascript configuration file (binding a JSON to a global var) to the bundle output?
it's not particularly elegant
but it works 🙂
But good point about the build though. I don't really care about team members (for the time being it's me myself and I) but I am clumsy enough that I could set env vars when building locally and forget about them
you're right about the polluted namespace
@nha: i’ve personally used goog.define
approach @martinklepsch mentions in his blog post. it works really well when used with leiningen profiles.
you could also require
different configuration namespaces depending on the environment (production, staging, local)
I just found this also: https://groups.google.com/forum/#!topic/clojurescript/YV-051DmdFE looks like a simplified version of adzerk/env
@nha, what's stopping you from just calling System/getenv
in a macro?
Seems like the macro there doesn't do nested properties: https://groups.google.com/forum/#!topic/clojurescript/YV-051DmdFE
modifying it with get-in
seems to break it - return nil (but I'm not completely comfortable with macros)
@rauh: That's a great idea! Can you help explain a bit on how to read local file at compile time(I'm assuming through clj? ) and use the content at runtime (like you said in some def
)?
I don’t think there is a maintained changelog, but commits are here: https://github.com/cognitect/transit-cljs/commits/master
we’re also not currently taking PRs on the transit projects - would happily offload such a task to the community
I recommend starting a discussion on the transit mailing list about that if you’re serious about getting some movement on that.
I'd be happy to take care of the last mile of commiting that to the readme
Should ClojureScript emit a warning or throw an error if trying to use something marked private, thoughts?
Warning seems right to me too
sorry, not immediately finding this — but is there a rational / statement on what browsers cljs wants to support?
we only generate ECMA-262 JS (circa 2001) and we rely on Google Closure so technically we support browsers all the way back to IE6 still.
is it possible to refactor requires in this format
[app.package1.ns1 :as ns1]
[app.package1.ns2 :as ns2]
[app.package2.ns3 :as ns3]
into
[app
[package1
[ns1 :as ns1]
[ns2 :as ns2]]
[package2
[ns3 :as ns3]]]
I know it is in clojure, I’m getting compiler errors in cljs so I assume the answer is no, just wanted to be sure I wasn’t missing something