ワールドクラウドを作成するhtmlファイルの作成
[public]ディレクトリーを右クリックし、[新規]→[ファイル]を選択し、cloud.htmlというファイルを作成します。
Node-REDからデータを受信し、ワードクラウドを描画するためには、WebSocketを利用します。「cloud.html」は次のように記述します。
■cloud.htmlに記述するHTMLコード
<!DOCTYPE html>
<meta charset="utf-8">
<title>Node-REDでWord Cloud</title>
<body align=middle>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="./d3.layout.cloud.js"></script>
<script>
function wordCloud(selector) {
var fill = d3.scale.category20b();
var svg = d3.select(selector).append("svg")
.attr("width", 1024)
.attr("height", 768)
.append("g")
.attr("transform", "translate(512,384)");
function draw(words) {
var cloud = svg.selectAll("g text")
.data(words, function(d) { return d.text; })
//Entering words
cloud.enter()
.append("text")
.style("font-family", "Impact")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr('font-size', 2)
.text(function(d) { return d.text; });
//Entering and existing words
cloud.transition()
.duration(600)
.style("font-size", function(d) { return d.size + "px"; })
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.style("fill-opacity", 1);
//Exiting words
cloud.exit()
.transition()
.duration(200)
.style('fill-opacity', 1e-6)
.attr('font-size', 1)
.remove();
}
return {
//Recompute the word cloud for a new set of words. This method will
// asynchronously call draw when the layout has been computed.
update: function(words) {
d3.layout.cloud().size([1024, 768])
.words(words)
.padding(2)
.rotate(function() { return ~~(Math.random() * -2) * 90; })
.font("Impact")
.fontSize(function(d) { return d.size; })
.on("end", draw)
.start();
}
}
}
var myWordCloud = wordCloud('body');
var ws;
var wsUri = "ws://<yourapp>.mybluemix.net/ws/wordcloud";
function start(wsUri) { // websocketを生成
ws = new WebSocket(wsUri);
ws.onopen = function(evt) {
console.log("CONNECTED");
};
ws.onclose = function(evt) {
console.log("DISCONNECTED");
setTimeout(function(){ start(wsUri) }, 3000);
}
ws.onmessage = function (evt) {
var wds = JSON.parse(evt.data);
keysSorted = Object.keys(wds).sort(function(a,b){return wds[a]-wds[b]});
var wrds=[];
for (var key in wds) {
wrds.push({ text:key, size:10 + 20 * wds[key] });
}
myWordCloud.update(wrds);
}
ws.onerror = function(evt) {
console.log("ERROR",evt);
}
}
start(wsUri);
</script>
</body>
HTMLの記述が終わったら保存して、左側にある鉛筆アイコンの下「Git リポジトリー」アイコンをクリックすると「Git」ページが表示されます。
編集したコードを右側のウィンドウで[コミット]し、左側上のウィンドウで[プッシュ]すると、自動的に[BUILD & DEPLOY]ジョブが動作し、Bluemixアプリケーションへのデプロイが開始されます。進捗は[BUILD & DEPLOY]ページから確認できます。
デプロイ後、[http://< host名 > .mybluemix.net/cloud.html]にアクセスすると空白ページが生成されていることが確認できます。この時点では、まだNode-RED側からTwitterデータを送信していないため、特に変化は起きません。
ワードクラウドの生成
最後に、Node-REDとcloud.htmlがデータ連携できるように、Node-REDにWebSocketノードを追加します。
Node-REDのフロー編集画面左の[output]から[websocket]を選択して配置します。
cloud.htmlで「/ws/wordcloud」からデータを受け取るように指定してあるため、Node-REDからの出力先も「/wss/wordcloud」を指定します。
WebSocketノードにWordCountノードをつなぎます。
Node-RED上で[Deploy]した後、再度cloud.htmlページを開いてみると、Twitterから収集し、カウントした単語がワードクラウドとしてビジュアル化されます。
※ ※ ※
BluemixとNode-REDを利用して、従来では難しかったIoTアプリにも必要なWebサービス間の連携やデータ連携を含むWebアプリケーションを簡単に作成できるようになりました。次回は、IoTアプリ作成に利用するWatsonについて紹介します。
著者:原田一樹(はらだ・かずき)
AWSやAzure、Bluemixなどのクラウド技術と、AIやIoTなどの新技術実証業務に従事。「PaaS」と「アジャイル開発」を組み合わせたDevOps手法を体系化し、革新的なサービスやビジネスを企画・開発・運用したいお客様を支援している。
また、Bluemixユーザー会「BMXUG」のコミュニテイリーダーを務めており、Bluemixのコアな技術情報の発信と普及活動に貢献している。2015年5月の「BluemixHack @XCITE Spring2015」と2015年9月の「IBM BluemixChallenge 2015」、2015年12月の「Watson 日本語版ハッカソン」の3つのコンテストすべてで最優秀賞を獲得した実績を持つ。