jsa-aerial / hanami Goto Github PK
View Code? Open in Web Editor NEWInteractive arts and charts plotting with Clojure(Script) and Vega-lite / Vega. Flower viewing 花見 (hanami)
License: MIT License
Interactive arts and charts plotting with Clojure(Script) and Vega-lite / Vega. Flower viewing 花見 (hanami)
License: MIT License
Hi there, hanami looks great!
My first thought would be how this relates to oz.
Just as suggestion, maybe you could mention in the readme in which way they differ?
Thank you :)
Hanami looks like a great project. I tried the ClientOnly example today and find the project is built for aerial.hanami "0.7.0" but aerial.hanami "0.6.0" is the latest available at Clojars.
Do you know when 7 will be released to Clojars?
Thanks for all the hard work!
I am trying to get the example (server-side) running. Unfortunately to no avail, and the same is true for bbhanami. Could be, that I am missing something (very important?), but right now, I am unsure, what it is.
Any help and most probably more detailed documentation (like a Tutorial) is greatly appreciated.
Thanks again for Hanami.
I've been learning Hanami and Vega-Lite at the same time. Other things being equal, I prefer to use Hanami (it's spoiled me--I don't want to have to specify everything in the detail required by V-L :-), but sometimes V-L is necessary, and sometimes it's helpful to study V-L to understand Hanami better.
One thing that would be helpful would be a list of templates with suggested uses, and/or a list of basic uses and suggested templates. (I sometimes go through templates.cljc to try to figure this out, but that involves a bit of guesswork and experimentation, I don't know whether I'm missing useful tools that are in other source files.)
My current case is that I want to produce a lot of small plots at once, and display them in an MxN layout, where the layout might be fixed or might just be whatever fits the plots in. My understanding is that I can do that in Vega-Lite with facet
(or maybe concat
). I don't know how to use these yet, but I'm trying to figure out whether there's a Hanami way that would make it easier, and then I'll start by learning that. The README illustrates hconcat-chart
and vconcat-chart
, but I'm wondering whether there is something in Hanami that makes using V-L facet
(orconcat
easier). Or maybe I just have to think about the existing templates or other tools in Hanami in a different way. [Maybe I'll use vconcat-chart
inside hconcat-chart
, or vice versa, but that won't let Vega-Lite figure the number of plots per row and column, and I wondered if there is a more direct way.]
Thanks!
I'm trying to require aerial.hanami.core
with [aerial.hanami "0.5.1"]
at clojurescript using shadow-cljs
and it gives me the error below.
Is there some way to ignore this reference duplication?
--------------------------------------------------------------------------------
1 | (ns aerial.hanami.core
-------^------------------------------------------------------------------------
conflict on "h-box" by "re-com.box" used by "re-com.core"
{:tag :shadow.build.ns-form/require-conflict, :ns-info {:rename-macros nil, :renames {}, :meta {:file "aerial/hanami/core.cljs", :line 1, :column 6, :end-line 1, :end-column 24}, :use-macros {go cljs.core.async, go-loop cljs.core.async, handler-fn re-com.core}, :excludes #{}, :name aerial.hanami.core, :imports nil, :requires {com.rpl.specter com.rpl.specter, cli aerial.hanasu.client, re-com.core re-com.core, rgt reagent.core, aerial.hanasu.client aerial.hanasu.client, cljsjs.vega-embed cljsjs.vega-embed, async cljs.core.async, re-com.box re-com.box, reagent.core reagent.core, com aerial.hanasu.common, aerial.hanami.templates aerial.hanami.templates, cljsjs.vega-tooltip cljsjs.vega-tooltip, cljs.core.async cljs.core.async, sp com.rpl.specter, aerial.hanami.common aerial.hanami.common, aerial.hanasu.common aerial.hanasu.common, cljsjs.vega-lite cljsjs.vega-lite, ht aerial.hanami.templates, hc aerial.hanami.common, rcm re-com.core, cljsjs.vega cljsjs.vega}, :seen #{:require}, :uses {row-button re-com.core, h-box re-com.core, modal-panel re-com.core, <! cljs.core.async, p re-com.core, input-textarea re-com.core, h-split re-com.core, slider re-com.core, chan cljs.core.async, progress-bar re-com.core, input-text re-com.core, radio-button re-com.core, checkbox re-com.core, button re-com.core, box re-com.core, input-password re-com.core, info-button re-com.core, vertical-bar-tabs re-com.core, popover-content-wrapper re-com.core, title re-com.core, v-box re-com.core, horizontal-bar-tabs re-com.core, >! cljs.core.async, v-split re-com.core, single-dropdown re-com.core, hyperlink-href re-com.core, md-icon-button re-com.core, line re-com.core, label re-com.core, gap re-com.core, throbber re-com.core, put! cljs.core.async, popover-anchor-wrapper re-com.core, md-circle-icon-button re-com.core}, :require-macros {cljs.core.async cljs.core.async, async cljs.core.async, re-com.core re-com.core, rcm re-com.core}, :flags {:require #{}}, :js-deps {}, :deps [cljs.core.async com.rpl.specter aerial.hanasu.client aerial.hanasu.common aerial.hanami.common aerial.hanami.templates cljsjs.vega cljsjs.vega-lite cljsjs.vega-embed cljsjs.vega-tooltip reagent.core re-com.core re-com.box]}, :merge-key :uses, :sym h-box, :ns re-com.box}
ExceptionInfo: conflict on "h-box" by "re-com.box" used by "re-com.core"
clojure.core/ex-info (core.clj:4739)
clojure.core/ex-info (core.clj:4739)
shadow.build.ns-form/merge-require (ns_form.clj:279)
shadow.build.ns-form/merge-require (ns_form.clj:272)
shadow.build.ns-form/merge-require-fn/fn--8794 (ns_form.clj:288)
clojure.lang.PersistentVector.reduce (PersistentVector.java:341)
clojure.core/reduce (core.clj:6747)
clojure.core/reduce (core.clj:6730)
shadow.cljs.util/reduce-> (util.clj:47)
shadow.cljs.util/reduce-> (util.clj:46)
shadow.build.ns-form/process-symbol-require (ns_form.clj:340)
shadow.build.ns-form/process-symbol-require (ns_form.clj:315)
shadow.build.ns-form/process-require (ns_form.clj:357)
shadow.build.ns-form/process-require (ns_form.clj:354)
shadow.build.ns-form/reduce-require (ns_form.clj:371)
shadow.build.ns-form/reduce-require (ns_form.clj:359)
clojure.lang.PersistentVector.reduce (PersistentVector.java:341)
clojure.core/reduce (core.clj:6747)
clojure.core/reduce (core.clj:6730)
shadow.cljs.util/reduce-> (util.clj:47)
shadow.cljs.util/reduce-> (util.clj:46)
shadow.build.ns-form/fn--8834 (ns_form.clj:408)
shadow.build.ns-form/fn--8834 (ns_form.clj:402)
clojure.lang.MultiFn.invoke (MultiFn.java:233)
clojure.lang.PersistentVector.reduce (PersistentVector.java:341)
clojure.core/reduce (core.clj:6747)
clojure.core/reduce (core.clj:6730)
shadow.build.ns-form/parse (ns_form.clj:528)
shadow.build.ns-form/parse (ns_form.clj:495)
shadow.build.ns-form/parse (ns_form.clj:497)
shadow.build.ns-form/parse (ns_form.clj:495)
shadow.build.compiler/hijacked-parse-ns (compiler.clj:111)
shadow.build.compiler/hijacked-parse-ns (compiler.clj:101)
shadow.build.compiler/fn--11393 (compiler.clj:157)
shadow.build.compiler/fn--11393 (compiler.clj:154)
clojure.lang.MultiFn.invoke (MultiFn.java:251)
cljs.analyzer/analyze-seq* (analyzer.cljc:3600)
cljs.analyzer/analyze-seq* (analyzer.cljc:3598)
cljs.analyzer/analyze-seq*-wrap (analyzer.cljc:3605)
cljs.analyzer/analyze-seq*-wrap (analyzer.cljc:3603)
cljs.analyzer/analyze-seq (analyzer.cljc:3629)
cljs.analyzer/analyze-seq (analyzer.cljc:3607)
cljs.analyzer/analyze-form (analyzer.cljc:3810)
cljs.analyzer/analyze-form (analyzer.cljc:3807)
cljs.analyzer/analyze* (analyzer.cljc:3860)
cljs.analyzer/analyze* (analyzer.cljc:3851)
shadow.build.compiler/analyze (compiler.clj:212)
shadow.build.compiler/analyze (compiler.clj:176)
shadow.build.compiler/analyze (compiler.clj:178)
shadow.build.compiler/analyze (compiler.clj:176)
shadow.build.compiler/default-analyze-cljs (compiler.clj:314)
shadow.build.compiler/default-analyze-cljs (compiler.clj:303)
clojure.core/partial/fn--5561 (core.clj:2617)
shadow.build.compiler/do-analyze-cljs-string (compiler.clj:257)
shadow.build.compiler/do-analyze-cljs-string (compiler.clj:215)
shadow.build.compiler/analyze-cljs-string/fn--11453 (compiler.clj:378)
shadow.build.compiler/analyze-cljs-string (compiler.clj:377)
shadow.build.compiler/analyze-cljs-string (compiler.clj:375)
shadow.build.compiler/do-compile-cljs-resource/fn--11474 (compiler.clj:468)
shadow.build.compiler/do-compile-cljs-resource (compiler.clj:450)
shadow.build.compiler/do-compile-cljs-resource (compiler.clj:411)
shadow.build.compiler/maybe-compile-cljs/fn--11560 (compiler.clj:731)
shadow.build.compiler/maybe-compile-cljs (compiler.clj:730)
shadow.build.compiler/maybe-compile-cljs (compiler.clj:706)
shadow.build.compiler/par-compile-one (compiler.clj:832)
shadow.build.compiler/par-compile-one (compiler.clj:787)
shadow.build.compiler/par-compile-cljs-sources/fn--11594/iter--11616--11620/fn--11621/fn--11622/fn--11623 (compiler.clj:905)
clojure.core/apply (core.clj:657)
clojure.core/with-bindings* (core.clj:1965)
clojure.core/with-bindings* (core.clj:1965)
clojure.core/apply (core.clj:661)
clojure.core/bound-fn*/fn--5471 (core.clj:1995)
java.util.concurrent.FutureTask.run (FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
java.lang.Thread.run (Thread.java:745)
--------------------------------------------------------------------------------
2 | (:require
3 | [cljs.core.async
4 | :as async
5 | :refer (<! >! put! chan)
--------------------------------------------------------------------------------
This would be based on a new substitution key, fdata-key which defaults to :FDATA.
Vega-Lite already supports data sources for values (vector of maps), urls (a relative or full path url to a data file - json and csv) and named channels (for vega changesets). Hanami supports these via data-key :DATA, :UDATA and :NDATA. The suggestion here is to have a new data source supported - files on the server side. Client support is also possible but due to browser restrictions would involve different mechanisms.
Suggested key (and values):
:FDATA <filepath | [filepath, type-vector-or-map]]
The filepath is a full path for the OS and can denote a file with extensions 'clj', 'edn', 'json', or 'csv'. These extensions indicate the file types - no other checking is done. For the 'clj', 'edn', and 'json' the content must be a vector of maps, where each map is a record of data fields and their values. CSV files are converted to vectors of maps, each map built from the column names and a row's corresponding values.
For 'csv', a type-vec-or-map may be provided as the second value of a vector pair (tuple). This can be either a vector of type indicators in 1-1 correspondence with the column names of the csv file, or a map where each key is one of the column names and the value is a type indicator. Type indicators supported are: "string", "int", "float", and "double". In either case, the strings in a row associated with the type indicators are converted per the indicator.
Example:
(hc/xform my-plot-template :FDATA ["/Data/RNAseq/Exp-xyz/Out/dge-xyz.csv" {"dge" "float"})
data/cars.json is missing
:-)
Just wanted to know if the team has considered extracting out the xform and templating capabilities and made them generic and not specific to visualization ? or.. does it exist elsewhere in another form or by aanother name ? thanks
Let's call a visualization (whether chart, plot, layout, etc) a picture. Currently pictures have a size based on the Vega/Vega-Lite height
and width
attributes of the outer view. This means that the total window area taken up by a picture is determined by this size. This also influences where and how much more area is taken up by any surrounding picture frame elements (top, bottom, left, right). Even with very large screen real estate this can easily overflow in large renderings. Overview+Detail charts are one way of trying to control this. But they do not work in all cases - for example, tree and network layouts. Or faceted charts involving a large number of data 'points' (hundreds to thousands). But making the picture size 'small' can render (so to speak) the graphic useless (unable to resolve individual cases or things start overwriting themselves, etc).
Putting the picture in a scroll area (scroller component), would enable choosing a limited amount of window area to be allocated, while keeping the picture itself at the optimal (or at least good) resolution. This is not always needed and in many cases would be a nuisance, so the ability should be optional.
The basic idea would be to add a special :scroller
element to picture frames (currently they have the :top
, :bottom
, :left
, and :right
elements), which, if provided, would define the window area limits:
:frame {
:scroller {:width <integer>, :min-width <CSS size style>, :max-width <CSS size style>
:height <integer>, :min-height <CSS size style>, :max-height <CSS size style>}
Where all of these are optional, but if none are given the whole point of the scroller is lost. Generally the :max-width
and :max-height
would be all you would ever provide. "CSS size style" would most typically be a "xxxxpx" size, for example "1000px", but could be others.
One thing to keep in mind with these sizes is that Hanami uses re-com and is all in on Flex styling! So, scrollers will have flex behaviors.
Would be nice to support 'picture frames' that have no picture (chart/visualization) in them. Basically the chart is a 'point'. This would enable a more general document structure supporting paragraphs of 'text oriented' material.
I'm interested in hanami. I tried to play with the example, but it isn't starting up.
Reproduce (as described in readme):
$ cd hanami/examples/ClientOnly
$ lein repl
[WARNING] No nREPL middleware descriptor in metadata of #'cider.piggieback/wrap-cljs-repl, see nrepl.middleware/set-descriptor!
nREPL server started on port 42029 on host 127.0.0.1 - nrepl://127.0.0.1:42029
ERROR: Unhandled REPL handler exception processing message {:id 3db52c4f-97a4-4b9b-b802-5b4fbeb52b98, :op clone}
java.lang.NullPointerException
at clojure.core$deref_future.invokeStatic(core.clj:2300)
at clojure.core$deref.invokeStatic(core.clj:2320)
at clojure.core$deref.invoke(core.clj:2306)
at cider.piggieback$wrap_cljs_repl$fn__2945.invoke(piggieback.clj:209)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__2583.invoke(middleware.clj:22)
at nrepl.server$default_handler$fn__1572.invoke(server.clj:130)
at nrepl.server$handle_STAR_.invokeStatic(server.clj:22)
at nrepl.server$handle_STAR_.invoke(server.clj:19)
at nrepl.server$handle$fn__1543.invoke(server.clj:39)
at clojure.core$binding_conveyor_fn$fn__5754.invoke(core.clj:2030)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
$ lein version
Leiningen 2.9.5 on Java 11.0.10 OpenJDK 64-Bit Server VM
I am the author of Klipse and I'd like to suggest you to demonstrate your amazing library in web pages that feature interactive code snippets with Klipse.
You could get inspired by the work done for a Reagent tutorial with Klipse. See here.
The benefit for you would be to allow people to get a feeling of how writing hanami based code looks like without need to install any artifact on their computer.
The project.clj uses dependency [reagent "0.7.0"] and has #_[reagent "0.8.1"] commented out. Is there a reason for this, is there an issue with later reagent ?
The readme docs state
The basic resource requirements are the various stylesheets, mostly in support of re-com, that are shown in the development 'landing page' index.html. When you create your own index.html landing page - or generate it dynamically - you will need to include these resources.
But the link is broken: https://github.com/jsa-aerial/hanami/blob/master/resources/public/index.html
Libraries should not contain logback.xml, but leave logging configuration to downstream apps
Hello,
Is there a way to specify the scaleFactor from Vega-Embed for exporting the visualization to png?
Best regards,
David
In VEGA Lite there is the notion of ordering for stacked charts. Right now, the only possibility to sort is by the color-field (stack grouping field). But there is no ORDER field for using other fields to order the stack in hanami. It would be great, if this is supported.
https://vega.github.io/vega-lite/docs/stack.html#sorting-stack-order
Hi,
I want to use the hanami library to create a dashboard, but I am having problems to understand how I can use only the clojurescript side without the need to create the hanami server side.
Could someone clarify how I can proceed? Why even reading the documents and studying the saite example, I can not figure out how to create a graph without the hanami ecosystem (server and client).
Best regards,
Vinicius
thank you for this library!
as briefly discussed elsewhere would be great to have a with-defaults
where you can bind the defaults that will be used.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.