From 9750e0309500259e9a56e267ce87984fb5bb5e53 Mon Sep 17 00:00:00 2001 From: gebele Date: Mon, 26 Nov 2018 15:29:26 +0000 Subject: clean out; better response codes; prepare for batch --- views/batch.haml | 238 ++++++++++++++++++++++++++--------------------- views/layout.haml | 5 +- views/model_details.haml | 2 +- views/style.scss | 7 ++ 4 files changed, 142 insertions(+), 110 deletions(-) (limited to 'views') diff --git a/views/batch.haml b/views/batch.haml index 0e7efc7..c5dd2f4 100644 --- a/views/batch.haml +++ b/views/batch.haml @@ -1,109 +1,133 @@ -%div.well - %a.btn.btn-warning{:href => to('/predict')} - %span.glyphicon.glyphicon-menu-left{:aria=>{:hidden=>"true"}} +:javascript + + function progress(value,id) { + var percent = Math.round(value); + var bar = document.getElementById("bar_"+id); + var prog = document.getElementById("progress_"+id); + bar.style.width = value + '%'; + if (percent == 100){ + prog.style.display = "none"; + }; + }; + + var HttpClient = function() { + this.get = function(aUrl, aCallback) { + var anHttpRequest = new XMLHttpRequest(); + anHttpRequest.onreadystatechange = function() { + if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200) + aCallback(anHttpRequest.responseText); + } + anHttpRequest.open( "GET", aUrl, true ); + anHttpRequest.send( null ); + } + }; + + var markers = []; + + function renderTask(task_id,model_id,id) { + var uri = "#{to("/prediction/task/?turi=")}" + task_id; + var aClient = new HttpClient(); + aClient.get(uri, function(res) { + var response = JSON.parse(res); + progress(response['percent'],id); + if (response['percent'] == 100){ + window.clearInterval(markers[id]); + $("a#downbutton_"+id).removeClass("disabled"); + $("a#detailsbutton_"+id).removeClass("disabled"); + $("a#downbutton_"+id).removeClass("btn-outline-info"); + $("a#detailsbutton_"+id).removeClass("btn-outline-info"); + $("a#downbutton_"+id).addClass("btn-info"); + $("a#detailsbutton_"+id).addClass("btn-info"); + }; + }); + }; + function simpleTemplating(data) { + var html = ''; + return html; + }; + function pagePredictions(task_id,model_id,id){ + button = document.getElementById("detailsbutton_"+id); + span = button.childNodes[1]; + if (span.className == "fa fa-caret-right"){ + span.className = "fa fa-caret-down"; + $('#data-container_'+id).removeClass("d-none"); + $('#data-container_'+id).show(); + $('#pager_'+id).show(); + $('#pager_'+id).pagination({ + dataSource: '#{to("/prediction/task/?predictions=")}' + task_id + '&model=' + model_id , + locator: 'prediction', + totalNumber: #{@compounds.size}, + pageSize: 1, + showPageNumbers: true, + showGoInput: true, + formatGoInput: 'go to <%= input %>', + formatAjaxError: function(jqXHR, textStatus, errorThrown) { + $('#data-container_'+id).html(errorThrown); + }, + /*ajax: { + beforeSend: function() { + $('#data-container_'+id).html('Loading content ...'); + } + },*/ + callback: function(data, pagination) { + var html = simpleTemplating(data); + $('#data-container_'+id).html(html); + //$('#data-container_'+id).css("min-height", $(window).height() + "px" ); + } + }); + } else if (span.className = "fa fa-caret-down"){ + span.className = "fa fa-caret-right"; + $('#data-container_'+id).hide(); + $('#pager_'+id).hide(); + }; + }; +%div.card + %a.btn.btn-warning{:href => to("/predict?tpid=#{@pid}")} + %span.fa.fa-caret-left{:aria=>{:hidden=>"true"}} New Prediction - %a.btn.btn-success{:id => "downbutton", :href=>"#{to("/predict/#{@tmppath}/#{@filename}")}", :title=>"download"} - %span.glyphicon.glyphicon-download-alt - Download CSV +%div.card.bg-light + %div.card-body + %h3.card-title="Batch prediction results for: #{@filename}" - / show file name - %topline - %div.row - %div.col-md-4 - %h3 Batch Prediction Results: - %div.col-md-8 - %h3= @filename - - / displays all prediction result in one table - %div.table-responsive - %table.table.table-bordered{:id=>"batch", :style=>"background-color:white;"} - %tbody - - if @warnings - - @warnings.each do |warning| - %tr - %td - %b Warning - %td - = warning.sub(/\b(tmp\/)\b/,"") - - @view.each do |compound, array| - %tr - %td{:style=>"vertical-align:top;"} - %p= compound.svg - %p= compound.smiles - - array.each do |model,prediction| - %td{:style=>"vertical-align:top;white-space:nowrap;"} - - model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression" - - unit = model.unit - - %b{:class => "title"} - = "#{model.endpoint.gsub('_', ' ')} (#{model.species})" - - / check for prediction - - if prediction[:value] - %p - / show model type (classification|regression) - %b Type: - = type - %p - / check for database hit - - if prediction[:info] =~ /\b(identical)\b/i - - / show message about dbhit and measurements - %p - %b Compound is part of the training dataset - %p - %b Measured activity: - %br - - if prediction[:measurements].is_a?(Array) - = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)} (#{unit})
#{compound.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("
") : prediction[:measurements].join(", ") - - else - = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)} (#{unit})
#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements] - - - / show prediction - %p - %b Prediction: - %br - = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})
#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value] - - / show prediction interval or probability - %p - - if type == "Regression" - %b 95% Prediction interval: - - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval]) - %br - = interval.nil? ? "" : "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} (#{unit})" - %br - = "#{compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{compound.mmol_to_mg(interval[0].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil? - - else - %b Probability: - - unless prediction[:probabilities].nil? - - probabilities = "" - - prediction[:probabilities].each{|k,v| probabilities += "#{k}: #{v.signif(3)}
"} - %br - = probabilities - / show warnings - %p - - if !prediction[:info].blank? - %b Info: - %br - %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",
") - - if !prediction[:warnings].blank? - %b Warnings: - - prediction[:warnings].uniq.each do |warning| - %br - %p=warning.sub(/substances/, "substances
").sub(/prediction\:/, "prediction\:
") - - / no prediction - - else - %br - - if !prediction[:info].blank? - %b Info: - %br - %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",
") - - if !prediction[:warnings].blank? - %b Warnings: - - prediction[:warnings].uniq.each do |warning| - %br - %p=warning.sub(/substances/, "substances
").sub(/prediction\:/, "prediction\:
") - %tr + - @models.each_with_index do |model,idx| + - m = Model::Validation.find model + - task = @tasks[idx].id + #result.caret.bg-light{:id=>idx} + %div.card-body + %div.row + %div.col-6 + %h5.card-title="#{m.endpoint} (#{m.species})" + #pager{:id=>idx} + %div.col-6 + %a.btn.btn-outline-info.btn-sm.disabled{:id => "detailsbutton_#{idx}", :data=>{:toggle=>"collapse"}, :href=>"javascript:void(0)", :onclick=>"pagePredictions('#{task}','#{model}','#{idx}')"} + %span.fa.fa-caret-right + Details + %a.btn.btn-outline-info.btn-sm.disabled{:id => "downbutton_#{idx}", :href=>"#{to("/predict/csv/#{task}/#{model}/#{@filename}")}", :title=>"download"} + %span.fa.fa-download + CSV + %div{:id=>"progress_#{idx}", :style=>"width:100%;height:3px;position:relative;background-color:#ccc;"} + %div{:id=>"bar_#{idx}", :style=>"background-color: #4CAF50;width:10px;height:3px;position:absolute;"} + - # increase interval timer for large datasets + - ctimer = ((@compounds.size/1000) == 0 ? 1000 : ((@compounds.size/1000)*1000)) + :javascript + var timer = #{ctimer}; + $(document).ready(function(){ + // check button class before execute a task + if (#{idx} > 0){ + markers[#{idx}] = setInterval(function(){ + var button = document.getElementById("detailsbutton_#{idx-1}"); + if(!button.classList.contains('disabled')){ + renderTask('#{task}','#{model}',#{idx}); + } + }, timer ); + }else{ + markers[#{idx}] = setInterval(function(){ + renderTask('#{task}','#{model}',#{idx}); + }, timer ); + }; + }); + #data-container.card.d-none{:id=>idx} diff --git a/views/layout.haml b/views/layout.haml index a520ed6..5e0445a 100644 --- a/views/layout.haml +++ b/views/layout.haml @@ -8,12 +8,13 @@ %link{:rel=>'icon', :type=>'image/x-icon', :href=>'/images/favicon.ico'} %link{:href=>"/stylesheets/bootstrap.min.css", :rel=>"stylesheet"} %link{:href=>"/stylesheets/font-awesome.min.css", :rel=>"stylesheet"} + %link{:href=>"/stylesheets/pagination.css", :rel=>"stylesheet"} %link{:href=>"/style.css", :rel=>"stylesheet"} %script{ :src=>"/javascripts/jquery.min.js"} %script{ :src=>"/javascripts/popper.min.js"} %script{:src=>"/javascripts/lazar-gui.js"} %script{ :src=>"/javascripts/bootstrap.js"} - //%script{ :src=>"/javascripts/bootstrap.js.map"} + %script{:src=>"/javascripts/pagination.min.js"} //%script{:src=>"/javascripts/google_analytics_lazar.js"} %body %noscript @@ -43,7 +44,7 @@ Problems, bugs, ideas for improvements ? Please report at our %a{:href => 'https://github.com/opentox/lazar-gui/issues', :rel => "external"} issue tracker , check out the - %a{:href=> to("/faq")} FAQ + %a{:href=> to("/predict/faq")} FAQ page or send us an email. %a{ :href=>"mailto:info@in-silico.ch?subject=[lazar v#{@version}]", :target=>"_top"} %span.fa.fa-envelope diff --git a/views/model_details.haml b/views/model_details.haml index 3f1cc7a..5417a48 100644 --- a/views/model_details.haml +++ b/views/model_details.haml @@ -151,7 +151,7 @@ %div.card.bg-light %div.card-body %h6.card-title QMRF: - %a.btn.btn-outline-info{:href=>"#{to("/report/#{model.id}")}", :id=>"report#{model.id}", :style=>"font-size:small;"} + %a.btn.btn-outline-info{:href=>"#{to("/predict/report/#{model.id}")}", :id=>"report#{model.id}", :style=>"font-size:small;"} %span.fa.fa-download XML %br diff --git a/views/style.scss b/views/style.scss index f15fd21..5d47872 100644 --- a/views/style.scss +++ b/views/style.scss @@ -65,3 +65,10 @@ ul.share-buttons{ .footer{ margin-top:3em; } +.single-batch{ + width: 100%; +} +.single-batch{ + table-layout: fixed; + width: 100%; +} -- cgit v1.2.3