mirror of
https://github.com/simon-brooke/clj-wordcloud.git
synced 2025-07-01 01:28:09 +00:00
Add support for custom bitmaps and docs
This commit is contained in:
parent
48f5ddc293
commit
8f76e1175a
|
@ -1,5 +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.
|
||||
|
||||
## API guidelines
|
||||
|
||||
* API should be compatible with [kumo](https://github.com/kennycason/kumo) and please refer to the repo for implementing new APIs.
|
||||
|
||||
## 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
|
||||
|
|
63
README.md
63
README.md
|
@ -6,18 +6,69 @@ A simple clojure wrapper around kumo to generate wordcloud
|
|||
|
||||
Given a map of element and the frequency the following image is generated. More examples/examples.clj.
|
||||
|
||||
### Circle
|
||||
|
||||
```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}))
|
||||
(ns examples
|
||||
(:require '[clj-wordcloud.core :refer :all]))
|
||||
|
||||
(let [frequency-map (zipmap (random-words 100) (shuffle (range 300)))
|
||||
word-cloud (word-cloud frequency-map
|
||||
{:dimension {:width 600
|
||||
:height 600}
|
||||
:background {:type :circle
|
||||
:size 300
|
||||
:color "0x000000"}
|
||||
:font {:type "Calibre"
|
||||
:weight :plain
|
||||
:scale-type :linear
|
||||
:x-scale 20
|
||||
:y-scale 20
|
||||
:padding 5}})]
|
||||
(write-to-file word-cloud "example_circle.png"))
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
### Bitmaps
|
||||
|
||||
```clojure
|
||||
(ns examples
|
||||
(:require '[clj-wordcloud.core :refer :all]))
|
||||
|
||||
(let [frequency-map (zipmap (range 100 150) (shuffle (range 300)))
|
||||
word-cloud (word-cloud frequency-map
|
||||
{:dimension {:width 600
|
||||
:height 600}
|
||||
:background {:type :pixel
|
||||
:size 300
|
||||
:color "0x000000"
|
||||
:bitmap "examples/backgrounds/haskell_1.bmp"}
|
||||
:font {:type "Calibre"
|
||||
:weight :plain
|
||||
:scale-type :linear
|
||||
:x-scale 20
|
||||
:y-scale 20
|
||||
:padding 5}})]
|
||||
(write-to-file word-cloud "example_haskell.png"))
|
||||
```
|
||||
|
||||

|
||||
|
||||
## TODO
|
||||
|
||||
* API parity with Kumo
|
||||
* clojure.spec for docs and validation
|
||||
* Cool examples
|
||||
* Better tests
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. Please refer to CONTRIBUTING.md.
|
||||
|
||||
## Stability
|
||||
|
||||
This library is still in early development phase and the API is subject to change.
|
||||
This library is still in early development phase and the API is subject to change. API design comments are welcome.
|
||||
|
||||
## Thanks
|
||||
|
||||
|
|
BIN
examples/backgrounds/haskell_1.bmp
Normal file
BIN
examples/backgrounds/haskell_1.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 994 KiB |
BIN
examples/backgrounds/haskell_2.bmp
Normal file
BIN
examples/backgrounds/haskell_2.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 994 KiB |
BIN
examples/example_circle.png
Normal file
BIN
examples/example_circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
BIN
examples/example_haskell.png
Normal file
BIN
examples/example_haskell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -1,7 +1,47 @@
|
|||
(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}))
|
||||
|
||||
(defn random-words
|
||||
[n]
|
||||
(->> "/usr/share/dict/words"
|
||||
slurp
|
||||
clojure.string/lower-case
|
||||
clojure.string/split-lines
|
||||
shuffle
|
||||
(take n)))
|
||||
|
||||
|
||||
(let [frequency-map (zipmap (random-words 100) (shuffle (range 300)))
|
||||
word-cloud (word-cloud frequency-map
|
||||
{:dimension {:width 600
|
||||
:height 600}
|
||||
:background {:type :circle
|
||||
:size 300
|
||||
:color "0x000000"}
|
||||
:font {:type "Calibre"
|
||||
:weight :plain
|
||||
:scale-type :linear
|
||||
:x-scale 20
|
||||
:y-scale 20
|
||||
:padding 5}})]
|
||||
(write-to-file word-cloud "example_circle.png"))
|
||||
|
||||
|
||||
(let [frequency-map (zipmap (range 100 150) (shuffle (range 300)))
|
||||
word-cloud (word-cloud frequency-map
|
||||
{:dimension {:width 600
|
||||
:height 600}
|
||||
:background {:type :pixel
|
||||
:size 300
|
||||
:color "0x000000"
|
||||
:bitmap "examples/backgrounds/haskell_1.bmp"}
|
||||
:font {:type "Calibre"
|
||||
:weight :plain
|
||||
:scale-type :linear
|
||||
:x-scale 20
|
||||
:y-scale 20
|
||||
:padding 5
|
||||
:colors ["0x00FF00" "0x0000FF" "0xFFAFFF"
|
||||
"0xFFEEFF" "0xEEEEEE"]}})]
|
||||
(write-to-file word-cloud "example_haskell.png"))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(defproject xtreak/clj-wordcloud "0.1.0-SNAPSHOT"
|
||||
(defproject xtreak/clj-wordcloud "0.0.1-SNAPSHOT"
|
||||
:description "A simple clojure wrapper around kumo for wordcloud generation"
|
||||
:url "http://github.com/tirkarthi/clj-wordcloud"
|
||||
:license {:name "MIT public license"
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
(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)
|
||||
(:import (java.awt Dimension Color)
|
||||
(java.awt.image BufferedImage)
|
||||
(javax.imageio ImageIO)
|
||||
(com.kennycason.kumo WordCloud WordFrequency LayeredWordCloud CollisionMode)
|
||||
(com.kennycason.kumo.bg CircleBackground RectangleBackground PixelBoundryBackground
|
||||
PixelBoundryBackground)
|
||||
(com.kennycason.kumo.palette ColorPalette)
|
||||
(com.kennycason.kumo.font KumoFont FontWeight)
|
||||
(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)]
|
||||
(let [type (get-in options [:background :type] :circle)
|
||||
size (get-in options [:background :size] 20)
|
||||
bitmap (get-in options [:background :bitmap])]
|
||||
(case type
|
||||
:circle
|
||||
(CircleBackground. size)
|
||||
:rectangle
|
||||
(RectangleBackground. dimension))))
|
||||
(RectangleBackground. dimension)
|
||||
:pixel
|
||||
(PixelBoundryBackground. (clojure.java.io/input-stream bitmap))
|
||||
(CircleBackground. size))))
|
||||
|
||||
|
||||
(defn- build-word-frequency
|
||||
|
@ -25,16 +33,79 @@
|
|||
(.add %1 (WordFrequency. (str word) count))))))
|
||||
|
||||
|
||||
(defn- build-font-scalar
|
||||
[options]
|
||||
(let [scale-type (get-in options [:font :scale-type] :linear)
|
||||
x-scale (get-in options [:font :x-scale] 10)
|
||||
y-scale (get-in options [:font :y-scale] 10)]
|
||||
(case scale-type
|
||||
:linear
|
||||
(LinearFontScalar. x-scale y-scale))))
|
||||
|
||||
|
||||
(defn- build-font
|
||||
[options]
|
||||
(let [font-map {:plain FontWeight/PLAIN, :bold FontWeight/BOLD, :italic FontWeight/ITALIC}
|
||||
font-type (get-in options [:font :type] "Arial")
|
||||
font-weight (get-in options [:font :weight] :plain)]
|
||||
(KumoFont. font-type (get font-map font-weight FontWeight/PLAIN))))
|
||||
|
||||
|
||||
(defn- build-dimension
|
||||
[options]
|
||||
(let [width (get-in options [:dimension :width] 100)
|
||||
height (get-in options [:dimension :height] 100)]
|
||||
(Dimension. width height)))
|
||||
|
||||
|
||||
(defn- build-color-palette
|
||||
[options]
|
||||
(let [default-colors ["0xFFFF00" "0x008000" "0x0000FF"]
|
||||
colors (->> default-colors
|
||||
(concat (get-in options [:font :colors] []))
|
||||
(take 5))
|
||||
color-palette (map #(Color/decode %1) colors)]
|
||||
(ColorPalette. color-palette)))
|
||||
|
||||
|
||||
(defn write-to-file
|
||||
"Writes the word cloud object as png image to the given location.
|
||||
Supply file name with extension png like example.png"
|
||||
|
||||
[word-cloud filename]
|
||||
(.writeToFile word-cloud filename))
|
||||
|
||||
|
||||
(defn word-cloud
|
||||
"
|
||||
Takes a map of string and the score along with options to return a wordcloud object
|
||||
Options spec as below :
|
||||
|
||||
{:dimension {:width 600 ; width of the image
|
||||
:height 600} ; height of the image
|
||||
:background {:type :circle ; type. Takes :circle, :pixel (bitmaps), :rectangle
|
||||
:size 300 ; size of the circle
|
||||
:color \"0x000000\"} ; Background color as hex
|
||||
:font {:type \"Calibre\" ; Font type
|
||||
:weight :plain ; Font weight. Takes :plain, :bold, :italic
|
||||
:scale-type :linear ; linear for now
|
||||
:x-scale 20 ; x scale of font
|
||||
:y-scale 20 ; y scale of font
|
||||
:padding 5}} ; padding between entries
|
||||
"
|
||||
[frequency-map options]
|
||||
(let [word-frequencies (build-word-frequency frequency-map)
|
||||
dimension (Dimension. (:width options 600) (:height options 600))
|
||||
dimension (build-dimension options)
|
||||
word-cloud (WordCloud. dimension CollisionMode/PIXEL_PERFECT)
|
||||
background (background-object options dimension)
|
||||
font (LinearFontScalar. (:font-x options 10) (:font-y options 40))]
|
||||
font-scalar (build-font-scalar options)
|
||||
kumo-font (build-font options)
|
||||
color-palette (build-color-palette options)]
|
||||
(doto word-cloud
|
||||
(.setPadding (:padding options 10))
|
||||
(.setPadding (get-in options [:font :padding] 10))
|
||||
(.setBackgroundColor (Color/decode (get-in options [:background :color] "0x000000")))
|
||||
(.setColorPalette color-palette)
|
||||
(.setBackground background)
|
||||
(.setFontScalar font)
|
||||
(.build word-frequencies)
|
||||
(.writeToFile (:filename options "test.png")))))
|
||||
(.setFontScalar font-scalar)
|
||||
(.setKumoFont kumo-font)
|
||||
(.build word-frequencies))))
|
||||
|
|
|
@ -9,9 +9,22 @@
|
|||
(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})]
|
||||
(let [freq-map (zipmap (range 100 130) (range 300))
|
||||
word-cloud (word-cloud freq-map
|
||||
{:dimension {:width 600
|
||||
:height 600}
|
||||
:background {:type :circle
|
||||
:size 300
|
||||
:color "0x000000"}
|
||||
:font {:type "Comic Sans MS"
|
||||
:scale-type :linear
|
||||
:x-scale 20
|
||||
:y-scale 20
|
||||
:padding 5
|
||||
:colors ["0x00FF00" "0x0000FF" "0xFFAFFF"
|
||||
"0xFFEEFF" "0xEEEEEE"]}})]
|
||||
(write-to-file word-cloud "sample.png")
|
||||
(is (= (get-size "sample.png") [600 600])))))
|
||||
|
|
Loading…
Reference in a new issue