Difference between revisions of "MediaWiki:Lipoquality.js"

From Jcbl.jp
Jump to: navigation, search
(Replaced content with "http://192.168.56.101/wiki/MediaWiki:Lipoquality.js")
Line 1: Line 1:
// html /////////////////////////////////////////////////////////////////////////////////////////////////////////
+
http://192.168.56.101/wiki/MediaWiki:Lipoquality.js
// <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");
+
 
+
// initialize //////////////////////////////////////////////////////////////////////////////////////////////////
+
addOnloadHook(init);
+
 
+
// 初期化 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
const DEFAULT_BAR_COLOR = "#7cb5ec";
+
var barColor = DEFAULT_BAR_COLOR;
+
function init()
+
{
+
// highstock.jsに依存するため、別で読み込む
+
var heatmapJS = document.createElement("script");
+
heatmapJS.src = "https://code.highcharts.com/modules/heatmap.js";
+
document.getElementsByTagName("head")[0].appendChild(heatmapJS);
+
 
+
var searchButton = document.createElement("input");
+
searchButton.value = "search";
+
searchButton.id    = "searchButton";
+
searchButton.type  = "button";
+
searchButton.style.width = "100%";
+
searchButton.onclick = function(){search()};
+
document.getElementById("search").appendChild(searchButton);
+
var showButton = document.createElement("input");
+
showButton.value = "show graph";
+
showButton.id    = "showButton";
+
showButton.type  = "button";
+
showButton.disabled = "yes";
+
showButton.onclick = function(){barColor = DEFAULT_BAR_COLOR; showChart()};
+
document.getElementById("show").appendChild(showButton);
+
var checkButton = document.createElement("input");
+
checkButton.value = "all check/uncheck";
+
checkButton.type  = "button";
+
checkButton.onclick = function(){checkAllResult()};
+
document.getElementById("check").appendChild(checkButton);
+
document.getElementById("graphform").style.display = "none";
+
 
+
// insert "Reset zoom" button
+
var resetZoomButton    = document.createElement("input");
+
resetZoomButton.setAttribute("type", "button");
+
resetZoomButton.value            = "Reset zoom";
+
resetZoomButton.id              = "resetZoomButton";
+
resetZoomButton.style.visibility = "hidden";
+
resetZoomButton.onclick          = unzoomBarCharts;
+
document.getElementById("resetZoom").appendChild(resetZoomButton);
+
 
+
setCombobox('SampleSource');
+
setCombobox('SampleType');
+
setCombobox('LipidClass');
+
 
+
$(window).resize(function() {
+
resizeChart();
+
});
+
}
+
// ウィンドウサイズが変更されたとき、チャートの幅も修正する ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function resizeChart()
+
{
+
if(chart == undefined || chart.length == 0)
+
return;
+
 
+
if(chart[0].options.chart.type != "heatmap"){
+
// barchart & piechart
+
var height  = 300;
+
var pieWidth = 400;
+
var width = $(window).width() - $("#sortableList").width() - $("#mw-panel").width() - pieWidth;
+
if(width < 300)
+
width = 300;
+
for(var i = 0; i < chart.length; i ++)
+
$("#container" + i).highcharts().setSize(width, height);
+
for(var i = 0; i < piechart.length; i ++)
+
$("#pieContainer" + i).highcharts().setSize(pieWidth, height);
+
} else {
+
var height = 400;
+
var width = $(window).width() - $("#sortableList").width() - $("#mw-panel").width();
+
// heatmap
+
for(var i = 0; i < chart.length; i ++)
+
$("#container" + i).highcharts().setSize(width, height);
+
}
+
}
+
 
+
// 検索ボックスの初期化 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
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);
+
}
+
}
+
}
+
 
+
// search
+
xmlHttpRequest.open('GET', url, true);
+
xmlHttpRequest.responseType = 'text';
+
xmlHttpRequest.send(null);
+
}
+
// XSS対策用 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function escape(text)
+
{
+
if(isFinite(text))
+
return text;
+
return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+
}
+
function attrEscape(text)
+
{
+
if(isFinite(text))
+
return text;
+
return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&rsquo;");
+
}
+
function inchiEscape(text)
+
{
+
if(isFinite(text))
+
return text;
+
return text.replace(/^InChIKey=/, "").replace(/[^A-Z0-9-]/g, "");
+
}
+
// 検索 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function search()
+
{
+
document.getElementById("searchButton").disabled = true;
+
document.getElementById('hit').innerHTML = '';
+
document.getElementById("showButton").disabled = "yes";
+
document.getElementById("graphform").style.display = "none";
+
 
+
var classification = document.getElementById("samplesource").value;
+
var sample  = document.getElementById("sampletype").value;
+
var type    = document.getElementById("lipidclass").value;
+
 
+
var url = 'https://script.google.com/macros/s/AKfycbwnSskrJWOPYksPyPqL5zHhGQxqeRpHhxt6ZzfaH-OCoMbG_w51/exec?classification=' + classification + '&sample=' + sample + '&type=' + type + '&q=search&callback=hasSearched';
+
// var url = '/lipo/json.txt'
+
 
+
document.getElementById('searching').style.display = "block";
+
 
+
// remove old elements
+
var root = document.getElementById('result');
+
root.textContent = '';
+
for(var i = root.childNodes.length-1; i >= 0; i --)
+
root.removeChild(root.childNodes[i]);
+
 
+
// jsonpを使って検索
+
var jsonp = document.createElement('script');
+
jsonp.src = url;
+
document.head.appendChild(jsonp);
+
}
+
 
+
function hasSearched(jsonp)
+
{
+
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 /= 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);
+
span.appendChild(title);
+
 
+
root.appendChild(span);
+
}
+
document.getElementById("searchButton").disabled = false;
+
 
+
document.getElementById("graphform").style.display = "block";
+
}
+
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;
+
}
+
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();
+
}
+
// チャート表示 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function showChart()
+
{
+
var targets = '';
+
var boxes = document.getElementsByName('target');
+
for(var i = 0; i < boxes.length; i ++){
+
if(boxes[i].checked)
+
targets += ',' + boxes[i].value;
+
}
+
if(targets.length == 0){
+
alert("選択してください");
+
return;
+
}
+
targets = targets.substring(1);
+
document.getElementById("resetZoomButton").style.visibility = "hidden";
+
 
+
document.getElementById("showButton").disabled = true;
+
document.getElementById("bar")      .disabled = true;
+
document.getElementById("heatmap")  .disabled = true;
+
document.getElementById("sortableList").style.display = "none";
+
 
+
var sortableList = document.getElementById("sortableList");
+
for(var i = sortableList.childNodes.length-1; i >= 0; i --)
+
sortableList.removeChild(sortableList.childNodes[i]);
+
 
+
var chartType;
+
if(document.getElementById('bar').checked)
+
chartType = 'bar';
+
else
+
chartType = 'heatmap';
+
 
+
retrieveChartData(targets, chartType);
+
}
+
// データ取得  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function retrieveChartData(targets, chartType)
+
{
+
var url = 'https://script.google.com/macros/s/AKfycbwnSskrJWOPYksPyPqL5zHhGQxqeRpHhxt6ZzfaH-OCoMbG_w51/exec?id=' + targets + '&type=' + chartType + '&q=data&callback=hasRetrieved';
+
//var url = '/lipo/data.php?id=' +  targets + '&type=' + chartType + '&q=data';
+
 
+
// jsonpを使った取得
+
var cutoff = document.getElementById("cutoff");
+
for(var i = cutoff.childNodes.length-1; i >= 0; i --)
+
cutoff.removeChild(cutoff.childNodes[i]);
+
var pieRoot = document.getElementById('pieContainer');
+
for(var i = pieRoot.childNodes.length-1; i >= 0; i --)
+
pieRoot.removeChild(pieRoot.childNodes[i]);
+
var root = document.getElementById('container');
+
for(var i = root.childNodes.length-1; i >= 0; i --)
+
root.removeChild(root.childNodes[i]);
+
document.getElementById('retrieving').style.display = "block";
+
var jsonp = document.createElement('script');
+
jsonp.src = url;
+
document.head.appendChild(jsonp);
+
}
+
 
+
// コールバック関数(jsonp)  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function hasRetrieved(jsonp)
+
{
+
document.getElementById('retrieving').style.display = "none";
+
 
+
var root = document.getElementById('container');
+
// remove old elements
+
root.textContent = '';
+
// for(var i = root.childNodes.length-1; i >= 0; i --)
+
// root.removeChild(root.childNodes[i]);
+
 
+
var chartType;
+
if(document.getElementById('bar').checked)
+
chartType = 'bar';
+
else
+
chartType = 'heatmap';
+
 
+
var cutoff    = document.getElementById("cutoff");
+
var cutoffText = document.createElement("input");
+
cutoffText.id    = "cutoffValue";
+
cutoffText.type  = "number";
+
cutoffText.value = 0;
+
cutoffText.min  = 0;
+
cutoffText.max  = 80;
+
cutoffText.style.width = "4em";
+
cutoffText.style.textAlign = "right";
+
cutoff.appendChild(cutoffText);
+
var cutoffButton = document.createElement("input");
+
cutoffButton.value = "< cutoff";
+
cutoffButton.type  = "button";
+
cutoff.appendChild(cutoffButton);
+
 
+
var result = jsonp;
+
//var result = JSON.parse(escape(jsonp));
+
if(chartType == 'bar')
+
showBarChart(result);
+
else
+
showHeatmap(result);
+
document.getElementById("showButton").disabled = false;
+
document.getElementById("bar")      .disabled = false;
+
document.getElementById("heatmap")  .disabled = false;
+
document.getElementById("sortableList").style.display = "block";
+
}
+
 
+
// バーチャート ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
var gBarData;
+
function getInchiOnBar(seq, x)
+
{
+
window.open("http://jcbl.jp/wiki/Category:LBG" + gBarData[seq][x], "new");
+
console.log(seq + "/" + x + " => " + gBarData[seq][x]);
+
}
+
var chart;
+
var piechart;
+
var defaultTickInterval = currentTickInterval = 5;
+
// バーチャートのズーム解除 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function unzoomBarCharts() {
+
for(var i = 0; i < chart.length; i ++){
+
//chart[i].xAxis[0].options.tickInterval = defaultTickInterval;
+
chart[i].xAxis[0].isDirty = true;
+
chart[i].xAxis[0].setExtremes(null, null, animation=true);
+
}
+
document.getElementById("resetZoomButton").style.visibility = "hidden";
+
}
+
// データの切り替え(表示/非表示、0-intensity) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function setBarchartData()
+
{ // inchiキー未処理 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
var target = [];
+
var cutoff = parseInt(document.getElementById("cutoffValue").value);
+
var xLabels = [];
+
for(var j = 0; j < chart[0].data.length; j ++){
+
var not0 = false;
+
for(var i = 0; i < chart.length; i ++){
+
if(chart[i].data[j][1] >= cutoff){
+
not0 = true;
+
break;
+
}
+
}
+
target[j] = not0;
+
}
+
 
+
for(var j = 0; j < chart.length; j ++){
+
var i = 0;
+
var data = [];
+
for(var k = 0,l = 0; k < chart[j].data.length; k ++){
+
if(target[k]){
+
data[i++] = chart[j].data[k];
+
}
+
}
+
chart[j].series[0].setData(data, true);
+
}
+
 
+
unzoomBarCharts();
+
}
+
// 表示 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function showBarChart(result)
+
{
+
function computeTickInterval(xMin, xMax)
+
{
+
var zoomRange = xMax - xMin;
+
 
+
if(zoomRange <= 2)
+
currentTickInterval = 0.5;
+
if(zoomRange < 20)
+
currentTickInterval = 1;
+
else if(zoomRange < 100)
+
currentTickInterval = 5;
+
}
+
 
+
// create ignore 0-intensity button
+
document.getElementById("cutoffValue").onchange = function(){
+
setBarchartData();
+
};
+
 
+
// create sortable list
+
var sortableList = document.getElementById("sortableList");
+
for(var i = 0; i < result[0].map.length; i ++){
+
var line = document.createElement("div");
+
var cbox = document.createElement("input");
+
cbox.setAttribute("type", "checkbox");
+
cbox.setAttribute("checked", "yes");
+
cbox.setAttribute("seq", i);
+
cbox.id = "item" + i;
+
cbox.onchange = function(e){
+
// 表示/非表示の切り替え
+
var seq = this.getAttribute("seq");
+
var option;
+
if(this.checked){
+
option = "block";
+
} else {
+
option = "none";
+
}
+
document.getElementById("container" + seq).style.display = option;
+
document.getElementById("pieContainer" + seq).style.display = option;
+
};
+
line.appendChild(cbox);
+
var label = document.createElement("label");
+
label.setAttribute("for", "item" + i);
+
label.innerHTML = (i+1) + "." + escape(result[0].map[i].title);
+
line.appendChild(label);
+
sortableList.appendChild(line);
+
}
+
$('#sortableList').sortable({
+
cursor: 'move',
+
update: function(event, ui){
+
var sortableList = document.getElementById("sortableList");
+
for(var i = 0; i < sortableList.childNodes.length; i ++){
+
var seq = sortableList.childNodes[i].childNodes[0].getAttribute("seq");
+
document.getElementById("container" + seq).setAttribute("order", i);
+
document.getElementById("pieContainer" + seq).setAttribute("order", i);
+
}
+
$("#container").html(
+
$("#container > div").sort(function(o1,o2)
+
{
+
var n1 = parseInt($(o1).attr("order"), 10);
+
var n2 = parseInt($(o2).attr("order"), 10);
+
if(n1 < n2) return -1;
+
if(n1 > n2) return 1;
+
return 0;
+
})
+
);
+
$("#pieContainer").html(
+
$("#pieContainer > div").sort(function(o1,o2)
+
{
+
var n1 = parseInt($(o1).attr("order"), 10);
+
var n2 = parseInt($(o2).attr("order"), 10);
+
if(n1 < n2) return -1;
+
if(n1 > n2) return 1;
+
return 0;
+
})
+
);
+
}
+
});
+
 
+
// create barchart(s)
+
gBarData = [];
+
chart    = [];
+
piechart = [];
+
var root    = document.getElementById('container');
+
var pieRoot = document.getElementById('pieContainer');
+
for(var i = 0; i < result[0].map.length; i ++){
+
gBarData[i] = [];
+
// データの整理
+
var data = [];
+
for(var j = 0; j < result[0].map[i].data.length; j ++){
+
data[j] = [attrEscape(result[0].x[j]), attrEscape(result[0].map[i].data[j][0])];
+
// gBarData[i][j] = inchiEscape(result[0].map[i].data[j][2]); // InChIキー
+
var type = result[0].map[i].title.replace(/.*\//,"");
+
gBarData[i][j] = type + attrEscape(result[0].x[j]).replace("/","-"); // InChIキー
+
}
+
 
+
// barchartの追加
+
var parent = document.createElement('div');
+
parent.id = 'container' + i;
+
parent.setAttribute("order", i);
+
root.appendChild(parent);
+
chart[i] = new Highcharts.Chart({
+
chart: {
+
type: 'column',
+
zoomType: 'x',
+
renderTo: parent,
+
height: 250,
+
resetZoomButton: {
+
theme: {
+
display: 'none'
+
}
+
}
+
},
+
title: {
+
text: (i+1) + '.' + attrEscape(result[0].map[i].title)
+
},
+
xAxis: {
+
min: 0,
+
type: 'category',
+
labels: {
+
rotation: -90,
+
style: {
+
fontSize: '11px',
+
fontFamily: 'Verdana, sans-serif'
+
},
+
step: 1
+
},
+
events : {
+
afterSetExtremes: function(){
+
if(!this.chart.options.chart.isZoomed){
+
if(this.chart.options.chart.isZoomed !== undefined)
+
document.getElementById("resetZoomButton").style.visibility = "visible";
+
 
+
var xMin = this.chart.xAxis[0].min;
+
var xMax = this.chart.xAxis[0].max;
+
 
+
var zmRange = computeTickInterval(xMin, xMax);
+
for(var i = 0; i < chart.length; i ++){
+
chart[i].xAxis[0].options.tickInterval = zmRange;
+
chart[i].xAxis[0].isDirty = true;
+
if(chart[i] !== this){
+
chart[i].options.chart.isZoomed = true;
+
chart[i].xAxis[0].setExtremes(xMin, xMax, true);
+
chart[i].options.chart.isZoomed = false;
+
}
+
}
+
}
+
},
+
}
+
},
+
scrollbar: {
+
enabled: true
+
},
+
yAxis: {
+
min: 0,
+
max: 100,
+
title: {
+
text: 'Relative Intensity(%)'
+
}
+
},
+
legend: {
+
enabled: false
+
},
+
tooltip: {
+
pointFormat: '<b>{point.y:.1f} %</b>'
+
},
+
series: [{
+
name: 'Population',
+
data: data,
+
color: barColor,
+
events: {
+
  click: function(event) {
+
//alert(event.point.name);
+
var index = event.target.farthestViewportElement.parentNode.parentElement.id.replace("container","");
+
getInchiOnBar(index, event.point.x);
+
  }
+
}
+
}]
+
});
+
chart[i].data = data;
+
 
+
// piechartの追加
+
var pieParent = document.createElement('div');
+
pieParent.id = 'pieContainer' + i;
+
pieParent.setAttribute("order", i);
+
pieRoot.appendChild(pieParent);
+
piechart[i] = new Highcharts.Chart({
+
chart: {
+
plotBackgroundColor: null,
+
plotBorderWidth: null,
+
plotShadow: false,
+
type: 'pie',
+
renderTo: pieParent,
+
height: 250
+
},
+
title: {
+
text: (i+1) + '.ratio'
+
},
+
tooltip: {
+
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
+
},
+
plotOptions: {
+
pie: {
+
allowPointSelect: true,
+
cursor: 'pointer',
+
dataLabels: {
+
enabled: true,
+
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
+
style: {
+
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
+
}
+
}
+
}
+
},
+
series: [{
+
name: 'Rate',
+
colorByPoint: true,
+
data: result[0].map[i].pie,
+
events: {
+
click: function(event) {
+
barColor = event.point.color;
+
 
+
var nextType = event.point.name;
+
var targets = '';
+
var sortableList = document.getElementById("sortableList");
+
for(var i = 0; i < sortableList.childNodes.length; i ++){
+
var w = sortableList.childNodes[i].childNodes[1].innerHTML.replace(/^[0-9]+./,"").split("/");
+
targets += "," + w[0] + "/" + w[1] + "/" + nextType;
+
}
+
targets = targets.substring(1);
+
document.getElementById("showButton").disabled = true;
+
document.getElementById("bar")      .disabled = true;
+
document.getElementById("heatmap")  .disabled = true;
+
document.getElementById("sortableList").style.display = "none";
+
 
+
var sortableList = document.getElementById("sortableList");
+
for(var i = sortableList.childNodes.length-1; i >= 0; i --)
+
sortableList.removeChild(sortableList.childNodes[i]);
+
 
+
retrieveChartData(targets, 'bar');
+
}
+
}
+
}]
+
});
+
}
+
resizeChart();
+
}
+
// ヒートマップ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
var chart;
+
var gHeatmapData;
+
function getInchiOnHeatmap(seq, x, y) // 未使用
+
{
+
window.open("http://jcbl.jp/wiki/Category:LBG" + gHeatmapData[seq].map[0].title.replace(/.*\//, "") + gHeatmapData[seq].x[x].replace("/","-"), "new");
+
// console.log(seq + "/" + y + "/" + x + " => " + gHeatmapData[seq][y][x]);
+
console.log(seq + "/" + y + "/" + x + " => " + gHeatmapData[seq].x[x].replace("/","-"));
+
 
+
}
+
function jumpToJcbl(inchi)
+
{
+
window.open("http://jcbl.jp/","new");
+
console.log(inchi);
+
}
+
// データの切り替え(表示/非表示、0-intensity) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function setHeatmapData(index, seq)
+
{
+
var i = 0;
+
var length = gHeatmapData[index].map.length;
+
 
+
var target = [];
+
var cutoff = parseInt(document.getElementById("cutoffValue").value);
+
var xLabels = [];
+
for(var k = 0; k < gHeatmapData[index].map[0].data.length; k ++){
+
var not0 = false;
+
for(var j = 0; j < length; j ++){
+
if(gHeatmapData[index].map[j].data[k][0] >= cutoff){
+
not0 = true;
+
break;
+
}
+
}
+
target[k] = not0;
+
if(not0)
+
xLabels[i++] = gHeatmapData[index].x[k];
+
}
+
 
+
var data = [];
+
var yLabels = [];
+
chart[index].inchi = [];
+
i = 0;
+
for(var j = 0; j < seq.length && j < length; j ++){
+
chart[index].inchi[j] = [];
+
for(var k = 0,l = 0; k < gHeatmapData[index].map[seq[j]].data.length; k ++){
+
if(target[k]){
+
data[i] = [l++, seq.length-j-1, attrEscape(gHeatmapData[index].map[seq[j]].data[k][0])];
+
chart[index].inchi[j][k] = inchiEscape(gHeatmapData[index].map[seq[j]].data[k][2]);
+
i ++;
+
}
+
}
+
yLabels[j] = (parseInt(seq[j])+1) + "." + attrEscape(gHeatmapData[index].map[seq[j]].title.replace(/\/[^\/]+$/, ""));
+
}
+
yLabels.reverse();
+
chart[index].series[0].setData(data, true);
+
chart[index].yAxis[0].setCategories(yLabels);
+
chart[index].xAxis[0].setCategories(xLabels);
+
}
+
// 表示 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function showHeatmap(result)
+
{
+
gHeatmapData = [];
+
var root = document.getElementById('container');
+
 
+
var sortableList = document.getElementById("sortableList");
+
chart = [];
+
gHeatmapData = result;
+
for(var i = 0; i < result.length; i ++){
+
// タイトル
+
var title = attrEscape(result[i].title);
+
 
+
// 親要素
+
var parent = document.createElement('div');
+
parent.id = 'container' + i;
+
root.appendChild(parent);
+
 
+
var index = 0;
+
var data = [];
+
var yLabels = [];
+
var length = result[i].map.length
+
var inchi = [];
+
for(var j = 0; j < length; j ++){
+
inchi[j] = [];
+
for(var k = 0; k < result[i].map[j].data.length; k ++){
+
data[index] = [k, length-j-1, attrEscape(result[i].map[j].data[k][0])];
+
inchi[j][k] = inchiEscape(result[i].map[j].data[k][2]);
+
index ++;
+
}
+
yLabels[j] = (j+1) + "." + attrEscape(result[i].map[j].title.replace(/\/[^\/]+$/, ""));
+
}
+
yLabels.reverse();
+
for(var j = 0; j < result[i].x.length; j ++)
+
result[i].x[j] = attrEscape(result[i].x[j]);
+
 
+
// create ignore 0-intensity button
+
document.getElementById("cutoffValue").onchange = function(){
+
// 表示/非表示の切り替え // 下と同じなので、後でまとめる
+
for(var index = 0; index < chart.length; index ++){
+
var sortableList = document.getElementById("sortableList" + index);
+
var sequence = [];
+
for(var i = 0, j = 0; i < sortableList.childNodes.length; i ++){
+
if(sortableList.childNodes[i].childNodes[0].checked)
+
sequence[j++] = sortableList.childNodes[i].childNodes[0].getAttribute("seq");
+
}
+
setHeatmapData(index, sequence);
+
}
+
};
+
 
+
// create sortable list
+
var listDiv = document.createElement("div");
+
listDiv.id = "sortableList" + i;
+
for(var j = 0; j < result[i].map.length; j ++){
+
var line = document.createElement("div");
+
var cbox = document.createElement("input");
+
cbox.setAttribute("type", "checkbox");
+
cbox.setAttribute("checked", "yes");
+
cbox.setAttribute("seq", j);
+
cbox.id = "item" + j;
+
cbox.onchange = function(e){
+
// 表示/非表示の切り替え
+
var index = this.parentElement.parentElement.id.replace("sortableList", "");
+
var sortableList = document.getElementById("sortableList" + index);
+
var sequence = [];
+
for(var i = 0, j = 0; i < sortableList.childNodes.length; i ++){
+
if(sortableList.childNodes[i].childNodes[0].checked)
+
sequence[j++] = sortableList.childNodes[i].childNodes[0].getAttribute("seq");
+
}
+
setHeatmapData(index, sequence);
+
};
+
line.appendChild(cbox);
+
var label = document.createElement("label");
+
label.setAttribute("for", "item" + j);
+
label.innerHTML = (j+1) + "." + escape(result[i].map[j].title);
+
line.appendChild(label);
+
listDiv.appendChild(line);
+
}
+
sortableList.appendChild(listDiv);
+
$('#sortableList' + i).sortable({
+
cursor: 'move',
+
update: function(event, ui){
+
var index = ui.item[0].parentElement.id.replace("sortableList", "");
+
var sortableList = document.getElementById("sortableList" + index);
+
var sequence = [];
+
for(var i = 0, j = 0; i < sortableList.childNodes.length; i ++){
+
if(sortableList.childNodes[i].childNodes[0].checked)
+
sequence[j++] = sortableList.childNodes[i].childNodes[0].getAttribute("seq");
+
}
+
setHeatmapData(index, sequence);
+
}
+
});
+
$('#sortableList').sortable(false);
+
 
+
// ヒートマップ
+
chart[i] = new Highcharts.Chart({
+
+
chart: {
+
type: 'heatmap',
+
zoomType: 'xy',
+
animation: 1,
+
marginBottom: 0,
+
plotBorderWidth: 1,
+
renderTo: parent,
+
animation: true,
+
},
+
+
scrollbar: {
+
enabled: true
+
},
+
+
title: {
+
text: title,
+
align: 'left'
+
},
+
+
xAxis: {
+
categories: result[i].x,
+
opposite: true,
+
labels: {
+
rotation: -90,
+
style: {
+
fontSize: '11px',
+
fontFamily: 'Verdana, sans-serif'
+
},
+
step: 1
+
},
+
},
+
+
yAxis: {
+
categories: yLabels,
+
title: null,
+
labels: {
+
step: 1
+
}
+
},
+
+
colorAxis: {
+
min: 0,
+
max: 100,
+
minColor: '#ffffff',
+
maxColor: Highcharts.getOptions().colors[8]
+
},
+
+
legend: {
+
align: 'right',
+
layout: 'vertical',
+
margin: 0,
+
verticalAlign: 'top',
+
y: 100,
+
symbolHeight: 145
+
},
+
+
tooltip: {
+
formatter: function () {
+
return this.series.yAxis.categories[this.point.y] + '<br />' +
+
this.series.xAxis.categories[this.point.x] + '<br />' +
+
(Math.round(this.point.value*10)/10) + ' %';
+
}
+
},
+
+
series: [{
+
name: 'HEK',
+
borderWidth: 1,
+
data: data,
+
dataLabels: {
+
enabled: false,
+
color: '#000000'
+
},
+
point: {
+
events: {
+
/*mouseOver: function() {
+
var index = event.target.farthestViewportElement.parentNode.parentElement.id.replace("container", "");
+
var target = getTarget(this.series.chart.xAxis[0].labelGroup.element.childNodes, result[index].x[this.x]);
+
if(target != null){
+
target.css('fill', 'red');
+
target.css('fontWeight', 'bold');
+
}
+
 
+
  $(this.series.chart.yAxis[0].labelGroup.element.childNodes[this.y]).css('fill', 'red');
+
  $(this.series.chart.yAxis[0].labelGroup.element.childNodes[this.y]).css('fontWeight', 'bold');
+
},
+
mouseOut: function() {
+
var index = event.target.farthestViewportElement.parentNode.parentElement.id.replace("container", "");
+
var target = getTarget(this.series.chart.xAxis[0].labelGroup.element.childNodes, result[index].x[this.x]);
+
if(target != null){
+
target.css('fill', '#666666');
+
target.css('fontWeight', '');
+
}
+
 
+
$(this.series.chart.yAxis[0].labelGroup.element.childNodes[this.y]).css('fill', '#666666');
+
$(this.series.chart.yAxis[0].labelGroup.element.childNodes[this.y]).css('fontWeight', '');
+
},*/
+
click: function(event){
+
// var index = event.target.farthestViewportElement.parentNode.parentElement.id.replace("container","");
+
getInchiOnHeatmap(0, event.point.x, event.point.y);
+
// jumpToJcbl(event.point.series.chart.inchi[event.point.y][event.point.x]);
+
}
+
}
+
}
+
}]
+
+
});
+
chart[i].inchi = inchi;
+
//chart.setSize(600,300,false);
+
}
+
resizeChart();
+
}
+
 
+
// ※未使用※ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
function getTarget(children, target)
+
{
+
for(var i = 0; i < children.length; i ++){
+
if(target == children[i].childNodes[0].textContent){
+
return $(children[i]);
+
}
+
// console.log(children[i].childNodes[0].textContent);
+
}
+
return null;
+
}
+

Revision as of 15:08, 20 July 2016

http://192.168.56.101/wiki/MediaWiki:Lipoquality.js
Personal tools