初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
1章:短編集
2章:診断系コンテンツ
3章:製品抽出系コンテンツ
番外:Simulation Game

点数表の作成

概要

エクセルで作成した得点表(csv形式)を読み込む

製品抽出では、選択した回答に応じて各製品(Lシリーズ,Eシリーズなど)ごとに得点を加えていきます。これを実現するためには得点表が必要となるので、今回は得点表の作成について説明します。診断系コンテンツの得点の仕組みよりも複雑になるため、エクセルで作成したcsvデータを読み込んで利用するようにしました。

jQueryで外部データを読み込む場合はxml(時にはjson)が一般的なのですが、xmlを作成するのは結構面倒なので私はcsvをよく利用します。仕事でも簡単なデータ修正はクライアント(依頼主)が修正したいという要望も多いので、エクセルから書き出せるcsvは有用なのです。

解説

csvデータの確認と改行コード/文字コードについての注意

今回利用する得点表のcsvは「data.csv」です。このデータをエクセルで開くと以下の様になっています。
ブラウザの設定によってはクリックすると直接エクセルが開くかもしれません。


まず「A列」を確認して下さい。ここには質問の選択肢のIDが書かれています。選択肢のIDは以下の様にhtmlタグ内にid属性として設定されていたことを思い出して下さい。

<li id="0_0">リビング</li><li id="0_1">書斎/仕事部屋</li><li id="0_2">寝室</li>

続いて「1行目」を確認して下さい。ここには今回登場する機種の名前が書かれています。この行はjQueryでは利用しません。編集する人が理解しやすいように書いています。

表の見方は、例えば1問目で1番目の選択肢(idは「0_0」)が選択された場合は、「vaio tap」に20点、「vaio duo」に10点、「tシリーズ」に8点と、機種ごとに加算される得点が記載されています。
※後述の文字コードの件があるので、データ内に2バイト文字を使うのは避けた方がよいでしょう。

また、このcsvデータはwindowsのエクセルで書き出されることを前提としています。というのはWindowsやMac、Unixは改行コードが異なるため、読み込んだ後の処理に違いが生じるからです(これについては次項で詳しく説明します)。ですのでwindows以外の機種で作成した場合は「改行コード」を変更できるテキストエディタでwindowsの改行コードに変更してから利用して下さい

さらに文字コードについても注意してください。jQueryは日本で一般的なjis(shift-jis)に対応していないため文字コードをUTF-8に変換する必要があります。そのためエクセルで書き出したcsvデータはテキストエディタなどで文字コードをUTF-8に変換する必要があります

しかしjQueryでshift jisを読み込むこともできるようです。
→参考サイト:IEでもできた! jQuery.ajaxでShift JIS(sjis)の外部HTMLを読み込む時の文字化け回避方法

どのようなデータに変換するか?

csvデータのままではjQueryで有効に利用できません。ですのでデータを利用しやすいように変換します。今回は選択肢ごとにデータを得られるように以下の様なobjectオブジェクトにしようと思います。
得点に関するデータなので以下の様に「scoreObj」と名付けました。

var scoreObj = new Object();
scoreObj.q0_0 = [20,10,8,15,8,8];
scoreObj.q0_1 = [8,12,12,20,12,12];
scoreObj.q0_2 = [5,12,15,5,12,12];

プロパティの部分に選択肢のIDを利用しました。識別子は数値から初めてはいけないので(javaScriptの場合は機能すると思いますが)上記のように「q + ID名」と先頭にqを追加したプロパティ名にしました。
qはquestionの略で、q0_0なら質問0の選択肢0というイメージから付けています。

そして値として得点の配列を代入するようにしました。これで選択肢から得点表のデータを得やすくなります。さらに得点を管理しやすくするには、配列ではなく以下の様に製品名を付けてobjectオブジェクトとして利用すべきなのですが、そうすると少し複雑になるので今回は配列にしました。

var scoreObj = new Object();
scoreObj.q0_0 = {tap:20, duo:10, t:8, l:15, s:8, e:8};
scoreObj.q0_1 = {tap:8, duo:12, t:12, l:20, s:12, e:12};
scoreObj.q0_2 = {tap:5, duo:12, t:15, l:5, s:12, e:12};

次項ではjQueryを利用して、実際にcsvデータを読込ます。

csvデータの読込

サンプル(score/01.html)を開くとアラートが表示されますが、とりあえずは閉じてjQueryに以下の処理が追加されているのを確認して下さい。jQueryではgetメソッドを利用して簡単に外部データを読み込むことができます。構文としては以下の様に第1引数に読み込むデータのURLを設定して、第2引数に読込が完了したら実行したい処理をfunctionとして設定します。

//---外部データの読込
$.get("../images/data.csv", function(myData){
	alert(myData);
});

読み込まれたデータはfunctionに引数として渡されます。上記では変数「myData」で引数を受け取り、アラートで表示するようにしています。ですので最初にアラートが表示されたのです。アラートの内容とdata.csvの内容が同じ事を確認して下さい。

データを改行コードで分割して配列に格納

人間の視点から見ると選択肢のデータは行によって区切られていますが、プログラム的には区切られていません。ですので、まずは選択肢のデータごとに区切ります。ここで利用するのが改行コードです(目には見えませんが、行の終わりには必ず改行コードがあります)。ですから最初の項目でwindowsの改行コードにすることについて説明したのです。

サンプル(score/02.html)を開くとアラートがたくさん表示されますが、とりあえず全てを閉じてjQueryが以下の様に変更されているのを確認して下さい。

$.get("../images/data.csv", function(myData){
	//---winの改行コードで分割して配列に変換
	var csvData = myData.split("\r\n");			
	//---配列になっているか確認
	for (var i=0; i<csvData.length; i++) {
		alert(csvData[i]);
	}
});

ポイントは2行目です。javaScriptのsplitメソッドを利用してwindowsの改行コード(\r\n)でデータを分割して配列に変換しています。変換された配列は変数csvDataに代入され、5〜7行目のfor文の処理で内容を確認します。

for文では変数iを0から配列csvDataの要素数まで繰り返すようにして、アラートで配列の各要素を表示するようにしました。結果として、行ごと(つまり選択肢のデータごと)にデータの内容が表示されます。しかし1行目は選択肢のデータではなく製品名のリストです。次項では、この1行目から製品名のリストを作成します。

製品名リストの作成

scoreObjに設定する配列は点数だけで、どの得点がどの製品の得点か分かりません。そこで配列内の得点が、どのような製品の順番で格納されているか把握する必要があります。製品の順番はエクセルの1行目に記されていますから、これを利用します。

サンプル(score/03.html)を開いてjQueryが以下のように変更されているのを確認して下さい。2行目の改行コードで分割したcsvDataの部分はscore/02.htmlと同じですが、それ以降が異なります。

$.get("../images/data.csv", function(myData){
	var csvData = myData.split("\r\n");
	//---製品名を配列に変換
	productData = csvData[0].split(",");
	//---最初のデータ(A列)は空なので削除
	productData.shift();
	alert(productData);
});

まず4行目では最初の行であるcsvData[0]を「カンマ(,)」で分解して配列に変換します。1行目のデータは最初の部分(エクセルではA列1行)が空白なので、この部分を削除します。配列で最初の要素を削除するのはjavaScriptのshiftメソッドなので、6行目でこれを利用して削除しました。

結果として製品名のリスト(変数productData)がアラートで表示されます。
次項は2行目以降のデータをobjectオブジェクトにする準備としてA列のデータからプロパティ名を作成します。

プロパティ名の作成

前述したように、プロパティ名は「q+選択肢のID」と名付けていきます。サンプル(score/04.html)を開いて、製品リストの作成部分の下に以下の処理が追加されているのを確認して下さい。

score/02.htmlでfor文を利用して配列の中を確認した処理と似ていますが、1行目で変数iを「0」ではなく「1」から始めていることに注意して下さい。最初の行(0行目)は製品名なので利用しません。

for (var i=1; i<csvData.length; i++) {
	var itemData = csvData[i].split(",");
	var qID = "q" + itemData.shift();//プロパティ名の作成
	alert(qID);
}

続いて2行目では行毎に分割されたデータ(csvData[i])を取り出して、splitメソッドを利用して「カンマ(,)」で区切り配列に格納します。この配列の最初の要素がA列のデータですから、5行目でshiftメソッドを利用して、このデータを取得し、先頭に「q」の文字を追加してプロパティ名とします。
javaScriptのshiftメソッドは先頭の要素を削除するだけでなく、その先頭の要素を返値として返します。

作成したプロパティ名は変数qIDに代入してアラートで表示するようにしました。結果として、q0_0〜q4_2までのプロパティ名が順々に表示されていきます。

得点表のobjectオブジェクトの完成

前項で作成したプロパティを得点表用のobjectオブジェクトに設定し、その値として製品ごとの得点リストを代入します(下図を参考にしてください)。

では実際にjQueryで、どのように実現するかを確認します。サンプル(score/05.html)を開いて、jQueryが以下の様に変更されているのを確認して下さい。

scoreObj = new Object();//---得点表objectオブジェクトを作成
for (var i=1; i<csvData.length; i++) {
	var itemData = csvData[i].split(",");
	var qID = "q" + itemData.shift();
	scoreObj[qID] = itemData;//---データの設定
}
alert(scoreObj.q0_0)//---確認

まず1行目で得点表用のobjectオブジェクトとしてscoreObjを作成しました。for文の処理は5行目の部分を追加しただけです。4行目の部分は変更無いのですがjavaScriptのshiftメソッド(前項/前々項で利用)について、まとめておきます。shiftメソッドは先頭の要素を削除し、その先頭の要素を返値として返します。つまり4行目で配列itemDataからは最初の要素(プロパティ名)が削除され、得点表部分のみになるのです。

ですから5行目でプロパティの値として、配列itemDataをそのまま代入することができるのです。また5行目で、objectオブジェクトのプロパティを[ ]を利用して設定する構文はサンプル-カテゴリ切替(3)の「メモ」の部分で説明しているので、忘れてしまった方は確認しておいて下さい。

そして7行目で、プロパティに値が設定されているかを確認しています。サンプルではscoreObjのq0_0プロパティの値だけ表示するようにしました。結果としてdata.csvのq0_0の行の得点表が表示されます。

これでcsvデータをjQueryで利用しやすい形式に変換できたので、次回は実際に製品ごとの得点を算出します。

今回作成した2つのデータ

最後に今回csvデータから作成した2つのデータを確認しておきます。

scoreObj - 得点の配列を記憶したobjectオブジェクト
このobjectオブジェクトを利用して、選ばれた選択肢から各製品の得点を取得します。
var scoreObj = new Object();
scoreObj.q0_0 = [20,10,8,15,8,8];
scoreObj.q0_1 = [8,12,12,20,12,12];
scoreObj.q0_2 = [5,12,15,5,12,12];
productData - 製品の順番リスト
上記scoreObjの配列に内に設定された得点は「何番目の要素が、どの製品の得点か」わかりません。そこで得点の順番が保存された、このproductDataが必要になるのです。これはサンプル(score/03.html)で作成しています。
productData = [tap,duo,t,l,s,e];

次回はこの2つのデータを利用して、選択された選択肢から各製品の得点を算出します。