diff --git a/packages/oncoprintjs/src/js/oncoprint.ts b/packages/oncoprintjs/src/js/oncoprint.ts index 09bd35db26f..b6372d556f3 100644 --- a/packages/oncoprintjs/src/js/oncoprint.ts +++ b/packages/oncoprintjs/src/js/oncoprint.ts @@ -936,6 +936,17 @@ export default class Oncoprint { this.resizeAndOrganizeAfterTimeout(); } + public resetSortableTracksSortDirection() { + if(this.webgl_unavailable || this.destroyed) { + return; + } + this.model.resetSortableTracksSortDirection(true); + + if (this.keep_sorted) { + this.sort(); + } + } + public setTrackSortDirection(track_id:TrackId, dir:TrackSortDirection) { if(this.webgl_unavailable || this.destroyed) { return; @@ -996,6 +1007,7 @@ export default class Oncoprint { const self = this; this.model.sort().then(function(x) { self.label_view.sort(self.model, self.getCellViewHeight); + self.track_options_view.sort(self.model, self.getCellViewHeight); self.cell_view.sort(self.model); self.minimap_view.sort(self.model, self.cell_view); diff --git a/packages/oncoprintjs/src/js/oncoprintheaderview.ts b/packages/oncoprintjs/src/js/oncoprintheaderview.ts index 4e56ba60c77..0785dadac68 100644 --- a/packages/oncoprintjs/src/js/oncoprintheaderview.ts +++ b/packages/oncoprintjs/src/js/oncoprintheaderview.ts @@ -57,8 +57,9 @@ export default class OncoprintHeaderView { $(document).trigger(TRACK_OPTIONS_VIEW_CLOSE_MENUS_EVENT); } - private static $makeDropdownOption(text:string, weight:string, disabled:boolean, callback:(evt:ClickEvent)=>void) { + private static $makeDropdownOption(text:string, weight:string, isDisabled?:()=>boolean, callback?:(evt:ClickEvent)=>void) { const li = $('
  • ').text(text).css({'font-weight': weight, 'font-size': 12, 'border-bottom': '1px solid rgba(0,0,0,0.3)'}); + const disabled = isDisabled && isDisabled(); if (!disabled) { if (callback) { li.addClass("clickable"); @@ -143,22 +144,28 @@ export default class OncoprintHeaderView { this.$dropdowns.push($dropdown); - // add dropdown options - group.header.options.forEach((option)=>{ - if (option.separator) { - $dropdown.append(OncoprintHeaderView.$makeDropdownSeparator()); - } else { - $dropdown.append(OncoprintHeaderView.$makeDropdownOption( - option.label || "", - option.weight || "normal", - !!option.disabled, - option.onClick && function(evt) { - evt.stopPropagation(); - option.onClick(trackGroupIndex); - } - )); - } - }); + const populateDropdownOptions = ()=>{ + // repopulate dropdown every time it opens, and every time an option is clicked, + // in order to update dynamic disabled status and weight + $dropdown.empty(); + // add dropdown options + group.header.options.forEach((option)=>{ + if (option.separator) { + $dropdown.append(OncoprintHeaderView.$makeDropdownSeparator()); + } else { + $dropdown.append(OncoprintHeaderView.$makeDropdownOption( + option.label || "", + option.weight ? option.weight() : "normal", + option.disabled, + function(evt) { + evt.stopPropagation(); + option.onClick && option.onClick(trackGroupIndex); + populateDropdownOptions(); + } + )); + } + }); + }; // add dropdown button const $img = $("") @@ -176,10 +183,11 @@ export default class OncoprintHeaderView { .on("click", (evt)=>{ evt.stopPropagation(); if ($dropdown.is(":visible")) { - $img.addClass(TOGGLE_BTN_OPEN_CLASS); + $img.removeClass(TOGGLE_BTN_OPEN_CLASS); $dropdown.fadeOut(FADE_MS); } else { - $img.removeClass(TOGGLE_BTN_OPEN_CLASS); + populateDropdownOptions(); + $img.addClass(TOGGLE_BTN_OPEN_CLASS); $dropdown.fadeIn(FADE_MS); this.closeDropdownsExcept($dropdown); } diff --git a/packages/oncoprintjs/src/js/oncoprintmodel.ts b/packages/oncoprintjs/src/js/oncoprintmodel.ts index 388ca753ca5..7d9904ccd7c 100644 --- a/packages/oncoprintjs/src/js/oncoprintmodel.ts +++ b/packages/oncoprintjs/src/js/oncoprintmodel.ts @@ -51,7 +51,7 @@ export type ActiveRules = {[ruleId:number]:boolean}; export type ActiveRulesCount = {[ruleId:number]:number}; export type TrackSortDirectionChangeCallback = (track_id:TrackId, dir:number)=>void; export type CustomTrackOption = {label?:string, separator?: boolean, onClick?:(id:TrackId)=>void, weight?:string, disabled?:boolean}; -export type CustomTrackGroupOption = {label?:string, separator?: boolean, onClick?:(id:TrackGroupIndex)=>void, weight?:string, disabled?:boolean}; +export type CustomTrackGroupOption = {label?:string, separator?: boolean, onClick?:(id:TrackGroupIndex)=>void, weight?:()=>string, disabled?:()=>boolean}; export type UserTrackSpec = { target_group?:TrackGroupIndex; cell_height?: number; @@ -835,6 +835,14 @@ export default class OncoprintModel { } this.precomputed_comparator.update(this, track_id); } + public resetSortableTracksSortDirection(no_callback?:boolean) { + const allTracks = this.getTracks(); + for (const trackId of allTracks) { + if (this.isTrackSortDirectionChangeable(trackId)) { + this.setTrackSortDirection(trackId, 0, no_callback); + } + } + } public setCellPaddingOn(cell_padding_on:boolean) { this.cell_padding_on = cell_padding_on; diff --git a/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts b/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts index e64d8380fcb..9aab35ea165 100644 --- a/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts +++ b/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts @@ -128,7 +128,7 @@ export default class OncoprintTrackOptionsView { $(document).trigger(HEADER_VIEW_CLOSE_MENUS_EVENT); } - private static $makeDropdownOption(text:string, weight:string, disabled:boolean, callback:(evt:ClickEvent)=>void) { + private static $makeDropdownOption(text:string, weight:string, disabled?:boolean, callback?:(evt:ClickEvent)=>void) { const li = $('
  • ').text(text).css({'font-weight': weight, 'font-size': 12, 'border-bottom': '1px solid rgba(0,0,0,0.3)'}); if (!disabled) { if (callback) { @@ -219,14 +219,14 @@ export default class OncoprintTrackOptionsView { self.hideMenusExcept(track_id); }); - const movingAndSortingDisabled = model.getTrackMovable(track_id) && model.isTrackInClusteredGroup(track_id); + const movingDisabled = model.getTrackMovable(track_id) && model.isTrackInClusteredGroup(track_id); if (model.getTrackMovable(track_id)) { - $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption('Move up', 'normal', movingAndSortingDisabled, function (evt) { + $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption('Move up', 'normal', movingDisabled, function (evt) { evt.stopPropagation(); self.moveUpCallback(track_id); })); - $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption('Move down', 'normal', movingAndSortingDisabled, function (evt) { + $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption('Move down', 'normal', movingDisabled, function (evt) { evt.stopPropagation(); self.moveDownCallback(track_id); })); @@ -242,7 +242,7 @@ export default class OncoprintTrackOptionsView { let $sort_inc_li:JQuery; let $sort_dec_li:JQuery; let $dont_sort_li:JQuery; - $sort_inc_li = OncoprintTrackOptionsView.$makeDropdownOption('Sort a-Z', (model.getTrackSortDirection(track_id) === 1 ? 'bold' : 'normal'), movingAndSortingDisabled, function (evt) { + $sort_inc_li = OncoprintTrackOptionsView.$makeDropdownOption('Sort a-Z', (model.getTrackSortDirection(track_id) === 1 ? 'bold' : 'normal'), false, function (evt) { evt.stopPropagation(); $sort_inc_li.css('font-weight', 'bold'); $sort_dec_li.css('font-weight', 'normal'); @@ -250,7 +250,7 @@ export default class OncoprintTrackOptionsView { self.sortChangeCallback(track_id, 1); OncoprintTrackOptionsView.renderSortArrow($sortarrow, model, track_id); }); - $sort_dec_li = OncoprintTrackOptionsView.$makeDropdownOption('Sort Z-a', (model.getTrackSortDirection(track_id) === -1 ? 'bold' : 'normal'), movingAndSortingDisabled, function (evt) { + $sort_dec_li = OncoprintTrackOptionsView.$makeDropdownOption('Sort Z-a', (model.getTrackSortDirection(track_id) === -1 ? 'bold' : 'normal'), false, function (evt) { evt.stopPropagation(); $sort_inc_li.css('font-weight', 'normal'); $sort_dec_li.css('font-weight', 'bold'); @@ -258,7 +258,7 @@ export default class OncoprintTrackOptionsView { self.sortChangeCallback(track_id, -1); OncoprintTrackOptionsView.renderSortArrow($sortarrow, model, track_id); }); - $dont_sort_li = OncoprintTrackOptionsView.$makeDropdownOption('Don\'t sort track', (model.getTrackSortDirection(track_id) === 0 ? 'bold' : 'normal'), movingAndSortingDisabled, function (evt) { + $dont_sort_li = OncoprintTrackOptionsView.$makeDropdownOption('Don\'t sort track', (model.getTrackSortDirection(track_id) === 0 ? 'bold' : 'normal'), false, function (evt) { evt.stopPropagation(); $sort_inc_li.css('font-weight', 'normal'); $sort_dec_li.css('font-weight', 'normal'); @@ -303,7 +303,7 @@ export default class OncoprintTrackOptionsView { if (option.separator) { $dropdown.append(OncoprintTrackOptionsView.$makeDropdownSeparator()); } else { - $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption(option.label || "", option.weight || "normal", !!option.disabled, option.onClick && function (evt) { + $dropdown.append(OncoprintTrackOptionsView.$makeDropdownOption(option.label || "", option.weight || "normal", option.disabled, option.onClick && function (evt) { evt.stopPropagation(); option.onClick(track_id); })); @@ -353,6 +353,10 @@ export default class OncoprintTrackOptionsView { this.renderAllOptions(model); this.resize(model, getCellViewHeight); } + public sort(model:OncoprintModel, getCellViewHeight:()=>number) { + this.renderAllOptions(model); + this.resize(model, getCellViewHeight); + } public setViewport(model:OncoprintModel, getCellViewHeight:()=>number) { this.renderAllOptions(model); this.resize(model, getCellViewHeight);