Skip to content

Commit

Permalink
Added event listener to the plotly element that detects changes in th…
Browse files Browse the repository at this point in the history
…e visible trace groups and records a list of currently visible species.

Added the list of currently visible species to the data set in the save plot request.
Added checks to determine if the new plot has already been saved when the visible species changes in the plot.
Added function to the plot results script to turn off trace groups for species that are not in the list of species sent in the request if they are sent.
Added key to the plots config that makes the plot static in the project manager.
Disabled default plotly legend event listeners.
Closes #981
  • Loading branch information
BryanRumsey committed Aug 19, 2020
1 parent 5d1cbb4 commit 09846ab
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 10 deletions.
6 changes: 5 additions & 1 deletion client/views/plots-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = View.extend({
getPlot: function () {
var self = this;
var plotArgs = {"title":this.model.title,"xaxis":this.model.xaxis,"yaxis":this.model.yaxis}
var data = {"plt_key":this.model.key, "plt_data":plotArgs}
var data = {"plt_key":this.model.key, "plt_data":plotArgs, "plt_species":this.model.species}
var endpoint = path.join(app.getApiPath(), 'workflow/plot-results')+"?path="+this.path+"&data="+JSON.stringify(data);
xhr({uri: endpoint, json: true}, function (err, response, body) {
if(response.statusCode >= 400) {
Expand All @@ -39,7 +39,11 @@ module.exports = View.extend({
plotFigure: function (figure) {
var self = this;
var el = this.queryByHook(this.model.key+this.model.stamp);
figure['config']['staticPlot'] = true
// figure['config']['modeBarButtonsToRemove'] = ["toggleSpikelines", "toImage", "sendDataToCloud", "autoScale2d"]
Plotly.newPlot(el, figure);
el.on('plotly_legendclick', function () {return false})
el.on('plotly_legenddoubleclick', function () {return false})
},
changeCollapseButtonText: function (e) {
var source = e.target.dataset.hook;
Expand Down
41 changes: 40 additions & 1 deletion client/views/workflow-results.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var $ = require('jquery');
var _ = require('underscore');
var path = require('path');
var xhr = require('xhr');
//support files
Expand Down Expand Up @@ -61,6 +62,7 @@ module.exports = View.extend({
this.ensembleAggragator = "avg";
this.plots = {}
this.plotArgs = {}
this.plotSpecies = {}
this.savedPlots = this.parent.settings.resultsSettings.outputs
},
render: function () {
Expand Down Expand Up @@ -194,6 +196,43 @@ module.exports = View.extend({
el.disabled = false;
}
});
el.on('plotly_restyle', function (e) {
let hiddenSpecies = el.data.filter(function (trace) {
if(trace.visible === "legendonly")
return true
}).map(trace => trace.name)
let hiddenSpeciesCounts = _.countBy(hiddenSpecies, name => name)
let names = Object.keys(hiddenSpeciesCounts)
let counts = Object.values(hiddenSpeciesCounts)
let minCount = Math.min.apply(Math, counts)
let nameOfMinCount = names[counts.indexOf(minCount)]
let isRemovable = counts.length > 1 ? Boolean(counts.filter(function (count) {
if(count === minCount)
return true
}).length <= 1) : false
if(isRemovable) {
hiddenSpecies = _.uniq(hiddenSpecies)
delete hiddenSpecies[hiddenSpecies.indexOf(nameOfMinCount)]
}
let speciesList = _.uniq(el.data.filter(function (trace) {
if(trace.visible !== "legendonly" && !hiddenSpecies.includes(trace.name) && !(trace.name.includes(" Lower Bound") || trace.name.includes(" Upper Bound"))) {
return trace.name
}
}).map(trace => trace.name))
self.plotSpecies[type] = speciesList
let plotSaved = Boolean(self.savedPlots.filter(function (plot) {
if(plot.key === type && JSON.stringify(plot.species) === JSON.stringify(speciesList))
return true
}).length > 0)
let saveBtn = $("button[data-hook=save-plot]").filter("#"+type)
if(plotSaved) {
saveBtn.prop('disabled', true)
saveBtn.text('Plot Saved to Gallery')
}else{
saveBtn.prop('disabled', false)
saveBtn.text('Save Plot to Gallery')
}
})
},
clickDownloadPNGButton: function (type) {
var pngButton = $('div[data-hook*='+type+'] a[data-title*="Download plot as a png"]')[0]
Expand Down Expand Up @@ -276,7 +315,7 @@ module.exports = View.extend({
type = this.getPsweepKey()
species = [this.speciesOfInterest]
}else{
species = this.species.map(function (specie) { return specie.name; });
species = this.plotSpecies[type];
}
let stamp = this.getTimeStamp()
var plotInfo = {"key":type, "stamp":stamp, "species":species};
Expand Down
15 changes: 10 additions & 5 deletions stochss/handlers/util/plot_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,14 @@ def edit_plot_fig(plt_fig, plt_data):
else:
plt_fig['layout'][key]['title']['text'] = plt_data[key]

return plt_fig

def customize_plot_traces(plot, plt_species):
for trace in plot['data']:
if trace['name'].split()[0] not in plt_species:
trace['visible'] = "legendonly"


def plot_results(plots_path, plt_key, plt_data=None):
def plot_results(plots_path, plt_key, plt_data=None, plt_species=None):
user_dir = "/home/jovyan"

full_path = path.join(user_dir, plots_path)
Expand All @@ -107,8 +111,9 @@ def plot_results(plots_path, plt_key, plt_data=None):

if isinstance(plt_fig, str):
return plt_fig
if not plt_data:
return json.dumps(plt_fig)
plt_fig = edit_plot_fig(plt_fig, plt_data)
if plt_data is not None:
edit_plot_fig(plt_fig, plt_data)
if plt_species is not None:
customize_plot_traces(plt_fig, plt_species)
return json.dumps(plt_fig)

8 changes: 5 additions & 3 deletions stochss/handlers/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,15 @@ async def get(self):
log.debug("Key identifying the requested plot: %s", plt_key)
plt_data = body['plt_data']
log.debug("Title and axis data for the plot: %s", plt_data)
plt_species = body['plt_species'] if "plt_species" in body.keys() else None
log.debug("Visible species in the plot: %s", plt_species)
self.set_header('Content-Type', 'application/json')
try:
if "None" in plt_data:
plt_fig = plot_results(results_path, plt_key)
plt_fig = plot_results(results_path, plt_key, plt_species=plt_species)
else:
# Add plot data to the exec cmd if its not "None"
plt_fig = plot_results(results_path, plt_key, plt_data)
plt_fig = plot_results(results_path, plt_key, plt_data=plt_data,
plt_species=plt_species)
log.debug("Plot figure: %s", plt_fig)
self.write(plt_fig)
except StochSSAPIError as err:
Expand Down

0 comments on commit 09846ab

Please sign in to comment.