diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40faaee --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/target +/classes +/checkouts +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port +.hgignore +.hg/ +*~ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..529069b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: clojure +script: lein test + +notifications: + email: false + +jdk: + - openjdk7 + - openjdk8 + - oraclejdk9 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..420e6f2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +# Change Log diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d8531bb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +This library is a wrapper around [kumo](https://github.com/kennycason/kumo) . You can look into the source for things to port. Fork and make a PR. + +## Code guidelines + +* Please use [aligned maps](https://github.com/bbatsov/clojure-style-guide#vertically-align-let-and-map) . In emacs select the map and hit `C-c SPC`. Refer : https://github.com/clojure-emacs/clojure-mode#vertical-alignment + +## Doc guidelines + +* Please document the feature in `examples` directory. Feel free to add an image if it's useful to convey the option better. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..86bc7ce --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Karthikeyan S + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9617f0 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# clj-wordcloud [![Build Status](https://travis-ci.org/tirkarthi/clj-wordcloud.svg?branch=master)](https://travis-ci.org/tirkarthi/clj-wordcloud) + +A simple clojure wrapper around kumo to generate wordcloud + +## Example + +Given a map of element and the frequency the following image is generated. More examples/examples.clj. + +```clojure +(let [frequency-map (zipmap (range 100 130) (range 300))] + (word-cloud frequency-map + {:background {:type :circle :size 300} + :filename "sample.png" :font-y 100 :padding 10})) +``` + +![Sample](/examples/sample.png) + +## Stability + +This library is still in early development phase and the API is subject to change. + +## Thanks + +Thanks to @kennycason for [kumo](https://github.com/kennycason/kumo) without which this library is not possible + +## License + +Copyright © 2018 Karthikeyan S + +Distributed under the MIT License diff --git a/doc/intro.md b/doc/intro.md new file mode 100644 index 0000000..bd42369 --- /dev/null +++ b/doc/intro.md @@ -0,0 +1,3 @@ +# Introduction to clj-wordcloud + +Refer to examples directory for now diff --git a/examples/examples.clj b/examples/examples.clj new file mode 100644 index 0000000..3bce873 --- /dev/null +++ b/examples/examples.clj @@ -0,0 +1,7 @@ +(ns examples + (:require '[clj-wordcloud.core :refer :all])) + +(let [frequency-map (zipmap (range 100 130) (range 300))] + (word-cloud frequency-map + {:background {:type :circle :size 300} + :filename "sample.png" :font-y 100 :padding 10})) diff --git a/examples/sample.png b/examples/sample.png new file mode 100644 index 0000000..ffa6f0d Binary files /dev/null and b/examples/sample.png differ diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..adfcbd9 --- /dev/null +++ b/project.clj @@ -0,0 +1,7 @@ +(defproject xtreak/clj-wordcloud "0.1.0-SNAPSHOT" + :description "A simple clojure wrapper around kumo for wordcloud generation" + :url "http://github.com/tirkarthi/clj-wordcloud" + :license {:name "MIT public license" + :url "http://opensource.org/licenses/mit-license.php"} + :dependencies [[org.clojure/clojure "1.9.0"] + [com.kennycason/kumo-core "1.13"]]) diff --git a/src/clj_wordcloud/core.clj b/src/clj_wordcloud/core.clj new file mode 100644 index 0000000..9063669 --- /dev/null +++ b/src/clj_wordcloud/core.clj @@ -0,0 +1,40 @@ +(ns clj-wordcloud.core + (:import (com.kennycason.kumo WordCloud WordFrequency) + (java.awt Dimension) + (com.kennycason.kumo WordCloud WordFrequency CollisionMode) + (com.kennycason.kumo.bg CircleBackground RectangleBackground) + (com.kennycason.kumo.font.scale LinearFontScalar) + (com.kennycason.kumo.nlp FrequencyAnalyzer))) + + +(defn- background-object + [options dimension] + (let [type (get-in options [:background :type] :circle) + size (get-in options [:background :size] 20)] + (case type + :circle + (CircleBackground. size) + :rectangle + (RectangleBackground. dimension)))) + + +(defn- build-word-frequency + [frequency-map] + (doto (java.util.ArrayList.) + (#(doseq [[word count] frequency-map] + (.add %1 (WordFrequency. (str word) count)))))) + + +(defn word-cloud + [frequency-map options] + (let [word-frequencies (build-word-frequency frequency-map) + dimension (Dimension. (:width options 600) (:height options 600)) + word-cloud (WordCloud. dimension CollisionMode/PIXEL_PERFECT) + background (background-object options dimension) + font (LinearFontScalar. (:font-x options 10) (:font-y options 40))] + (doto word-cloud + (.setPadding (:padding options 10)) + (.setBackground background) + (.setFontScalar font) + (.build word-frequencies) + (.writeToFile (:filename options "test.png"))))) diff --git a/test/clj_wordcloud/core_test.clj b/test/clj_wordcloud/core_test.clj new file mode 100644 index 0000000..bd28a69 --- /dev/null +++ b/test/clj_wordcloud/core_test.clj @@ -0,0 +1,17 @@ +(ns clj-wordcloud.core-test + (:require [clojure.test :refer :all] + [clj-wordcloud.core :refer :all])) + + +(defn get-size + [file] + (with-open [r (java.io.FileInputStream. file)] + (let [image (javax.imageio.ImageIO/read r)] + [(.getWidth image) (.getHeight image)]))) + +(deftest image-dimensions-test + (testing "Test width and height of the generated image" + (let [word-cloud (word-cloud (zipmap (range 100 130) (range 300)) + {:background {:type :circle :size 300} + :filename "sample.png" :font-y 100 :padding 10})] + (is (= (get-size "sample.png") [600 600])))))