Commit 455568bf authored by Iker Hurtado's avatar Iker Hurtado
Browse files

DOS data conversion for graphs refactoring

- working fine for VASP and exciting codes
parent 41bcfb04
Pipeline #36338 passed with stages
in 5 seconds
......@@ -78,7 +78,7 @@
let PubSub = __webpack_require__(6);
let Router = __webpack_require__(7);
let MaterialMod = __webpack_require__(8);
let SearchModule = __webpack_require__(32);
let SearchModule = __webpack_require__(37);
let UserGuidance = __webpack_require__(33);
let DataStore = __webpack_require__(2);
......@@ -4055,14 +4055,18 @@
for (var i = 0; i < pointsY.length; i++) {
let energy = pointsY[i]/E_FACTOR;
let dos_value_spin1 = pSpin1[i]/dosValueDivisor;
let dos_value_spin1 = pSpin1[i]*dosValueDivisor;
pointsXInPlotRange.push(dos_value_spin1);
if (pSpin2 !== null) pointsXInPlotRange.push(pSpin2[i]);
//if (pSpin2 !== null) pointsXInPlotRange.push(pSpin2[i]);
pointsYInPlotRange.push(energy);
//console.log('POINTS : ',pointsX[i], energy);
console.log('POINTS : ',dos_value_spin1, energy);
this.pointsSpin1.push({x: dos_value_spin1, y: energy});
if (pSpin2 !== null)
this.pointsSpin2.push({x: pSpin2[i]/dosValueDivisor, y: energy});
if (pSpin2 !== null){
let dos_value_spin2 = pSpin2[i]*dosValueDivisor;
this.pointsSpin2.push({x: dos_value_spin2, y: energy});
pointsXInPlotRange.push(dos_value_spin2);
}
}
let maxDosVal = Math.max.apply(null, pointsXInPlotRange);
......@@ -7609,8 +7613,9 @@
/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {
/* 32 */,
/* 33 */
/***/ function(module, exports) {
/**
......@@ -7632,470 +7637,182 @@
/*
This file implements the Search Module of the application.
It's a container UI component that shows the seach part of the application:
front search interface and search results page.
This file implements the user guidance system. This complex system for
showing tips to the user is specified in the project documentation
*/
"use strict";
let util = __webpack_require__(1);
let UserGuidance = __webpack_require__(33);
let ElementTable = __webpack_require__(34);
let MaterialList = __webpack_require__(35);
let PropertiesBox = __webpack_require__(36);
//let util = require('util.js');
let body = document.querySelector('body');
let tips = [];
let tipData = [];
let currentTip;// = 1;
let independentTips = []; // if null => showing else if 'off' not showing
let addBox, table, searchBox, propertiesTabs;
let searchBarShowing = false;
// local utility functions
function getTagHtml(tag, isFormula){
return `<span class="search-label" data-el="${tag}" >
<img src="img/tag.svg" height="16px" class="remove-label"
style="vertical-align: bottom"/>
${isFormula ? util.getSubscriptedFormula(tag) : tag}
<img src="img/cross.svg" height="6px" class="remove-label"
style="vertical-align: middle; padding: 4px 3px 6px 5px;" />
</span>`;
function createUserMsg(i, width){
let element= document.createElement('div');
element.setAttribute('class','user-guidance');
element.innerHTML = '<img src="img/tip'+i+'.png" width="'+width+'px" />';
element.style.position = 'absolute';
element.style.display = 'none';
body.appendChild(element);
return element;
}
function replaceDashes(s){
return s.split('-').join('_');
function showTip(tipNumber){
if (tipNumber === 8 && !searchBarShowing) return; // Do nothing
if (tipNumber === 4 && !searchBarShowing) return; // Do nothing
let r = tipData[tipNumber].domTarget.getBoundingClientRect();
//console.log("GGGGGGGGG: ",r);
tips[tipNumber].style.top = (r.top + tipData[tipNumber].top + window.pageYOffset)+'px';
tips[tipNumber].style.left = (r.left + tipData[tipNumber].left)+'px';
tips[tipNumber].style.display = 'block';
}
// Init per user session
function init(addBoxP, tableP, searchBoxP, propertiesTabsP){
addBox = addBoxP;
table = tableP;
searchBox = searchBoxP;
propertiesTabs = propertiesTabsP;
independentTips[3] = localStorage.getItem('tip3');
independentTips[4] = localStorage.getItem('tip4');
independentTips[7] = localStorage.getItem('tip7');
class SearchMod {
createUserTips();
let currentTip = localStorage.getItem('currentTip');
if (currentTip === null){ // First time
updateCurrentTip(1);
}else{
currentTip = parseInt(currentTip);
if (currentTip < 10){ // regular case
updateCurrentTip(currentTip);
}//else { currentTip === 10 the guidance has finished
}
}
constructor() {
this.element = document.createElement('div');
this.element.setAttribute("id",'search-module');
this.element.innerHTML=
`
<div class="search-page">
<div class="searchline" style="visibility: hidden">
<div class="search-query-wrapper" style="float: left;">
<div class="search-query-box" style="float: left;">
</div>
<button class="clean-btn" style="float: right;">Clear all</button>
</div>
function createUserTips(){
<button style="float: right" class="search-btn" >Search</button>
<div style="clear: both;"></div>
<div class="exclusive-search-line">
Exclusive search <input class="exclusive-search" type="checkbox" >
</div>
</div>
if (tips.length === 0){
tips[1] = createUserMsg(1, 220);
tipData[1] = {domTarget: addBox, top: -70, left: -240 };
tips[2] = createUserMsg(2, 280);
tipData[2] = {domTarget: addBox, top: -110, left: 80 };
tips[3] = createUserMsg(3, 180);
tipData[3] = {domTarget: table, top: 180, left: 720 };
tips[4] = createUserMsg(4, 240);
tipData[4] = {domTarget: searchBox, top: 45, left: -250 };
tips[5] = createUserMsg(5, 210);
tipData[5] = {domTarget: addBox, top: -130, left: 70};
tips[6] = createUserMsg(6, 240);
tipData[6] = {domTarget: addBox, top: -100, left: 370};
tips[7] = createUserMsg(7, 220);
tipData[7] = {domTarget: propertiesTabs, top: 160, left: -40};
tips[8] = createUserMsg(8, 240);
tipData[8] = {domTarget: searchBox, top: 30, left: 760};
// Event
tips[1].addEventListener( "click", closeAndShowNext);
tips[2].addEventListener( "click", closeAndShowNext);
tips[3].addEventListener( "click", e => { closeIndependentTip(3) });
tips[4].addEventListener( "click", e => { closeIndependentTip(4) });
tips[5].addEventListener( "click", closeAndShowNext);
tips[6].addEventListener( "click", closeAndShowNext);
tips[7].addEventListener( "click", e => { closeIndependentTip(7) });
tips[8].addEventListener( "click", e => {
e.target.style.display = 'none';
updateCurrentTip(10);
});
}
}
<div class="add-buttons" >
<div class="tab-buttons" style="width: 70%; display: inline-block">
<button class="element-add-btn" id="add-tab-selected">Element</button>
<button class="formula-add-btn" style="padding: 10px 20px;" >Formula/Material</button>
<button class="props-add-btn" >Properties</button>
</div>
<div class="bool-buttons" style="width: 28%; display: inline-block" >
<button disabled >AND</button>
<button disabled >OR</button>
<button disabled >NOT</button>
<button disabled >(</button> <button disabled >)</button>
<!--<input type="checkbox" name="and-or" class="not-symbol-btn" />NOT-->
</div>
</div>
function setFinal(){
searchBarShowing = true;
if (currentTip < 10){
tips[currentTip].style.display = 'none';
updateCurrentTip(8);//currentTip = 4;
showTip(currentTip);
}
showIndependentTip(4, true);
}
<div>
<div class="triangle element-tri" style="margin: -10px 64px; visibility: visible"></div>
<div class="triangle formula-tri" style="margin: -10px 30px; visibility: hidden"></div>
<div class="triangle props-tri" style="margin: -10px 70px; visibility: hidden"></div>
</div>
function closeIndependentTip( tipNumber){
//e.preventDefault();
tips[tipNumber].style.display = 'none';
localStorage.setItem('tip'+tipNumber, 'off');
independentTips[tipNumber] = 'off';
}
<div class="add-panel">
</div>
</div> <!-- search-page -->
function closeAndShowNext(e){
e.preventDefault();
//console.log("closeAndShowNext",currentTip);
e.target.style.display = 'none';
switch (currentTip) {
case 2: currentTip = 5; break;
<div class="results-page" style="display: none">
</div>
case 6: currentTip = 8; break;
`;
default: // 1 , 5
currentTip++;
}
updateCurrentTip(currentTip);
showTip(currentTip);
}
this.searchPage = this.element.querySelector('.search-page');
this.searchQueryBox= this.element.getElementsByClassName("search-query-box")[0];
this.searchLine = this.element.querySelector('.searchline');
this.mainButton= this.element.querySelector('.search-btn');
this.cleanButton= this.element.querySelector('.clean-btn');
this.addButtonsBox= this.element.querySelector('.add-buttons');
this.addElementButton = this.addButtonsBox.querySelector('.element-add-btn');
this.addFormulaButton = this.addButtonsBox.querySelector('.formula-add-btn');
function showIndependentTip(tipNumber, value){
//console.log("showIndependentTip",tipNumber);
if (independentTips[tipNumber] === null){ // Tip has not been removed (clicked)
if (value) showTip(tipNumber);
else tips[tipNumber].style.display = 'none';
}
}
this.addPanel= this.element.querySelector('.add-panel');
this.elementTable= new ElementTable();
this.elementTable.setClickListener(elementArray => {
this.addElementsInSearchQuery(elementArray);
this.addFormulaButton.disabled = true; // Not always necessary but it simplifies the code
});
this.elementTable.setDeselectListener(e => this.removeElementORFormulaInSearchQuery(e));
this.propertiesBox= new PropertiesBox();
this.propertiesBox.setAddPropertiesListener(propsMap => {
this.addPropertiesInSearchQuery(propsMap);
});
this.formulaBox = new FormulaBox();
this.formulaBox.setAddFormulaListener(formula => {
if (formula.trim() !== ''){
this.addTagInSearchQuery(formula, 'F');
this.addElementButton.disabled = true;
this.formulaBox.disable(true);
}
});
function show(value, tip3, tip7){ // Global show - the UserGuidance is shown or hidden at all
if (currentTip < 10){ // sequential tips
if (value) showTip(currentTip);
else tips[currentTip].style.display = 'none';
}
// Independent tips
showIndependentTip(3, value && tip3);
showIndependentTip(4, value);
showIndependentTip(7, value && tip7);
}
this.formulaBox.setAddMaterialListener(materialName => {
if (materialName.trim() !== ''){
this.addTagInSearchQuery(materialName, 'material-name');
this.addElementButton.disabled = true;
this.formulaBox.disable(true);
}
});
this.materialList= new MaterialList();
this.resultsPage = this.element.querySelector('.results-page');
this.materialList.attachAndSetEvents(this.resultsPage);
function updateCurrentTip(value){
currentTip = value;
localStorage.setItem('currentTip', value);
//console.log('localStorage.currentTip:',localStorage.getItem('currentTip'));
}
this.currentTab = 'element';
this.addPanel.appendChild(this.elementTable.element);
this.userGuidance = true; // can enabled/disabled
this.showingSearchBox = false;
this.searchQuery = [];
this.queryTypes = []; //**** Types associated to query elements
// Types: element (E), formula (F), symbol (S) and prop names
this._events();
}
_events() {
// External event - Search button press
this.mainButton.addEventListener( "click", (e) => {
//console.log("this.labels: "+JSON.stringify(this.labels));
if (this.searchQuery.lenght === 0){
util.showUserMsg('No query');
}else{
let queryObj = {};
let elements = [];
queryObj.search_by = {};
this.searchQuery.forEach( (item, i) => {
if (this.queryTypes[i] === 'F') queryObj.search_by.formula = item;
else if (this.queryTypes[i] === 'E') elements.push(item);
else if (this.queryTypes[i] !== 'S'){ // property
if (this.queryTypes[i].indexOf('band-gap') === 0){ // special case
let bandGapData = this.queryTypes[i].split(':');
queryObj.band_gap = {"min": util.eV2J(bandGapData[1]),
"max": util.eV2J(bandGapData[2])};
queryObj.band_gap_direct = bandGapData[3];
}else if (this.queryTypes[i].indexOf('mass-density') === 0){ // special case
let massDensity = this.queryTypes[i].split(':');
queryObj.mass_density = {"min": massDensity[1], "max": massDensity[2]};
}else if (this.queryTypes[i].indexOf('has') === 0){// boolean fields
queryObj[replaceDashes(this.queryTypes[i])] = 'Yes';
}else // general fields
queryObj[replaceDashes(this.queryTypes[i])] = item.split(' | ');
}
});
if (elements.length > 0)
queryObj.search_by.element = elements.join(',');
let exclusiveEl = this.element.querySelector('.exclusive-search:checked');
queryObj.search_by.exclusive = (exclusiveEl === null ? '0' : '1');
this.materialList.setSearch(queryObj);
util.setBrowserHashPath('search','results');
}
});
this.cleanButton.addEventListener( "click", (e) => {
this.searchQuery = [];
this.queryTypes = [];
this.updateSearchQuery();
this.addFormulaButton.disabled = false;
this.addElementButton.disabled = false;
this.formulaBox.disable(false);
this.elementTable.deselectAllElements();
});
this.addButtonsBox.addEventListener( "click", (e) => {
if (e.target !== e.currentTarget) { // When the event source is a child
let className = e.target.className;
let index = className.indexOf('add-btn');
if (index > 0){
let selectingElement;
let selectingTab = className.substring(0, index-1);
if (selectingTab === 'element')
selectingElement = this.elementTable.element;
else if (selectingTab === 'props')
selectingElement = this.propertiesBox.element;
else if (selectingTab === 'formula')
selectingElement = this.formulaBox.element;
this.addPanel.replaceChild(selectingElement, this.addPanel.lastChild);
// Change the styles of the buttons
let selEl = this.element.querySelector('.'+this.currentTab+'-add-btn');
this._setTabSelectedStyles(selEl, false);
this._setTabSelectedStyles(e.target, true);
// Change the triangle
this.element.querySelector('.'+this.currentTab+'-tri').style.visibility = 'hidden';
this.element.querySelector('.'+selectingTab+'-tri').style.visibility = 'visible';
this.currentTab = selectingTab;
if (this.userGuidance){
if (selectingTab === 'element'){
UserGuidance.showIndependentTip(7, false);
UserGuidance.showIndependentTip(3, true);
}
else if (selectingTab === 'props'){
UserGuidance.showIndependentTip(3, false);
UserGuidance.showIndependentTip(7, true);
}else if (selectingTab === 'formula'){
UserGuidance.showIndependentTip(3, false);
UserGuidance.showIndependentTip(7, false);
}
}
}
}
});
this.searchQueryBox.addEventListener( "click", (e) => {
let className = e.target.className;
if (className === 'remove-label'){
let elSymbol = e.target.parentElement.getAttribute('data-el');
this.removeElementORFormulaInSearchQuery(elSymbol);
}
});
}
_setTabSelectedStyles(element, value){
/*
element.style.fontWeight = (value ? 'bold' : 'normal');
element.style.color = (value ? '#E56400' : '#777');
element.style.borderColor = (value ? '#E56400' : '#777');
*/
element.id = (value ? 'add-tab-selected' : '');
}
_showSearchBox(){
if (!this.showingSearchBox){
this.showingSearchBox = true;
this.searchLine.style.visibility = 'visible';
if (this.userGuidance) UserGuidance.setFinal();
}
}
_addItemInSearchQuery(item, type){
this.searchQuery.push(item);
this.queryTypes.push(type);
}
addTagInSearchQuery(tag, type){
// If the it's an element and is already in the query it's not inserted
if (type === 'E' && this.searchQuery.indexOf(tag) >= 0) return;
if ( this.searchQuery.length > 0 )
this._addItemInSearchQuery('&', 'S');
this._addItemInSearchQuery(tag, type);
this.updateSearchQuery();
this._showSearchBox();
}
addElementsInSearchQuery(elementArray){
let index = elementArray.length;
while (index--) {
this.addTagInSearchQuery(elementArray[index], 'E');
}
return true;
}
addPropertiesInSearchQuery(propsMap){
propsMap.forEach((values/*Array*/, propName) => {
let i = this.queryTypes.indexOf(propName);
if (i < 0)
this.addTagInSearchQuery(values.join(' | '), propName);
else{
let currentValues = this.searchQuery[i].split(' | ');
//console.log('Current VAlues: ',currentValues);
values.forEach(value => {
if (currentValues.indexOf(value) < 0) currentValues.push(value);
});
this.searchQuery[i] = currentValues.join(' | ');
this.updateSearchQuery();
this._showSearchBox();
}
});
}
removeElementORFormulaInSearchQuery(element){
let index = this.searchQuery.indexOf(element);
if (index >= 0){
this.searchQuery.splice(index, 1);
this.queryTypes.splice(index, 1);
if ( index > 0 ){
let prevSymbol = this.searchQuery[index-1];
if (prevSymbol === '&' || prevSymbol === '|') {
this.searchQuery.splice(index-1, 1);
this.queryTypes.splice(index-1, 1);
}
}
// Check if after the removal a & or | symbol remains as the first in query
if (this.queryTypes[0] === 'S'){
this.searchQuery.splice(0, 1);
this.queryTypes.splice(0, 1);
}
this.updateSearchQuery();
if (util.ELEMENTS.indexOf(element) >= 0){
this.elementTable.deselectElement(element);
if (this.queryTypes.indexOf('E') < 0)
this.addFormulaButton.disabled = false;
}else{
this.addElementButton.disabled = false;
this.formulaBox.disable(false);
}
//console.log(" final searchQuery: ",this.searchQuery);
}
return true;
}
updateSearchQuery(){
let html= '';
for (let i = 0; i < this.searchQuery.length; i++) {
let type = this.queryTypes[i];
if (type === 'S')
html+= `<span class="search-query-symbol" > ${this.searchQuery[i]} </span>`;
else
html+= getTagHtml(this.searchQuery[i], ( type === 'F' ? true : false));
}
console.log('this.updateSearchQuery: ', this.searchQuery ,this.queryTypes);
this.searchQueryBox.innerHTML= html;
}
showResultsPage(){
this.searchPage.style.display= 'none';
this.resultsPage.style.display= 'block';
if (this.userGuidance) UserGuidance.show(false);
}
showSearchPage(){
this.searchPage.style.display= 'block';
this.resultsPage.style.display= 'none';
if (this.userGuidance){
setTimeout(() => {
UserGuidance.init(this.addButtonsBox, this.elementTable.element,
this.searchLine, this.propertiesBox.tabsElement);
UserGuidance.show(true, this.currentTab === 'element',
this.currentTab === 'props');
}, 400);
}
}
}
class FormulaBox{
constructor() {
this.element = document.createElement('div');
this.element.setAttribute("id",'formula-box');
this.element.innerHTML=
`
<div style="padding-bottom: 40px;">
<input type="text" class="formula-text-field"
placeholder="Add formula to the search query above" >
<button class="adding-formula-btn" disabled>Add to query</button>
</div>
<div>
<input type="text" class="material-name-text-field"
placeholder="Add material name to the search query above" >
<button class="adding-material-name-btn" disabled>Add to query</button>
</div>
`;
this.formulaTextField = this.element.querySelector('.formula-text-field');
this.formulaButton = this.element.querySelector('.adding-formula-btn');