4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

require.jsを使ってchart.jsとannotation,realtimeプラグインをYellowfin上で使う

Last updated at Posted at 2020-07-21

realtime-annotation.gif

はじめに

Yellowfin(BIツール)でIoTデータを表示する際にグラフを作成するにあたって、リアルタイムで表現できるものがないか探していたら、chartjs-plugin-streamingで実現できることがわかり、早速手を付けたのですが、なかなかうまく実装できなかったので記事にしてみました。・・・sampleのPlainJSはすごく簡単なのに:innocent:
アノテーションプラグインでは、limitとしてvalue90の値のところにオレンジの横線をいれ、90以上に赤の薄いboxと-90以下に青の薄いboxを置いています。

Yellowfinでは前からレポートにJSChartを組み込むことで自分でライブラリを読み込んでグラフを描画できたのですが、v9からダッシュボード上にドラッグアンドドロップでレポートを配置したり、より柔軟にデザインできるようになったので、せっかくなのでダッシュボードにHTMLウィジェットを置いて実装していきます。

※データはchartjs-plugin-streamingのサンプル通り、時間はDate.now()、値は-100〜100までの値をとる関数を使用しています。

準備

各ライブラリは下記に配置していきます。YellowfinではROOTフォルダがwebserver上の/になるので適宜実装したい環境によって読み替えてください。
Yellowfin9.2/appserver/webapps/ROOT/js/chartingLibraries
moment.js 使用したバージョン(2.24.0)
Chart.js 使用したバージョン(2.8.0)
chartjs-plugin-annotation.js 使用したバージョン(0.5.7)
chartjs-plugin-streaming.js 使用したバージョン(1.8.0)

今回はこの4つのライブラリとそのプラグインを使っていきます。

HTMLタブ

基本的にはdivとcanvasタグを入れるだけです。YellowfinではHTMLウィジェットを置いて、コードモードにすることで、canvas-areaタグの中に配置します。
image.png

htmlタブ
<canvas-area xmlns="http://www.w3.org/1999/xhtml" canvas-uuid="22a3ee56-fc20-4c23-82d5-ea659a0c2835">
    <custom-html widget-uuid="8bc6dfd7-6b0c-4023-9792-6fe0fa11a066" width="1001" height="785" top="0" left="0" rotation="0" name="カスタムHTML" on-click="none" style="z-index: 1">
        <div>
		    <canvas id="myChart" width="1000" height="600"></canvas>
	    </div>
    </custom-html>
</canvas-area>

JSタブ

ここが一番しんどかったです・・。require.jsの仕様やjavascriptの勉強不足ですね。。まだまだ理解できてないです。。
大事なrequire.configの部分はこんな感じです。
image.png
shimのdepsを指定することで、jsの依存性を解決し、読み込む順番をコントロールできます。これを使う方法以外ではrequire関数のネストしかないのかな。
後は、mapで各chart.jsプラグイン中で使われるchart.jsを紐つけます。

全体としてはこんな感じになります。

JSタブ.js

require.config({
  paths: {
    moment: "js/chartingLibraries/moment",
    chart: "js/chartingLibraries/Chart",
    annotation: "js/chartingLibraries/chartjs-plugin-annotation",
    streaming: "js/chartingLibraries/chartjs-plugin-streaming"
  },
  shim: {
    chart: {
      exports: "C",
      deps: ["moment"]
    },
    annotation: {
      exports: "C",
      deps: ["chart"]
    },
    streaming: {
      exports: "C",
    }
  },

  map: {
    annotation: {
      "chart.js": "chart"
    },
    streaming: {
      "chart.js": "chart"
    }
  }
});

require(["moment", "chart","annotation","streaming"], function(moment, chart) {

var chartColors = {
	red: 'rgb(255, 99, 132)',
	orange: 'rgb(255, 159, 64)',
	yellow: 'rgb(255, 205, 86)',
	green: 'rgb(75, 192, 192)',
	blue: 'rgb(54, 162, 235)',
	purple: 'rgb(153, 102, 255)',
	grey: 'rgb(201, 203, 207)'
};

function randomScalingFactor() {
	return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
}

function onRefresh(chart) {
	chart.config.data.datasets.forEach(function(dataset) {
		dataset.data.push({
			x: Date.now(),
			y: randomScalingFactor()
		});
	});
}

var color = chart.helpers.color;

var config = {
	type: 'line',
	data: {
		datasets: [{
			label: 'データセット1',
			backgroundColor: chartColors.red,
			borderColor: chartColors.red,
			fill: false,
			lineTension: 0,
			borderDash: [8, 4],
			data: []
		}, {
			label: 'データセット2',
			backgroundColor: chartColors.blue,
			borderColor: chartColors.blue,
			fill: false,
			cubicInterpolationMode: 'monotone',
			data: []
		}]
	},
	options: {
		title: {
			display: true,
			text: 'annotation and realtime plugin sample'
		},
		scales: {
			xAxes: [{
				type: 'realtime',
				realtime: {
					duration: 20000,
					refresh: 1000,
					delay: 2000,
					onRefresh: onRefresh
				}
			}],
			yAxes: [{
				type: 'linear',
				display: true,
				scaleLabel: {
					display: true,
					labelString: 'value'
				}
			}]
		},
		tooltips: {
			mode: 'nearest',
			intersect: false
		},
		hover: {
			mode: 'nearest',
			intersect: false
		},
		annotation: {
			events: ['click'],
			annotations: [
				{
					drawTime: 'afterDatasetsDraw',
					id: 'hline',
					type: 'line',
					mode: 'horizontal',
					scaleID: 'y-axis-0',
					value: 90,//randomScalingFactor(),
					borderColor: 'rgb(255, 159, 64)',//'black',
					borderWidth: 5,
					label: {
						backgroundColor: 'red',
						content: 'limit',
						enabled: true
					},
					onClick: function(e) {
						console.log('Annotation', e.type, this);
					}
				},
				{
					drawTime: 'beforeDatasetsDraw',
					type: 'box',
					yScaleID: 'y-axis-0',
					yMin: 90,//randomScalingFactor(),
					yMax: 100,//randomScalingFactor(),
					backgroundColor: color(chartColors.red).alpha(0.25).rgbString(),
					borderColor: color(chartColors.purple),
					borderWidth: 1,
					onClick: function(e) {
						console.log('Box', e.type, this);
					}
				},
				{
					drawTime: 'beforeDatasetsDraw',
					type: 'box',
					yScaleID: 'y-axis-0',
					yMin: -90,//randomScalingFactor(),
					yMax: -100,//randomScalingFactor(),
					backgroundColor: color(chartColors.blue).alpha(0.25).rgbString(),
					borderColor: color(chartColors.purple),
					borderWidth: 1,
					onClick: function(e) {
						console.log('Box', e.type, this);
					}
				}
			]
		}
		
	}
};

	var ctx = document.getElementById('myChart').getContext('2d');
	window.myChart = new Chart(ctx, config);

});

おわりに

実際のデータで使用するには、データを取得するAPIやプログラムにアクセスして、それをparseしてdataにpushすることになるのでもう少し手をかけないといけないですね。
そして、もっといい方法があれば知りたいです。。プラグインをたくさん入れようとするとさらにconfigの設定が難しくて・・
他の環境で動かない場合は、require.configのpathsかmapのフォルダパスを調整すればいい気がします。1

参考にさせて頂いたところ

https://www.chartjs.org/
https://nagix.github.io/chartjs-plugin-streaming/ja/
Chart.js でリアルタイムストリーミングデータをグラフ化

  1. こちらも参考にしました : What is the syntax for require.config for chartjs-plugin-streaming and dependencies using RequireJS?(https://stackoverflow.com/

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?