Skip to content

Commit

Permalink
feat(rotation): Add rotate option
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanchen committed Apr 24, 2017
1 parent 4c31b6c commit a8f0b30
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 39 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ Note: if words element not contains color property, default will use [d3 schemeC
* `height=[number]`
* `width=[number]`
* `padding=[string]` -> [optional] padding for each word, defaults to `5`
* `rotate=[number, function]` -> [optional] rotation for each word, default to `~~(Math.random() * 2) * 60`
* `on-click=[function]` -> word clicked callback

## Directive Usage ##
```html
<div id="wordsCloud">
<word-cloud words="appCtrl.words" width="appCtrl.width" height="appCtrl.height" padding="5" on-click="appCtrl.wordClicked">
<word-cloud words="appCtrl.words" width="appCtrl.width" height="appCtrl.height" padding="5" rotate="appCtrl.rotate" on-click="appCtrl.wordClicked">
</word-cloud>
</div>
```
Expand All @@ -79,11 +80,16 @@ Inject `angular-d3-word-cloud` into angular module, set up some options to our c
self.height = $window.innerHeight * 0.5;
self.width = $element.find('#wordsCloud')[0].offsetWidth;
self.wordClicked = wordClicked;
self.rotate = rotate;
self.words = [
{text: 'Angular',size: 25, color: '#6d989e'},
{text: 'Angular2',size: 35, color: '#473fa3'}
]

function rotate() {
return ~~(Math.random() * 2) * 90;
}

function wordClicked(word){
alert('text: ' + word.text + ',size: ' + word.size);
}
Expand Down
41 changes: 23 additions & 18 deletions dist/angular-word-cloud.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* angular-d3-word-cloud 0.3.0
* angular-d3-word-cloud 0.3.1
* Running example base on express server
* https://weihanchen.github.io/angular-d3-word-cloud/
*
* Released under the MIT license.
*/

(function() {
(function () {
'use strict';
angular.module('angular-d3-word-cloud', [])
.directive('wordCloud', [wordCloud]);
Expand All @@ -15,10 +15,11 @@
return {
restrict: 'E',
scope: {
height: '=',
padding: '=?',
rotate: '=?',
words: '=',
width: '=',
height: '=',
onClick: '='
},
template: '<div></div>',
Expand All @@ -35,16 +36,18 @@
* layout grnerator by d3 and use drawListener to generator word cloud.
*/
var layout = d3.layout.cloud()
.rotate(function() {
return ~~(Math.random() * 2) * 60;
})
.fontSize(function(d) {

.fontSize(function (d) {
return d.size;
})
.on('end', drawListener);

$scope.$watch(watchParameters, watchListener, true);

function defaultRotate() {
return ~~(Math.random() * 2) * 60;
}

function drawListener(words) {
var wordsCloudSVGDiv = d3.select($element[0]);
var width = layout.size()[0];
Expand All @@ -58,40 +61,42 @@
.selectAll('text')
.data(words)
.enter().append('text')
.on('click', function(d) { //call back clicked element
.on('click', function (d) { //call back clicked element
if (self.onClick) self.onClick(d);
})
.on('mouseover', function() { //zoom in font-size
d3.select(this).transition().style('font-size', function(d) {
.on('mouseover', function () { //zoom in font-size
d3.select(this).transition().style('font-size', function (d) {
return d.size * 1.2 + 'px';
}).attr('opacity', 0.5);
})
.on('mouseout', function() {
d3.select(this).transition().style('font-size', function(d) {
.on('mouseout', function () {
d3.select(this).transition().style('font-size', function (d) {
return d.size + 'px';
}).attr('opacity', 1);
})
.style('font-size', function(d) {
.style('font-size', function (d) {
return d.size + 'px';
})
.style('font-family', 'Impact')
.style('fill', function(d, i) {
.style('fill', function (d, i) {
return d.color || fill(i);
})
.attr('text-anchor', 'middle')
.attr('cursor', 'pointer')
.transition()
.attr('transform', function(d) {
.attr('transform', function (d) {
return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
})
.text(function(d) {
.text(function (d) {
return d.text;
});
}

function updateLayout(width, height, words, padding) {
function updateLayout(width, height, words, padding, rotate) {
padding = padding || 5;
rotate = rotate || defaultRotate;
layout.size([width, height])
.rotate(rotate)
.padding(padding)
.words(words);
layout.start();
Expand All @@ -107,7 +112,7 @@
function watchListener(newVal) {
var parameters = angular.copy(newVal);
if (angular.isUndefined(parameters.words) || angular.isUndefined(parameters.width) || angular.isUndefined(parameters.height)) return;
updateLayout(parameters.width, parameters.height, parameters.words, parameters.padding);
updateLayout(parameters.width, parameters.height, parameters.words, parameters.padding, parameters.rotate);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion dist/angular-word-cloud.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ <h3>
<li><code>height=[number]</code></li>
<li><code>width=[number]</code></li>
<li><code>padding=[number]</code> -&gt; [optional] padding for each word, defaults to <code>5</code></li>
<li><code>rotate=[number, function]</code> -&gt; [optional] rotation for each word, defaults to <code>~~(Math.random() * 2) * 60</code></li>
<li>
<code>on-click=[function]</code> -&gt; word clicked callback</li>

Expand All @@ -71,7 +72,9 @@ <h3>
<a id="directive-usage" class="anchor" href="#directive-usage" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Directive Usage</h3>
<div class="highlight highlight-text-html-basic"><pre>&lt;<span class="pl-ent">div</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>wordsCloud<span class="pl-pds">"</span></span>&gt;
&lt;<span class="pl-ent">word</span><span class="pl-e">-cloud</span> <span class="pl-e">words</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.words<span class="pl-pds">"</span></span> <span class="pl-e">width</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.width<span class="pl-pds">"</span></span> <span class="pl-e">height</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.height<span class="pl-pds">"</span></span>
<span class="pl-e">padding</span>=<span class="pl-s"><span class="pl-pds">"</span>10<span class="pl-pds">"</span></span> <span class="pl-e">on-click</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.wordClicked<span class="pl-pds">"</span></span>&gt;
<span class="pl-e">padding</span>=<span class="pl-s"><span class="pl-pds">"</span>10<span class="pl-pds">"</span></span>
<span class="pl-e">rotate</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.rotate<span class="pl-pds">"</span></span>
<span class="pl-e">on-click</span>=<span class="pl-s"><span class="pl-pds">"</span>appCtrl.wordClicked<span class="pl-pds">"</span></span>&gt;
&lt;/<span class="pl-ent">word</span><span class="pl-e">-cloud</span>&gt;
&lt;/<span class="pl-ent">div</span>&gt;</pre></div>
<h3>
Expand All @@ -85,11 +88,18 @@ <h3>
<span class="pl-smi">self</span>.<span class="pl-c1">height</span> <span class="pl-k">=</span> <span class="pl-smi">$window</span>.<span class="pl-c1">innerHeight</span> <span class="pl-k">*</span> <span class="pl-c1">0.5</span>;
<span class="pl-smi">self</span>.<span class="pl-c1">width</span> <span class="pl-k">=</span> <span class="pl-smi">$element</span>.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>word-cloud<span class="pl-pds">'</span></span>)[<span class="pl-c1">0</span>].<span class="pl-smi">offsetWidth</span>;
<span class="pl-smi">self</span>.<span class="pl-smi">wordClicked</span> <span class="pl-k">=</span> wordClicked;
<span class="pl-smi">self</span>.<span class="pl-smi">rotate</span> <span class="pl-k">=</span> rotate;
<span class="pl-smi">self</span>.<span class="pl-smi">words</span> <span class="pl-k">=</span> [
{text<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>Angular<span class="pl-pds">'</span></span>,size<span class="pl-k">:</span> <span class="pl-c1">25</span>,color<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>#0e6632<span class="pl-pds">'</span></span>},
{text<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>Angular2<span class="pl-pds">'</span></span>,size<span class="pl-k">:</span> <span class="pl-c1">35</span>,color<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>#0e558<span class="pl-pds">'</span></span>}
]


<span class="pl-k">function</span> <span class="pl-en">rotate</span>(<span class="pl-smi"></span>){
<span class="pl-en">return</span> ~~(Math.random() * 2) * 90;
}

//custom rotate
<span class="pl-k">function</span> <span class="pl-en">wordClicked</span>(<span class="pl-smi">word</span>){
<span class="pl-en">alert</span>(word);
}
Expand All @@ -109,10 +119,14 @@ <h3><a id="example" class="anchor" href="#example" aria-hidden="true"><span aria
Custom words color: <input type="text" colorpicker colorpicker-position="top" ng-model="appCtrl.customColor" />
</div>
<p></p>
<div class="form-group">
Rotate: <input type="text" class="form-control" placeholder="Please input rotate number" ng-model="appCtrl.editRotate">
</div>
<p></p>
<button class="btn-sm" ng-click="appCtrl.generateWords()"><i class="fa fa-cloud" aria-hidden="true"></i> Generate</button>
<p></p>
<div id="wordsCloud">
<word-cloud words="appCtrl.words" width="appCtrl.width" height="appCtrl.height" padding="appCtrl.padding" on-click="appCtrl.wordClicked">
<word-cloud words="appCtrl.words" width="appCtrl.width" height="appCtrl.height" padding="appCtrl.padding" rotate="appCtrl.rotate" on-click="appCtrl.wordClicked">
</word-cloud>
</div>
<!--advance usage-->
Expand Down
1 change: 1 addition & 0 deletions docs/js/controllers/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
self.width = width;
self.height = height;
self.padding = self.editPadding;
self.rotate = self.editRotate;
});
}

Expand Down
39 changes: 22 additions & 17 deletions src/angular-word-cloud.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(function() {
(function () {
'use strict';
angular.module('angular-d3-word-cloud', [])
.directive('wordCloud', [wordCloud]);
Expand All @@ -7,10 +7,11 @@
return {
restrict: 'E',
scope: {
height: '=',
padding: '=?',
rotate: '=?',
words: '=',
width: '=',
height: '=',
onClick: '='
},
template: '<div></div>',
Expand All @@ -27,16 +28,18 @@
* layout grnerator by d3 and use drawListener to generator word cloud.
*/
var layout = d3.layout.cloud()
.rotate(function() {
return ~~(Math.random() * 2) * 60;
})
.fontSize(function(d) {

.fontSize(function (d) {
return d.size;
})
.on('end', drawListener);

$scope.$watch(watchParameters, watchListener, true);

function defaultRotate() {
return ~~(Math.random() * 2) * 60;
}

function drawListener(words) {
var wordsCloudSVGDiv = d3.select($element[0]);
var width = layout.size()[0];
Expand All @@ -50,40 +53,42 @@
.selectAll('text')
.data(words)
.enter().append('text')
.on('click', function(d) { //call back clicked element
.on('click', function (d) { //call back clicked element
if (self.onClick) self.onClick(d);
})
.on('mouseover', function() { //zoom in font-size
d3.select(this).transition().style('font-size', function(d) {
.on('mouseover', function () { //zoom in font-size
d3.select(this).transition().style('font-size', function (d) {
return d.size * 1.2 + 'px';
}).attr('opacity', 0.5);
})
.on('mouseout', function() {
d3.select(this).transition().style('font-size', function(d) {
.on('mouseout', function () {
d3.select(this).transition().style('font-size', function (d) {
return d.size + 'px';
}).attr('opacity', 1);
})
.style('font-size', function(d) {
.style('font-size', function (d) {
return d.size + 'px';
})
.style('font-family', 'Impact')
.style('fill', function(d, i) {
.style('fill', function (d, i) {
return d.color || fill(i);
})
.attr('text-anchor', 'middle')
.attr('cursor', 'pointer')
.transition()
.attr('transform', function(d) {
.attr('transform', function (d) {
return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
})
.text(function(d) {
.text(function (d) {
return d.text;
});
}

function updateLayout(width, height, words, padding) {
function updateLayout(width, height, words, padding, rotate) {
padding = padding || 5;
rotate = rotate || defaultRotate;
layout.size([width, height])
.rotate(rotate)
.padding(padding)
.words(words);
layout.start();
Expand All @@ -99,7 +104,7 @@
function watchListener(newVal) {
var parameters = angular.copy(newVal);
if (angular.isUndefined(parameters.words) || angular.isUndefined(parameters.width) || angular.isUndefined(parameters.height)) return;
updateLayout(parameters.width, parameters.height, parameters.words, parameters.padding);
updateLayout(parameters.width, parameters.height, parameters.words, parameters.padding, parameters.rotate);
}
}
}
Expand Down

0 comments on commit a8f0b30

Please sign in to comment.