Skip to content
Snippets Groups Projects
Commit 2ae20397 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

help tip for chemical panel dynamically refers to the proper disease

parent b1438b78
No related branches found
No related tags found
1 merge request!174Resolve "description of chemical panel refers to Parkinson Disease"
Pipeline #
......@@ -11,41 +11,40 @@ var Functions = require('../Functions');
var logger = require('../logger');
function Panel(params) {
AbstractGuiElement.call(this, params);
var self = this;
self.setParent(params.parent);
var configuration = params.configuration;
if (params.configuration === undefined) {
configuration = self.getMap().getConfiguration();
}
var guiUtils = new GuiUtils(configuration);
self.setGuiUtils(guiUtils);
if (self.getMap() !== undefined) {
this.getGuiUtils().setMap(self.getMap());
}
self.setPanelName(params.panelName);
if (params.scrollable) {
$(self.getElement()).addClass("pre-scrollable");
} else {
$(self.getElement()).css("overflow-y", "auto");
}
$(self.getElement()).css("position", "relative");
if (params.helpTip !== undefined) {
self.createHelpButton();
self.setHelpTip(params.helpTip);
}
GuiConnector.addWindowResizeEvent(function () {
self.onresize();
});
$("a[href='#" + self.getElement().id + "']").on('shown.bs.tab', function () {
self.onresize();
});
AbstractGuiElement.call(this, params);
var self = this;
self.setParent(params.parent);
var configuration = params.configuration;
if (params.configuration === undefined) {
configuration = self.getMap().getConfiguration();
}
var guiUtils = new GuiUtils(configuration);
self.setGuiUtils(guiUtils);
if (self.getMap() !== undefined) {
this.getGuiUtils().setMap(self.getMap());
}
self.setPanelName(params.panelName);
if (params.scrollable) {
$(self.getElement()).addClass("pre-scrollable");
} else {
$(self.getElement()).css("overflow-y", "auto");
}
$(self.getElement()).css("position", "relative");
if (params.helpTip !== undefined) {
self.setHelpTip(params.helpTip);
}
GuiConnector.addWindowResizeEvent(function () {
self.onresize();
});
$("a[href='#" + self.getElement().id + "']").on('shown.bs.tab', function () {
self.onresize();
});
}
......@@ -53,249 +52,252 @@ Panel.prototype = Object.create(AbstractGuiElement.prototype);
Panel.prototype.constructor = Panel;
Panel.prototype.createHelpButton = function () {
var self = this;
var helpTipButton = Functions.createElement({
type: "button",
className: "minerva-help-button",
content: '<span class="ui-icon ui-icon-help" style="margin-left: -0.5em;"/>',
var self = this;
var helpTipButton = Functions.createElement({
type: "button",
className: "minerva-help-button",
content: '<span class="ui-icon ui-icon-help" style="margin-left: -0.5em;"/>',
});
helpTipButton.onclick = function () {
var helpDialogDiv = Functions.createElement({
type: "div",
content: self.getHelpTip(),
});
helpTipButton.onclick = function () {
var helpDialogDiv = Functions.createElement({
type: "div",
content: self.getHelpTip(),
});
$(helpDialogDiv).dialog({
close: function () {
$(this).dialog('destroy').remove();
},
position: {
my: "left top",
at: "left bottom",
of: helpTipButton
},
});
$('.ui-dialog').find("a").blur();
};
self.getElement().appendChild(helpTipButton);
$(helpDialogDiv).dialog({
close: function () {
$(this).dialog('destroy').remove();
},
position: {
my: "left top",
at: "left bottom",
of: helpTipButton
},
});
$('.ui-dialog').find("a").blur();
};
self.getElement().appendChild(helpTipButton);
};
Panel.prototype.disablePanel = function (message) {
var self = this;
var self = this;
var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
var searchResultsElement = self.getControlElement(PanelControlElementType.SEARCH_RESULTS_DIV);
var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
var searchResultsElement = self.getControlElement(PanelControlElementType.SEARCH_RESULTS_DIV);
searchQueryElement.style.visibility = "hidden";
searchResultsElement.style.visibility = "hidden";
var hideReasonDiv = document.createElement("div");
hideReasonDiv.className = "searchPanel";
searchQueryElement.style.visibility = "hidden";
searchResultsElement.style.visibility = "hidden";
var hideReasonDiv = document.createElement("div");
hideReasonDiv.className = "searchPanel";
var center = document.createElement("center");
var messageDiv = document.createElement("h4");
messageDiv.innerHTML = message;
center.appendChild(messageDiv);
hideReasonDiv.appendChild(center);
var center = document.createElement("center");
var messageDiv = document.createElement("h4");
messageDiv.innerHTML = message;
center.appendChild(messageDiv);
hideReasonDiv.appendChild(center);
self.getElement().insertBefore(hideReasonDiv, searchQueryElement);
self.getElement().insertBefore(hideReasonDiv, searchQueryElement);
};
Panel.prototype.isDisabled = function () {
var self = this;
var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
return searchQueryElement.style.visibility === "hidden";
var self = this;
var searchQueryElement = self.getControlElement(PanelControlElementType.SEARCH_DIV);
return searchQueryElement.style.visibility === "hidden";
};
Panel.prototype.setMap = function (map) {
this._map = map;
this._map = map;
};
Panel.prototype.getMap = function () {
return this._map;
return this._map;
};
Panel.prototype.setPanelName = function (panelName) {
this._panelName = panelName;
this._panelName = panelName;
};
Panel.prototype.getPanelName = function () {
return this._panelName;
return this._panelName;
};
Panel.prototype.setElement = function (element) {
if (element === undefined || element === null) {
throw new Error("DOM Element must be defined");
}
this._element = element;
if (element === undefined || element === null) {
throw new Error("DOM Element must be defined");
}
this._element = element;
};
Panel.prototype.getElement = function () {
return this._element;
return this._element;
};
Panel.prototype.getElementByName = function (element, name) {
if (element !== undefined) {
if (element.getAttribute("name") === name) {
return element;
}
var children = element.children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
var res = this.getElementByName(child, name);
if (res !== undefined) {
return res;
}
}
if (element !== undefined) {
if (element.getAttribute("name") === name) {
return element;
}
return undefined;
var children = element.children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
var res = this.getElementByName(child, name);
if (res !== undefined) {
return res;
}
}
}
return undefined;
};
Panel.prototype.getDialogDiv = function (id) {
var dialogs = this.getElementByName(this.getElement(), "dialogs");
if (dialogs === undefined) {
dialogs = document.createElement("div");
dialogs.setAttribute("name", "dialogs");
this.getElement().appendChild(dialogs);
var dialogs = this.getElementByName(this.getElement(), "dialogs");
if (dialogs === undefined) {
dialogs = document.createElement("div");
dialogs.setAttribute("name", "dialogs");
this.getElement().appendChild(dialogs);
this._dialogs = [];
}
this._dialogs = [];
}
var dialogDiv = this._dialogs[id];
var dialogDiv = this._dialogs[id];
if (dialogDiv === undefined) {
dialogDiv = document.createElement("div");
dialogDiv.className = "ui-widget";
dialogDiv.setAttribute("name", "dialog-" + id);
if (dialogDiv === undefined) {
dialogDiv = document.createElement("div");
dialogDiv.className = "ui-widget";
dialogDiv.setAttribute("name", "dialog-" + id);
var contentDiv = document.createElement("div");
contentDiv.setAttribute("name", "content");
dialogDiv.appendChild(contentDiv);
var contentDiv = document.createElement("div");
contentDiv.setAttribute("name", "content");
dialogDiv.appendChild(contentDiv);
dialogs.appendChild(dialogDiv);
dialogs.appendChild(dialogDiv);
this._dialogs[id] = dialogDiv;
}
return dialogDiv;
this._dialogs[id] = dialogDiv;
}
return dialogDiv;
};
Panel.prototype.assignDialogOptions = function (div, params) {
var dialog = $(div);
for (var key in params) {
if (params.hasOwnProperty(key)) {
if (key === "id") {
div.setAttribute("name", "dialog-" + params[key]);
} else if (key === "modal") {
dialog.dialog('option', 'modal', params[key]);
} else if (key === "buttons") {
dialog.dialog('option', 'buttons', params[key]);
} else if (key === "className") {
dialog.dialog('option', 'dialogClass', params[key]);
} else if (key === "title") {
dialog.dialog('option', 'title', params[key]);
} else {
throw new Error("Unknown dialog param: " + key + " - " + params[key]);
}
}
var dialog = $(div);
for (var key in params) {
if (params.hasOwnProperty(key)) {
if (key === "id") {
div.setAttribute("name", "dialog-" + params[key]);
} else if (key === "modal") {
dialog.dialog('option', 'modal', params[key]);
} else if (key === "buttons") {
dialog.dialog('option', 'buttons', params[key]);
} else if (key === "className") {
dialog.dialog('option', 'dialogClass', params[key]);
} else if (key === "title") {
dialog.dialog('option', 'title', params[key]);
} else {
throw new Error("Unknown dialog param: " + key + " - " + params[key]);
}
}
}
};
Panel.prototype.openDialog = function (content, options) {
if (options === undefined) {
options = {};
}
if (options.id === undefined) {
logger.warn("Id of dialog is not defined");
}
var div = this.getDialogDiv(options.id);
var contentDiv = this.getElementByName(div, "content");
while (contentDiv.hasChildNodes()) {
contentDiv.removeChild(contentDiv.lastChild);
}
contentDiv.appendChild(content);
contentDiv.style.display = "block";
$(div).dialog({
close: function () {
contentDiv.style.display = "none";
$(this).dialog('destroy');
},
dialogClass: options.className,
});
this.assignDialogOptions(div, options);
$(div).dialog("open");
if (options === undefined) {
options = {};
}
if (options.id === undefined) {
logger.warn("Id of dialog is not defined");
}
var div = this.getDialogDiv(options.id);
var contentDiv = this.getElementByName(div, "content");
while (contentDiv.hasChildNodes()) {
contentDiv.removeChild(contentDiv.lastChild);
}
contentDiv.appendChild(content);
contentDiv.style.display = "block";
$(div).dialog({
close: function () {
contentDiv.style.display = "none";
$(this).dialog('destroy');
},
dialogClass: options.className,
});
this.assignDialogOptions(div, options);
$(div).dialog("open");
};
Panel.prototype.init = function () {
throw new Error(this.getPanelName() + " Not implemented");
throw new Error(this.getPanelName() + " Not implemented");
};
Panel.prototype.setParent = function (parent) {
this._parent = parent;
this._parent = parent;
};
Panel.prototype.getParent = function () {
return this._parent;
return this._parent;
};
Panel.prototype.setGuiUtils = function (guiUtils) {
this._guiUtils = guiUtils;
this._guiUtils = guiUtils;
};
Panel.prototype.getGuiUtils = function () {
return this._guiUtils;
return this._guiUtils;
};
Panel.prototype.setHelpTip = function (helpTip) {
this._helpTip = helpTip;
if (this._helpTip === undefined && helpTip !== undefined) {
this.createHelpButton();
}
this._helpTip = helpTip;
};
Panel.prototype.getHelpTip = function () {
return this._helpTip;
return this._helpTip;
};
Panel.prototype.onresize = function () {
var self = this;
var footerPosition = window.innerHeight;
// compute the width (we can only compute it for visible elements)
var size = 100000;
if ($(self.getElement()).is(":visible")) {
$(".pre-scrollable", self.getElement()).each(function (index, element) {
if ($(element).is(":visible")) {
size = Math.min(size, footerPosition - $(element).offset().top);
}
});
if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
size = Math.min(size, footerPosition - $(self.getElement()).offset().top);
}
if (size !== 100000) {
$(".pre-scrollable", self.getElement()).each(function (index, element) {
$(element).css('max-height', size);
$(element).css('height', size);
});
}
if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
$(self.getElement()).css('max-height', size);
$(self.getElement()).css('height', size);
}
var self = this;
var footerPosition = window.innerHeight;
// compute the width (we can only compute it for visible elements)
var size = 100000;
if ($(self.getElement()).is(":visible")) {
$(".pre-scrollable", self.getElement()).each(function (index, element) {
if ($(element).is(":visible")) {
size = Math.min(size, footerPosition - $(element).offset().top);
}
});
if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
size = Math.min(size, footerPosition - $(self.getElement()).offset().top);
}
if (size !== 100000) {
$(".pre-scrollable", self.getElement()).each(function (index, element) {
$(element).css('max-height', size);
$(element).css('height', size);
});
}
if ($(self.getElement()).hasClass("pre-scrollable") && $(self.getElement()).is(":visible")) {
$(self.getElement()).css('max-height', size);
$(self.getElement()).css('height', size);
}
}
};
Panel.prototype.destroy = function () {
for (var id in this._dialogs) {
if (this._dialogs.hasOwnProperty(id)) {
var div = this._dialogs[id];
if ($(div).hasClass("ui-dialog-content")) {
$(div).dialog("destroy");
}
}
for (var id in this._dialogs) {
if (this._dialogs.hasOwnProperty(id)) {
var div = this._dialogs[id];
if ($(div).hasClass("ui-dialog-content")) {
$(div).dialog("destroy");
}
}
}
};
module.exports = Panel;
......@@ -3,26 +3,23 @@
var Promise = require("bluebird");
/* exported logger */
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
var AbstractDbPanel = require('./AbstractDbPanel');
var PanelControlElementType = require('../PanelControlElementType');
function ChemicalPanel(params) {
var self = this;
params.panelName = "chemical";
params.helpTip = '<p>source: Comparative Toxicogenomics Database <a target="_ctd" href="http://ctdbase.org/">ctdbase.org</a></p>'
+ '<p>only associations between genes and chemicals with direct evidence to '
+ 'Parkinson Disease (<a href="http://bioportal.bioontology.org/ontologies/1351?p=terms&conceptid=D010300" target="_blank">D010300</a>) are displayed</p>'
+ '<p>use only the full name of chemicals according to <a target="_ctd_chemicals" href="http://ctdbase.org/voc.go?type=chem"> ctdbase/chem</a> for search</p>'
+ 'if the chemical name includes comma(s), place a semicolon behind the name to avoid a segmentation of the name</p>'
+ '<p>separate multiple search by semicolon';
params.placeholder = "full chemical name (CTD)";
AbstractDbPanel.call(this, params);
AbstractDbPanel.call(self, params);
if (this.getMap().getProject().getDisease() === undefined) {
this.disablePanel("DISEASE NOT DEFINED FOR PROJECT. PLEASE, DEFINE IT IN THE ADMIN SECTION.");
if (self.getMap().getProject().getDisease() === undefined) {
self.disablePanel("DISEASE NOT DEFINED FOR PROJECT. PLEASE, DEFINE IT IN THE ADMIN SECTION.");
}
}
......@@ -30,47 +27,49 @@ ChemicalPanel.prototype = Object.create(AbstractDbPanel.prototype);
ChemicalPanel.prototype.constructor = ChemicalPanel;
ChemicalPanel.prototype.createPreamble = function (chemical) {
var self = this;
var guiUtils = self.getGuiUtils();
var result = document.createElement("div");
if (chemical === undefined || chemical.getName() === undefined) {
result.appendChild(guiUtils.createLabel("NOT FOUND"));
} else {
result.appendChild(guiUtils.createParamLine("Chemical: ", chemical.getName()));
result.appendChild(guiUtils.createParamLine("Description: ", chemical.getDescription()));
result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", chemical.getSynonyms()));
result.appendChild(guiUtils.createParamLine("Direct Evidence: ", chemical.getDirectEvidence()));
result.appendChild(guiUtils
.createAnnotations("Direct Evidence Publications: ", chemical.getDirectEvidenceReferences()));
result.appendChild(guiUtils.createAnnotations("Sources: ", chemical.getReferences()));
result.appendChild(guiUtils.createNewLine());
}
var self = this;
var guiUtils = self.getGuiUtils();
var result = document.createElement("div");
if (chemical === undefined || chemical.getName() === undefined) {
result.appendChild(guiUtils.createLabel("NOT FOUND"));
} else {
result.appendChild(guiUtils.createParamLine("Chemical: ", chemical.getName()));
result.appendChild(guiUtils.createParamLine("Description: ", chemical.getDescription()));
result.appendChild(guiUtils.createArrayParamLine("Synonyms: ", chemical.getSynonyms()));
result.appendChild(guiUtils.createParamLine("Direct Evidence: ", chemical.getDirectEvidence()));
result.appendChild(guiUtils
.createAnnotations("Direct Evidence Publications: ", chemical.getDirectEvidenceReferences()));
result.appendChild(guiUtils.createAnnotations("Sources: ", chemical.getReferences()));
result.appendChild(guiUtils.createNewLine());
}
return result;
return result;
};
ChemicalPanel.prototype.createTableElement = function (target, icon) {
return this.createTargetRow(target, icon);
return this.createTargetRow(target, icon);
};
ChemicalPanel.prototype.searchByQuery = function () {
var self = this;
var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
var self = this;
var query = self.getControlElement(PanelControlElementType.SEARCH_INPUT).value;
return self.getOverlayDb().searchByQuery(query);
return self.getOverlayDb().searchByQuery(query);
};
ChemicalPanel.prototype.init = function () {
var self = this;
return self.getToolTipForAnnotation(self.getProject().getDisease()).then(function (toolTip) {
self.setHelpTip(toolTip);
var query = ServerConnector.getSessionData().getChemicalQuery();
if (query !== undefined) {
return this.getOverlayDb().searchByEncodedQuery(query);
} else {
return Promise.resolve();
return this.getOverlayDb().searchByEncodedQuery(query);
}
});
};
ChemicalPanel.prototype.destroy = function () {
return Promise.resolve();
return Promise.resolve();
};
ChemicalPanel.prototype.getAutocomplete = function (query) {
......@@ -91,4 +90,23 @@ ChemicalPanel.prototype.refreshSearchAutocomplete = function () {
});
};
ChemicalPanel.prototype.getToolTipForAnnotation = function (annotation) {
var self =this;
var promise = Promise.resolve('disease');
if (annotation !== null && annotation !== undefined) {
promise = ServerConnector.getMesh({id: annotation.getResource()}).then(function (mesh) {
return mesh.getName() + " (" + self.getGuiUtils().createAnnotationLink(annotation).outerHTML + ")";
});
}
return promise.then(function (diseaseString) {
var result = '<p>source: Comparative Toxicogenomics Database <a target="_ctd" href="http://ctdbase.org/">ctdbase.org</a></p>'
+ '<p>only associations between genes and chemicals with direct evidence to '
+ diseaseString + ' are displayed</p>'
+ '<p>use only the full name of chemicals according to <a target="_ctd_chemicals" href="http://ctdbase.org/voc.go?type=chem"> ctdbase/chem</a> for search</p>'
+ 'if the chemical name includes comma(s), place a semicolon behind the name to avoid a segmentation of the name</p>'
+ '<p>separate multiple search by semicolon';
return Promise.resolve(result);
});
};
module.exports = ChemicalPanel;
......@@ -13,7 +13,18 @@ var assert = chai.assert;
var logger = require('../../logger');
describe('ChemicalPanel', function () {
function createPanel(){
var parkinsonDiseaseAnnotation = new Annotation({
link: "http://bioportal.bioontology.org/ontologies/1351?p=terms&conceptid=D010300",
type: "MESH_2012",
resource: "D010300"
});
var alzheimerDiseaseAnnotation = new Annotation({
link: "http://bioportal.bioontology.org/ontologies/1351?p=terms&conceptid=D000544",
type: "MESH_2012",
resource: "D000544"
});
function createPanel() {
var map = helper.createCustomMap();
map.getModel().setId(15781);
helper.createChemicalDbOverlay(map);
......@@ -38,11 +49,7 @@ describe('ChemicalPanel', function () {
});
it('map with disease', function () {
return ServerConnector.getProject().then(function (project) {
project.setDisease(new Annotation({
link: "http://bioportal.bioontology.org/ontologies/1351?p=terms&conceptid=D010300",
type: "MESH_2012",
resource: "D010300"
}));
project.setDisease(parkinsonDiseaseAnnotation);
var map = helper.createCustomMap(project);
helper.createChemicalDbOverlay(map);
......@@ -57,6 +64,24 @@ describe('ChemicalPanel', function () {
});
});
describe('init', function () {
it('Parkinson Disease', function () {
var panel;
return ServerConnector.getProject().then(function (project) {
var map = helper.createCustomMap(project);
helper.createChemicalDbOverlay(map);
panel = new ChemicalPanel({
element: testDiv,
customMap: map
});
return panel.init();
}).then(function () {
panel.destroy();
});
});
});
describe('createPreamble', function () {
it('default', function () {
var map = helper.createCustomMap();
......@@ -125,4 +150,32 @@ describe('ChemicalPanel', function () {
});
});
describe("getToolTipForAnnotation", function () {
it("for null argument", function () {
var panel = createPanel();
return panel.getToolTipForAnnotation(null).then(function (tooltip) {
assert.ok(tooltip.indexOf("Comparative Toxicogenomics Database") >= 0);
assert.equal(tooltip.indexOf("Parkinson"), -1);
});
});
it("for Parkinson Disease", function () {
var panel = createPanel();
return panel.getToolTipForAnnotation(parkinsonDiseaseAnnotation).then(function (tooltip) {
assert.ok(tooltip.indexOf("Comparative Toxicogenomics Database") >= 0);
assert.ok(tooltip.indexOf("Parkinson") >= 0);
});
});
it("for Alzheimer Disease", function () {
var panel = createPanel();
return panel.getToolTipForAnnotation(alzheimerDiseaseAnnotation).then(function (tooltip) {
assert.ok(tooltip.indexOf("Comparative Toxicogenomics Database") >= 0);
assert.equal(tooltip.indexOf("Parkinson"), -1);
});
});
});
});
{"synonyms":["Presenile Alzheimer Dementia","Dementias, Alzheimer","Familial Alzheimer Disease (FAD)","Alzheimer Disease, Early Onset","Dementia, Primary Senile Degenerative","Alzheimer Syndrome","Acute Confusional Senile Dementia","Alzheimer Diseases, Familial (FAD)","Alzheimer Type Senile Dementia","Dementia, Alzheimer Type","Focal Onset Alzheimer's Disease","Early Onset Alzheimer Disease","Alzheimer Dementia","Late Onset Alzheimer Disease","Alzheimer Disease, Familial (FAD)","Primary Senile Degenerative Dementia","Alzheimer Sclerosis","Presenile Dementia","Dementia, Presenile","Alzheimer Dementias","Dementia, Alzheimer","Dementia, Senile","Senile Dementia","Dementia, Alzheimer-Type (ATD)","Alzheimer Type Dementia","Alzheimer's Disease, Focal Onset","Alzheimer Disease, Late Onset","Sclerosis, Alzheimer","Alzheimer-Type Dementia (ATD)","Alzheimer's Disease","Senile Dementia, Alzheimer Type","Senile Dementia, Acute Confusional","Familial Alzheimer Diseases (FAD)","Alzheimer Type Dementia (ATD)"],"name":"Alzheimer Disease","description":"A degenerative disease of the BRAIN characterized by the insidious onset of DEMENTIA. Impairment of MEMORY, judgment, attention span, and problem solving skills are followed by severe APRAXIAS and a global loss of cognitive abilities. The condition primarily occurs after age 60, and is marked pathologically by severe cortical atrophy and the triad of SENILE PLAQUES; NEUROFIBRILLARY TANGLES; and NEUROPIL THREADS. (From Adams et al., Principles of Neurology, 6th ed, pp1049-57)","id":"D000544"}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment