この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回に引き続き、RailsでAdminLTEをテンプレートとして使用する方法についてです。今回は前回解説したアプリのクライアント側の実装方法について書いていきたいと思います。
実装方法
1.フォルダ作成
まずはアプリのフォルダを作成します。前回書いたようにサーバとクライアントではフォルダを分けるので、アプリのルートとなるフォルダ配下に「client」フォルダを作成します。
2.ライブラリの配置
AdminLTEのページの「Download」ボタンを押下してライブラリとサンプルソースをダウンロードします。今回はAdminLTE自体のソースを変更しないので「Ready」の方をダウンロードしました。
clientフォルダ内にライブラリを配置するフォルダを作成します。前回書いたようにlibフォルダを作成し、その中にadminlteフォルダを作成してください。
ダウンロードしたzipを解凍すると、中にライブラリとサンプルソースがあります。これらから「bootstrap」「dist」「plugins」フォルダをlib/adminlteフォルダにコピーします。以下の様なフォルダ構成になるはずです。
.
├── client
│ ├── lib
│ │ └── adminlte
│ │ ├── bootstrap
│ │ ├── dist
│ │ ├── plugins
3.starter.html
先ほどのサンプルにstarter.htmlがあります。これをclientフォルダへコピーします。そしてlib/adminlteフォルダ内のライブラリを参照するよう、html内のstylesheetやjavascriptの参照先を変更します。以下のようになります。
<!DOCTYPE html>
<!--
This is a starter template page. Use this page to start your new project from
scratch. This page gets rid of all links and provides the needed markup only.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | Starter</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="lib/adminlte/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="lib/adminlte/dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. We have chosen the skin-blue for this starter
page. However, you can choose any other skin. Make sure you
apply the skin class to the body tag so the changes take effect.
-->
<link rel="stylesheet" href="lib/adminlte/dist/css/skins/skin-blue.min.css">
(中略)
<!DOCTYPE html>
<!--
This is a starter template page. Use this page to start your new project from
scratch. This page gets rid of all links and provides the needed markup only.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | Starter</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="lib/adminlte/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="lib/adminlte/dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. We have chosen the skin-blue for this starter
page. However, you can choose any other skin. Make sure you
apply the skin class to the body tag so the changes take effect.
-->
<link rel="stylesheet" href="lib/adminlte/dist/css/skins/skin-blue.min.css">
4.chartjs.html
chartjs.htmlについてもサンプルから流用します。pages/chartsフォルダを作成し、サンプルのchartjs.htmlをコピーしてください。
コピーしたらstarter.htmlと同様、stylesheetやjavascriptの参照先を変更します。以下のようになります。(全ての修正箇所は網羅できていないかもしれません)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | ChartJS</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="../../lib/adminlte/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="../../lib/adminlte/dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="../../lib/adminlte/dist/css/skins/_all-skins.min.css">
(中略)
<!-- jQuery 2.1.4 -->
<script src="../../lib/adminlte/plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="../../lib/adminlte/bootstrap/js/bootstrap.min.js"></script>
<!-- ChartJS 1.0.1 -->
<script src="../../lib/adminlte/plugins/chartjs/Chart.min.js"></script>
<!-- FastClick -->
<script src="../../lib/adminlte/plugins/fastclick/fastclick.min.js"></script>
<!-- AdminLTE App -->
<script src="../../lib/adminlte/dist/js/app.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="../../lib/adminlte/dist/js/demo.js"></script>
(以下略)
次にデータの取得とグラフの表示です。サンプルではJavaScriptで固定のデータを表示していますが、chartjs.htmlではサーバよりデータを取得するようにします。サーバとの通信はベーシックなjQueryで行います(jQueryがAdminLTEのライブラリに入っていることもある)。以下の様なソースとなります。
<script>
$(function () {
$.getJSON(
'http://localhost:3000/api/v1/pages/charts/chartjs/area_chart.json',
function(data) {
//--------------
//- AREA CHART -
//--------------
// Get context with jQuery - using jQuery's .get() method.
var areaChartCanvas = $("#areaChart").get(0).getContext("2d");
// This will get the first returned node in the jQuery collection.
var areaChart = new Chart(areaChartCanvas);
var areaChartData = data;
var areaChartOptions = {
//Boolean - If we should show the scale at all
showScale: true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines: false,
//String - Colour of the grid lines
scaleGridLineColor: "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth: 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - Whether the line is curved between points
bezierCurve: true,
//Number - Tension of the bezier curve between points
bezierCurveTension: 0.3,
//Boolean - Whether to show a dot for each point
pointDot: false,
//Number - Radius of each point dot in pixels
pointDotRadius: 4,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth: 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius: 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke: true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth: 2,
//Boolean - Whether to fill the dataset with a color
datasetFill: true,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].lineColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
//Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
//Boolean - whether to make the chart responsive to window resizing
responsive: true
};
//Create the line chart
areaChart.Line(areaChartData, areaChartOptions);
//-------------
//- LINE CHART -
//--------------
var lineChartCanvas = $("#lineChart").get(0).getContext("2d");
var lineChart = new Chart(lineChartCanvas);
var lineChartOptions = areaChartOptions;
lineChartOptions.datasetFill = false;
lineChart.Line(areaChartData, lineChartOptions);
//-------------
//- BAR CHART -
//-------------
var barChartCanvas = $("#barChart").get(0).getContext("2d");
var barChart = new Chart(barChartCanvas);
var barChartData = areaChartData;
barChartData.datasets[1].fillColor = "#00a65a";
barChartData.datasets[1].strokeColor = "#00a65a";
barChartData.datasets[1].pointColor = "#00a65a";
var barChartOptions = {
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero: true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines: true,
//String - Colour of the grid lines
scaleGridLineColor: "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth: 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke: true,
//Number - Pixel width of the bar stroke
barStrokeWidth: 2,
//Number - Spacing between each of the X value sets
barValueSpacing: 5,
//Number - Spacing between data sets within X values
barDatasetSpacing: 1,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
//Boolean - whether to make the chart responsive
responsive: true,
maintainAspectRatio: true
};
barChartOptions.datasetFill = false;
barChart.Bar(barChartData, barChartOptions);
}
);
$.getJSON(
'http://localhost:3000/api/v1/pages/charts/chartjs/pie.json',
function(data) {
//-------------
//- PIE CHART -
//-------------
// Get context with jQuery - using jQuery's .get() method.
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var pieChart = new Chart(pieChartCanvas);
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//Boolean - whether to make the chart responsive to window resizing
responsive: true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(data, pieOptions);
}
);
});
</script>
ちょっと長いですが、大きく2つに分かれます。getJSON()で囲まれている3行目〜110行目までと、112行目以降です。
3行目〜110行目までは「http://localhost:3000/api/v1/pages/charts/chartjs/area_chart.json」にアクセスし、コールバック内で取得したJSONデータをAreaChart、LineChart、BarChartに設定しています。
112行目は「http://localhost:3000/api/v1/pages/charts/chartjs/pie.json」にアクセスし、コールバック内でPieチャートにデータを設定しています。
今回は「http://localhost:3000〜」とベタ書きしていますが、実案件ではこの辺は定数などに切り出した方がいいでしょう。
5.クライアントをWebサーバで動かす
クライアントをWebサーバ内で動かし、http〜でアクセスする方法についてです。starter.htmlについてはサーバと通信していないので、クライアントのみで動かすことができます。いろいろなWebサーバがありますが、今回はRubyのみで動かすことできる「WEBrick」を使用しました。ターミナルでclientフォルダへ移動し、以下のコマンドを実行します。
$ ruby -rwebrick -e 'WEBrick::HTTPServer.new({:DocumentRoot => "./", :Port => 8888}).start'
ポートは8888で起動しています。この状態でブラウザより「http://localhost:8888/starter.html」でアクセスすると、以下の様が画面が表示されるはずです。
まとめ
クライアント側の実装について見てきました。クライアントをサーバから分離したことにより、サンプルから流用したhtmlファイルの修正箇所が少なく済んだかと思います。特にchartjs.htmlのJavaScriptについては、getJSON()のコールバック内のソースはサンプルをほとんど変更することなく実装できています。
次回、サーバ側の実装について書いていきたいと思います。