MediaWiki:Lipoquality.js: Difference between revisions

No edit summary
No edit summary
Line 1: Line 1:
// Last-Update: 2018/08/01
// html /////////////////////////////////////////////////////////////////////////////////////////////////////////
// html /////////////////////////////////////////////////////////////////////////////////////////////////////////
// <span id="search"></span><span id="show"></span>
// <span id="search"></span><span id="show"></span>
Line 84: Line 85:
var chain        = "";
var chain        = "";
var chart        = "";
var chart        = "";
var species      = "";
// パラメータの取得
// パラメータの取得
// ss = SampleSource - デフォルトはAll
// ss = SampleSource - デフォルトはAll
Line 104: Line 106:
} else if(name == "ct"){ // lipid chain
} else if(name == "ct"){ // lipid chain
chart = value;
chart = value;
} else if(name == "sp"){ // species
species = value;
}
}
}
}
Line 120: Line 125:
// lipidclass基準の棒グラフを表示
// lipidclass基準の棒グラフを表示
selectCombobox([sampleSource, sampleType, lipidClass]);
selectCombobox([sampleSource, sampleType, lipidClass]);
var result = retrieveChainData(sampleSource, sampleType, lipidClass, chain);
var result = retrieveChainData(species, sampleSource, sampleType, lipidClass, chain);
if(result.x.length > 0){
if(result.x.length > 0){
showChainChart(result);
showChainChart(result);

Revision as of 04:39, 1 August 2018

// Last-Update: 2018/08/01
// html /////////////////////////////////////////////////////////////////////////////////////////////////////////
// <span id="search"></span><span id="show"></span>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// external script //////////////////////////////////////////////////////////////////////////////////////////////
mw.loader.load( ['jquery.ui.sortable'] );
mw.loader.load('https://code.highcharts.com/stock/highstock.js', "text/javascript");
importScript( 'MediaWiki:LipoqualityCommon.js' );
importScript( 'MediaWiki:LipoqualityGet.js'    );
importScript( 'MediaWiki:LipoqualitySearch.js' );
importScript( 'MediaWiki:LipoqualityChart.js'  );

// initialize //////////////////////////////////////////////////////////////////////////////////////////////////
addOnloadHook(lipoqulityInit); 

var gChartType;

// 初期化 //////////////////////////////////////////////////////////////////////////////////////////////////////
function lipoqulityInit()
{
	// highstock.jsに依存するため、別で読み込む
	var heatmapJS = document.createElement("script");
	heatmapJS.src = "https://code.highcharts.com/modules/heatmap.js";
	document.getElementsByTagName("head")[0].appendChild(heatmapJS);
	var exportingJS = document.createElement("script");
	exportingJS.src = "https://code.highcharts.com/modules/exporting.js";
	document.getElementsByTagName("head")[0].appendChild(exportingJS);

	// 検索、表示、チェックボタンを作成
		// 検索ボタン
	var searchButton = document.createElement("input");
	searchButton.value    = "search";
	searchButton.id       = "searchButton";
	searchButton.type     = "button";
	searchButton.disabled = true;
	searchButton.style.width = "100%";
	searchButton.onclick = function(){
		var sampleSource = document.getElementById("samplesource").value;
		var sampleType   = document.getElementById("sampletype").value;
		var lipidClass   = document.getElementById("lipidclass").value;
		search(sampleSource, sampleType, lipidClass);
	};
	document.getElementById("search").appendChild(searchButton);
		// グラフ表示ボタン
	var showButton = document.createElement("input");
	showButton.value = "show graph";
	showButton.id    = "showButton";
	showButton.type  = "button";
	showButton.disabled = true;
	showButton.onclick = function(){barColor = DEFAULT_BAR_COLOR; showChart(getSelectedIDs())};
	document.getElementById("show").appendChild(showButton);
		// チェックボタン
	var checkButton = document.createElement("input");
	checkButton.value = "all check/uncheck";
	checkButton.id    = "allswitch";
	checkButton.type  = "button";
	checkButton.onclick = function(){checkAllResult()};
	document.getElementById("check").appendChild(checkButton);
	document.getElementById("graphform").style.display = "none";

	// コンポーネント初期化
	lipoqulityChartInit();

	// コンボボックスの初期化
	setCombobox('SampleSource');
	setCombobox('SampleType');
	setCombobox('LipidClass');

	// 全データの取得
	retrieveAllDataFromText(hasRetrievedAllData);
}
// 全データの取得が完了した後の処理 /////////////////////////////////////
// return なし
function hasRetrievedAllData()
{
	// GETメソッドによる検索を行う場合の処理 /////////////////////////////
	var query  = window.location.search.substring(1);
	var params = query.split('&');
	var sampleSource = "All";
	var sampleType   = "All";
	var lipidClass   = "";
	var chain        = "";
	var chart        = "";
	var species      = "";
	// パラメータの取得
	// ss = SampleSource - デフォルトはAll
	// st = SampleType - デフォルトはAll
	// lc = LipidClass - デフォルトは空文字。この文字列が入っていないと、検索は行わない
	// chain = Lipid chain - chainグラフの表示には必須項目。16:0/16:0/16:0のようにスラッシュ区切り
	for(var i = 0; i < params.length; i++){
		var w = params[i].split('=');
		var name  = decodeURIComponent(w[0]);
		var value = decodeURIComponent(w[1]);
		if(name == "ss"){ // sample source
			sampleSource = value;

		} else if(name == "st"){ // sample type
			sampleType = value;

		} else if(name == "lc"){ // lipid class
			lipidClass = value;

		} else if(name == "ct"){ // lipid chain
			chart = value;

		} else if(name == "sp"){ // species
			species = value;
		}
	}
	var index = lipidClass.indexOf(" ");
	if(index > 0){
		chain = lipidClass.substring(index+1);
		lipidClass = lipidClass.substring(0, index);
	} else {
		index = lipidClass.indexOf("(");
		if(index >= 0){
			chain = lipidClass.substring(index+1, lipidClass.length-1);
			lipidClass = lipidClass.substring(0, index);
		}
	}
	if(chart == "c" && chain.length > 0){
		// lipidclass基準の棒グラフを表示
		selectCombobox([sampleSource, sampleType, lipidClass]);
		var result = retrieveChainData(species, sampleSource, sampleType, lipidClass, chain);
		if(result.x.length > 0){
			showChainChart(result);
		}

	} else if(chart == "b" && lipidClass.length > 0){
		// bar(棒グラフ)を表示
		selectCombobox([sampleSource, sampleType, lipidClass]);
		search(sampleSource, sampleType, lipidClass);
		if(document.getElementsByClassName("results").length > 0){
			document.getElementById('allswitch').click();
			document.getElementById('bar').checked = true;
			showChart(getSelectedIDs());
		}
	}

	document.getElementById('loading').style.display = "none";
	// 検索ボタンは有効化しておく
	document.getElementById("searchButton").disabled = false;
}
function getSelectedIDs()
{
	var targets = [];
	var boxes = document.getElementsByName('target');
	for(var i = 0; i < boxes.length; i ++){
		if(boxes[i].checked)
			targets.push(boxes[i].value);
	}
	if(targets.length == 0){
		alert("選択してください");
		return [];
	}
	return targets;
}
// 検索ボックスの初期化 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// param name カテゴリ名
// return なし
function setCombobox(name)
{
	var url = '/mediawiki/api.php?action=query&prop=revisions&redirects=1&titles=Lipoquality:' + name + '&rvprop=content&format=xml'

	var xmlHttpRequest = new XMLHttpRequest();
	xmlHttpRequest.onreadystatechange = function()
	{
		var READYSTATE_COMPLETED = 4;
		if(this.readyState == READYSTATE_COMPLETED){
			var HTTP_STATUS_OK = 200;
			if(this.status == HTTP_STATUS_OK) {
				// success
				var parser = new DOMParser();
				var dom = parser.parseFromString(this.response.trim(), "text/xml");
				var text = dom.getElementsByTagName("rev");
				var lines = text[0].textContent.split("\n");
				var select = document.getElementById(name.toLowerCase());
				if(name != 'LipidClass')
					lines.unshift('All');
				for(var i = 0; i < lines.length; i ++){
					var opt = document.createElement('option');
					opt.value = opt.textContent = lines[i].replace(/^\*/, '').replace(/^ */, '').replace(/ *$/, '').replace(/"/g, "&quot;").replace(/'/g, "&rsquo");;
					select.appendChild(opt);
				}
			} else {
				// error
				console.log('search failed. ' + this.status + ':' + this.statusText + "/" + this.readyState);
			}
		}
	}

	// AJAXを使って、コンボボックスの選択項目を取得する
	xmlHttpRequest.open('GET', url, true);
	xmlHttpRequest.responseType = 'text';
	xmlHttpRequest.send(null);
}
// 指定されたコンボボックスの値をセットする /////////////////////////////////////
// param targets - 選択するSampleSource, SampleType, LipidClassの項目値
// return なし
function selectCombobox(targets)
{
	var ids = ["samplesource", "sampletype", "lipidclass"];

	// 一つでもコンボボックスの初期化が終わっていなければ、処理を後回しにする
	var counter = 1;
	for(var i = 0; i < ids.length; i ++)
		counter *= document.getElementById(ids[i]).options.length;
	if(counter == 0){
		window.setTimeout( function() { selectCombobox(targets) }, 50 );
		return;
	}

	// コンボボックスの値をセットする
	for(var i = 0; i < ids.length; i ++){
		var cb = document.getElementById(ids[i]);
		for(var j = 0; j < cb.options.length; j ++){
			if(cb.options[j].value == targets[i]){
				cb.selectedIndex = j;
				break;
			}
		}
	}
}
// 検索 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// param sampleSource - 検索対象のSampleSource
// param sampleType   - 検索対象のSampleType
// param lipidClass   - 検索対象のLipidClass
// return なし
function search(sampleSource, sampleType, lipidClass)
{
	// 検索ボタン等を無効化しておく
	document.getElementById("searchButton").disabled      = true;
	document.getElementById("showButton")  .disabled      = true;
	document.getElementById('hit')         .innerHTML     = "";
	document.getElementById("graphform")   .style.display = "none";

	// 「検索中」を表示
	document.getElementById('searching').style.display = "block";

	// 検索を行う
	var result = lipoqualitySearch(sampleSource, sampleType, lipidClass);
//	var url = 'https://script.google.com/macros/s/AKfycbxW5WpkJH0PUmmLrMtrluvkaKmz0OTTfeBucudy5-LxalQ7vus/exec?classification=' + classification + '&sample=' + sample + '&type=' + type + '&q=search&callback=hasSearched';
//	var url = '/lipo/json.txt'

	// 過去の検索結果を削除する
	var root = document.getElementById('result');
	root.textContent = '';
	for(var i = root.childNodes.length-1; i >= 0; i --)
		root.removeChild(root.childNodes[i]);

	// 「検索中」を非表示
	document.getElementById('searching').style.display = "none";
	var root = document.getElementById('result');

//	var result = jsonp;
	//var result = JSON.parse(escape(jsonp));
	document.getElementById('hit').innerHTML = 'result. ' + escape(result.length) + ' hit(s).';
	// チェックボックスを並べるため、最長文字数を調べる
	var lenmax = 0;
	for(var i = 0; i < result.length; i ++){
		if(result[i].title.length > lenmax)
			lenmax = result[i].title.length;
	}
	lenmax += 6; // "(meta)"分
	lenmax /= 1.5;
	// チェックボックスの作成
	for(var i = 0; i < result.length; i ++){
		var span = document.createElement('span');
		span.style.display = "inline-block";
		span.style.width   = lenmax + "em";

		var check = document.createElement('input');
		check.type = 'checkbox';
		check.id	= attrEscape(result[i].title);
		check.value = attrEscape(result[i].title);
		check.name  = 'target';
		check.className = "results";
		check.onchange = function(e){
			checkSelection();
		};
		span.appendChild(check);
		var title = document.createElement('label');
		title.setAttribute('for', attrEscape(result[i].title));
		title.innerHTML = escape(result[i].title) + ' <a href="' + result[i]["Method link"] + '" target="_blank">(meta)</a>';
		span.appendChild(title);

		root.appendChild(span);
	}
	// 検索ボタンを有効化
	document.getElementById("searchButton").disabled = false;

	document.getElementById("graphform").style.display = "block";
}
// チェックボックスの状態に応じて、グラフ表示ボタンを有効/無効化する /////////////////
// return なし
function checkSelection()
{
	var c = document.getElementsByClassName("results");
	var disabled = true;
	for(var i = 0; i < c.length; i ++){
		if(c[i].checked){
			disabled = false;
			break;
		}
	}
	document.getElementById("showButton").disabled = disabled;
}
// すべてのチェックボックスをチェックする/アンチェックする //////////////////////
// return なし
function checkAllResult()
{
	var c = document.getElementsByClassName("results");

	// チェックするか、アンチェックするかを調べる
	var checked = 0;
	for(var i = 0; i < c.length; i ++){
		if(c[i].checked)
			checked ++;
	}
	var state = true;
	if(checked == c.length)
		state = false;

	// チェック状態を変更する
	for(var i = 0; i < c.length; i ++)
		c[i].checked = state;

	checkSelection();
}