diff --git a/end-to-end-test/local/screenshots/reference/initializes_as_configured_by_default_element_chrome_1600x1000.png b/end-to-end-test/local/screenshots/reference/initializes_as_configured_by_default_element_chrome_1600x1000.png index 7ee959b502e..f4919901280 100644 Binary files a/end-to-end-test/local/screenshots/reference/initializes_as_configured_by_default_element_chrome_1600x1000.png and b/end-to-end-test/local/screenshots/reference/initializes_as_configured_by_default_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/local/screenshots/reference/initializes_correctly_when_clinicallist_config_present_in_url_element_chrome_1600x1000.png b/end-to-end-test/local/screenshots/reference/initializes_correctly_when_clinicallist_config_present_in_url_element_chrome_1600x1000.png index d8ed56457f5..7900e5ee92c 100644 Binary files a/end-to-end-test/local/screenshots/reference/initializes_correctly_when_clinicallist_config_present_in_url_element_chrome_1600x1000.png and b/end-to-end-test/local/screenshots/reference/initializes_correctly_when_clinicallist_config_present_in_url_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/local/screenshots/reference/show_stacked_bar_chart_for_patient_who_has_significant_id_signatures_element_chrome_1600x1000.png b/end-to-end-test/local/screenshots/reference/show_stacked_bar_chart_for_patient_who_has_significant_id_signatures_element_chrome_1600x1000.png index 2ae53c7f71f..349a0be14c1 100644 Binary files a/end-to-end-test/local/screenshots/reference/show_stacked_bar_chart_for_patient_who_has_significant_id_signatures_element_chrome_1600x1000.png and b/end-to-end-test/local/screenshots/reference/show_stacked_bar_chart_for_patient_who_has_significant_id_signatures_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/local/screenshots/reference/shows_oql_structural_variant_variations_element_chrome_1600x1000.png b/end-to-end-test/local/screenshots/reference/shows_oql_structural_variant_variations_element_chrome_1600x1000.png index 43c8ad12cf3..347e2a10d4b 100644 Binary files a/end-to-end-test/local/screenshots/reference/shows_oql_structural_variant_variations_element_chrome_1600x1000.png and b/end-to-end-test/local/screenshots/reference/shows_oql_structural_variant_variations_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/remote/screenshots/reference/coadread_tcga_pub_with_column_gaps_inserted_based_on_clinical_track_element_chrome_1600x1000.png b/end-to-end-test/remote/screenshots/reference/coadread_tcga_pub_with_column_gaps_inserted_based_on_clinical_track_element_chrome_1600x1000.png index f11067484cc..e2133cbeb85 100644 Binary files a/end-to-end-test/remote/screenshots/reference/coadread_tcga_pub_with_column_gaps_inserted_based_on_clinical_track_element_chrome_1600x1000.png and b/end-to-end-test/remote/screenshots/reference/coadread_tcga_pub_with_column_gaps_inserted_based_on_clinical_track_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/remote/screenshots/reference/hierarchical_sorting_when_two_tracks_have_enabled_gaps_element_chrome_1600x1000.png b/end-to-end-test/remote/screenshots/reference/hierarchical_sorting_when_two_tracks_have_enabled_gaps_element_chrome_1600x1000.png index 476ea215771..08cebfa6fa3 100644 Binary files a/end-to-end-test/remote/screenshots/reference/hierarchical_sorting_when_two_tracks_have_enabled_gaps_element_chrome_1600x1000.png and b/end-to-end-test/remote/screenshots/reference/hierarchical_sorting_when_two_tracks_have_enabled_gaps_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/remote/screenshots/reference/shows_gaps_for_sex_track_with_correct_subgroup_percentages_element_chrome_1600x1000.png b/end-to-end-test/remote/screenshots/reference/shows_gaps_for_sex_track_with_correct_subgroup_percentages_element_chrome_1600x1000.png index 0a7f14f408e..2c2b80e4150 100644 Binary files a/end-to-end-test/remote/screenshots/reference/shows_gaps_for_sex_track_with_correct_subgroup_percentages_element_chrome_1600x1000.png and b/end-to-end-test/remote/screenshots/reference/shows_gaps_for_sex_track_with_correct_subgroup_percentages_element_chrome_1600x1000.png differ diff --git a/end-to-end-test/remote/specs/core/oncoprint.gaps.spec.js b/end-to-end-test/remote/specs/core/oncoprint.gaps.spec.js index c2e919456e3..d5dbdbc9159 100644 --- a/end-to-end-test/remote/specs/core/oncoprint.gaps.spec.js +++ b/end-to-end-test/remote/specs/core/oncoprint.gaps.spec.js @@ -26,7 +26,7 @@ describe('oncoprint gap screenshot tests', () => { sexElements.dropdown_selector, 'Failed to open sex track menu' ); - await clickElement(`${sexElements.dropdown_selector} li:nth-child(9)`); // Click "show gaps" + await clickElement(`${sexElements.dropdown_selector} li:nth-child(10)`); // Click "show gaps" await browser.pause(100); // give time to sort and insert gaps await waitForOncoprint(); @@ -51,7 +51,7 @@ describe('oncoprint gap screenshot tests', () => { 'Failed to open cancer type detailed track menu' ); await clickElement( - `${cancerTypeDetailedElements.dropdown_selector} li:nth-child(9)` + `${cancerTypeDetailedElements.dropdown_selector} li:nth-child(10)` ); // Click "show gaps" await browser.pause(100); // give time to sort and insert gaps diff --git a/end-to-end-test/remote/specs/core/oncoprint.screenshot.spec.js b/end-to-end-test/remote/specs/core/oncoprint.screenshot.spec.js index 2e8240529f4..bbb47ba0517 100644 --- a/end-to-end-test/remote/specs/core/oncoprint.screenshot.spec.js +++ b/end-to-end-test/remote/specs/core/oncoprint.screenshot.spec.js @@ -153,7 +153,7 @@ describe('oncoprint screenshot tests', () => { 'Failed to open cancer type detailed track menu' ); await clickElement( - `${cancerTypeDetailedElements.dropdown_selector} li:nth-child(9)` + `${cancerTypeDetailedElements.dropdown_selector} li:nth-child(10)` ); // Click "show gaps" await browser.pause(100); // give time to sort and insert gaps diff --git a/packages/oncoprintjs/src/index.tsx b/packages/oncoprintjs/src/index.tsx index 3e44ff13e0a..c302af05069 100644 --- a/packages/oncoprintjs/src/index.tsx +++ b/packages/oncoprintjs/src/index.tsx @@ -9,6 +9,6 @@ export { } from './js/oncoprint'; export * from './js/oncoprintruleset'; -export { default as OncoprintModel } from './js/oncoprintmodel'; +export { default as OncoprintModel, GAP_MODE_ENUM } from './js/oncoprintmodel'; export * from './js/oncoprintmodel'; export { default as shapeToSvg } from './js/oncoprintshapetosvg'; diff --git a/packages/oncoprintjs/src/js/oncoprint.ts b/packages/oncoprintjs/src/js/oncoprint.ts index 905bf4f2acb..c84e39bdfa4 100644 --- a/packages/oncoprintjs/src/js/oncoprint.ts +++ b/packages/oncoprintjs/src/js/oncoprint.ts @@ -6,9 +6,9 @@ import OncoprintModel, { ColumnProp, CustomTrackOption, Datum, + GAP_MODE_ENUM, LibraryTrackSpec, SortConfig, - TrackGroup, TrackGroupHeader, TrackGroupIndex, TrackId, @@ -1234,7 +1234,7 @@ export default class Oncoprint { if (this.model.getTrackSortDirection(track_id) === 0) { if (this.model.getTrackShowGaps(track_id)) { - this.setTrackShowGaps(track_id, false); + this.setTrackShowGaps(track_id, GAP_MODE_ENUM.HIDE_GAPS); } } } @@ -1292,9 +1292,12 @@ export default class Oncoprint { this.resizeAndOrganizeAfterTimeout(); } - public setTrackShowGaps(track_id: TrackId, showGaps: boolean) { - this.model.setTrackShowGaps(track_id, showGaps); - if (this.model.getTrackSortDirection(track_id) === 0 && showGaps) { + public setTrackShowGaps(track_id: TrackId, gap_mode: GAP_MODE_ENUM) { + this.model.setTrackShowGaps(track_id, gap_mode); + if ( + this.model.getTrackSortDirection(track_id) === 0 && + gap_mode !== GAP_MODE_ENUM.HIDE_GAPS + ) { this.setTrackSortDirection(track_id, 1); } this.track_options_view.setTrackShowGaps( diff --git a/packages/oncoprintjs/src/js/oncoprintmodel.ts b/packages/oncoprintjs/src/js/oncoprintmodel.ts index 2e70d199a26..c19d0e82ed4 100644 --- a/packages/oncoprintjs/src/js/oncoprintmodel.ts +++ b/packages/oncoprintjs/src/js/oncoprintmodel.ts @@ -21,6 +21,12 @@ import PrecomputedComparator from './precomputedcomparator'; import { calculateHeaderTops, calculateTrackTops } from './modelutils'; import { OncoprintGapConfig } from './oncoprintwebglcellview'; +export enum GAP_MODE_ENUM { + SHOW_GAPS = 'SHOW_GAPS', + SHOW_GAPS_PERCENT = 'SHOW_GAPS_PERCENT', + HIDE_GAPS = 'HIDE_GAPS', +} + export type ColumnId = string; export type ColumnIndex = number; export type TrackId = number; @@ -62,7 +68,10 @@ export type TrackSortDirectionChangeCallback = ( track_id: TrackId, dir: number ) => void; -export type TrackGapChangeCallBack = (track_id: TrackId, on: boolean) => void; +export type TrackGapChangeCallBack = ( + track_id: TrackId, + mode: GAP_MODE_ENUM +) => void; export type CustomTrackOption = { label?: string; separator?: boolean; @@ -318,7 +327,7 @@ export default class OncoprintModel { private track_expansion_parent: TrackProp; private track_custom_options: TrackProp; private track_can_show_gaps: TrackProp; - private track_show_gaps: TrackProp; + private track_show_gaps: TrackProp; // Rule set properties private rule_sets: { [ruleSetId: number]: RuleSet }; @@ -571,7 +580,11 @@ export default class OncoprintModel { const precomputedComparator = model.precomputed_comparator.get(); const trackIdsWithGaps = model .getTracks() - .filter(trackId => model.getTrackShowGaps(trackId)); + .filter( + trackId => + model.getTrackShowGaps(trackId) !== + GAP_MODE_ENUM.HIDE_GAPS + ); const ids = model.visible_id_order.get(); for (let i = 1; i < ids.length; i++) { @@ -736,7 +749,7 @@ export default class OncoprintModel { this.column_left.addBoundProperty(this.column_left_no_padding); } - public setTrackShowGaps(trackId: TrackId, show: boolean) { + public setTrackShowGaps(trackId: TrackId, show: GAP_MODE_ENUM) { this.track_show_gaps[trackId] = show; this.track_gap_change_callback[trackId](trackId, show); this.ids_after_a_gap.update(this); @@ -1143,7 +1156,14 @@ export default class OncoprintModel { public getGapSize() { if (this.showGaps()) { - return 50; // this creates enough space for 3 digit percentage + switch (this.gapMode()) { + case GAP_MODE_ENUM.SHOW_GAPS: + return this.getCellWidth(true); + case GAP_MODE_ENUM.SHOW_GAPS_PERCENT: + return 50; + default: + return 50; + } } else { return this.getCellWidth(true); } @@ -1425,7 +1445,9 @@ export default class OncoprintModel { ); const trackShowGaps = ifndef(params.show_gaps_on_init, false); - this.track_show_gaps[track_id] = trackShowGaps; + this.track_show_gaps[track_id] = trackShowGaps + ? GAP_MODE_ENUM.SHOW_GAPS_PERCENT + : GAP_MODE_ENUM.HIDE_GAPS; const trackNotSorted = this.track_sort_direction[track_id] === 0; if (trackShowGaps && trackNotSorted) { this.track_sort_direction[track_id] = 1; @@ -1889,7 +1911,16 @@ export default class OncoprintModel { } public showGaps() { - return _.some(this.track_show_gaps); + return _(this.track_show_gaps) + .values() + .some(t => t !== GAP_MODE_ENUM.HIDE_GAPS); + } + + public gapMode() { + const mode = _(this.track_show_gaps) + .values() + .find(g => g !== GAP_MODE_ENUM.HIDE_GAPS); + return mode || GAP_MODE_ENUM.HIDE_GAPS; } public getOncoprintWidthNoColumnPaddingNoGaps() { diff --git a/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts b/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts index 1ddd72b2349..60c35799bb7 100644 --- a/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts +++ b/packages/oncoprintjs/src/js/oncoprinttrackoptionsview.ts @@ -1,13 +1,13 @@ import $ from 'jquery'; import menuDotsIcon from '../img/menudots.svg'; import OncoprintModel, { - TrackGroupProp, + GAP_MODE_ENUM, TrackId, TrackProp, TrackSortDirection, } from './oncoprintmodel'; -import ClickEvent = JQuery.ClickEvent; import { CLOSE_MENUS_EVENT as HEADER_VIEW_CLOSE_MENUS_EVENT } from './oncoprintheaderview'; +import ClickEvent = JQuery.ClickEvent; const TOGGLE_BTN_CLASS = 'oncoprintjs__track_options__toggle_btn_img'; const TOGGLE_BTN_OPEN_CLASS = 'oncoprintjs__track_options__open'; @@ -44,7 +44,10 @@ export default class OncoprintTrackOptionsView { sortDirection: TrackSortDirection ) => void, private unexpandCallback: TrackCallback, - private showGapsCallback: (trackId: TrackId, showGaps: boolean) => void + private showGapsCallback: ( + trackId: TrackId, + showGaps: GAP_MODE_ENUM + ) => void ) { const position = $div.css('position'); if (position !== 'absolute' && position !== 'relative') { @@ -448,31 +451,51 @@ export default class OncoprintTrackOptionsView { $dropdown.append( OncoprintTrackOptionsView.$makeDropdownSeparator() ); - const $show_gaps_opt = OncoprintTrackOptionsView.$makeDropdownOption( - 'Show gaps', - model.getTrackShowGaps(track_id) ? 'bold' : 'normal', + + const $show_gaps_percent_opt = OncoprintTrackOptionsView.$makeDropdownOption( + model.getTrackShowGaps(track_id) === + GAP_MODE_ENUM.SHOW_GAPS_PERCENT + ? 'Hide gaps (w/%)' + : 'Show Gaps (w/%)', + model.getTrackShowGaps(track_id) === + GAP_MODE_ENUM.SHOW_GAPS_PERCENT + ? 'bold' + : 'normal', false, function(evt) { evt.stopPropagation(); $show_gaps_opt.css('font-weight', 'bold'); - $dont_show_gaps_opt.css('font-weight', 'normal'); - self.showGapsCallback(track_id, true); + const mode: GAP_MODE_ENUM = [ + GAP_MODE_ENUM.SHOW_GAPS_PERCENT, + ].includes(model.getTrackShowGaps(track_id)) + ? GAP_MODE_ENUM.HIDE_GAPS + : GAP_MODE_ENUM.SHOW_GAPS_PERCENT; + self.showGapsCallback(track_id, mode); } ); - const $dont_show_gaps_opt = OncoprintTrackOptionsView.$makeDropdownOption( - "Don't show gaps", - model.getTrackShowGaps(track_id) ? 'normal' : 'bold', + + const $show_gaps_opt = OncoprintTrackOptionsView.$makeDropdownOption( + model.getTrackShowGaps(track_id) === GAP_MODE_ENUM.SHOW_GAPS + ? 'Hide gaps' + : 'Show Gaps', + model.getTrackShowGaps(track_id) === GAP_MODE_ENUM.SHOW_GAPS + ? 'bold' + : 'normal', false, function(evt) { evt.stopPropagation(); - - $show_gaps_opt.css('font-weight', 'normal'); - $dont_show_gaps_opt.css('font-weight', 'bold'); - self.showGapsCallback(track_id, false); + $show_gaps_opt.css('font-weight', 'bold'); + const mode: GAP_MODE_ENUM = [ + GAP_MODE_ENUM.SHOW_GAPS, + ].includes(model.getTrackShowGaps(track_id)) + ? GAP_MODE_ENUM.HIDE_GAPS + : GAP_MODE_ENUM.SHOW_GAPS; + self.showGapsCallback(track_id, mode); } ); + $dropdown.append($show_gaps_opt); - $dropdown.append($dont_show_gaps_opt); + $dropdown.append($show_gaps_percent_opt); } // Add custom options const custom_options = model.getTrackCustomOptions(track_id); diff --git a/packages/oncoprintjs/src/js/oncoprintwebglcellview.ts b/packages/oncoprintjs/src/js/oncoprintwebglcellview.ts index 176d5533b1c..1a698d2c142 100644 --- a/packages/oncoprintjs/src/js/oncoprintwebglcellview.ts +++ b/packages/oncoprintjs/src/js/oncoprintwebglcellview.ts @@ -11,18 +11,19 @@ import OncoprintModel, { ColumnId, ColumnLabel, ColumnProp, + GAP_MODE_ENUM, IdentifiedShapeList, TrackId, TrackOverlappingCells, TrackProp, } from './oncoprintmodel'; import OncoprintToolTip from './oncoprinttooltip'; -import { arrayFindIndex, ifndef, sgndiff } from './utils'; -import MouseUpEvent = JQuery.MouseUpEvent; -import MouseMoveEvent = JQuery.MouseMoveEvent; +import { ifndef, sgndiff } from './utils'; import { CellClickCallback, CellMouseOverCallback } from './oncoprint'; import { getFragmentShaderSource, getVertexShaderSource } from './shaders'; import _ from 'lodash'; +import MouseUpEvent = JQuery.MouseUpEvent; +import MouseMoveEvent = JQuery.MouseMoveEvent; type ColorBankIndex = number; // index into vertex bank (e.g. 0, 4, 8, ...) type ColorBank = number[]; // flat list of color: [c0,c0,c0,c0,v1,v1,v1,c1,c1,c1,c1,...] @@ -846,7 +847,10 @@ export default class OncoprintWebGLCellView { const cell_top = model.getCellTops(track_id); const cell_height = model.getCellHeight(track_id); - if (model.showGaps()) { + if ( + model.showGaps() && + model.gapMode() === GAP_MODE_ENUM.SHOW_GAPS_PERCENT + ) { const gaps = this.getGaps(model, track_id); if (gaps) { gaps.forEach((gap: OncoprintGapConfig, i: number) => { @@ -854,7 +858,8 @@ export default class OncoprintWebGLCellView { const y = model.getZoomedTrackTops()[track_id] + cell_height - - scroll_y; + scroll_y - + 4; this.drawGapLabel(gap.labelFormatter(), x, y); diff --git a/src/shared/components/oncoprint/Oncoprint.tsx b/src/shared/components/oncoprint/Oncoprint.tsx index 48e01dc6d59..ccb9653ecab 100644 --- a/src/shared/components/oncoprint/Oncoprint.tsx +++ b/src/shared/components/oncoprint/Oncoprint.tsx @@ -22,6 +22,7 @@ import { } from 'shared/model/AnnotatedMutation'; import { CustomDriverNumericGeneMolecularData } from 'shared/model/CustomDriverNumericGeneMolecularData'; import { ExtendedAlteration } from 'shared/model/ExtendedAlteration'; +import { GAP_MODE_ENUM } from 'oncoprintjs'; export type CategoricalTrackDatum = { entity: string; @@ -90,7 +91,7 @@ export class ClinicalTrackConfig { export type ClinicalTrackConfigChange = { stableId?: string; sortOrder?: string; - gapOn?: boolean; + gapMode?: GAP_MODE_ENUM; }; export type ClinicalTrackConfigMap = { @@ -313,7 +314,7 @@ export interface IOncoprintProps { onDeleteClinicalTrack?: (key: string) => void; onDeleteGeneticTrack?: (key: string, sublabel: string) => void; onTrackSortDirectionChange?: (trackId: TrackId, dir: number) => void; - onTrackGapChange?: (trackId: TrackId, gap: boolean) => void; + onTrackGapChange?: (trackId: TrackId, gap: GAP_MODE_ENUM) => void; trackKeySelectedForEdit?: string | null; setTrackKeySelectedForEdit?: (key: string | null) => void; diff --git a/src/shared/components/oncoprint/ResultsViewOncoprint.tsx b/src/shared/components/oncoprint/ResultsViewOncoprint.tsx index 89772ce219d..aee6055c16f 100644 --- a/src/shared/components/oncoprint/ResultsViewOncoprint.tsx +++ b/src/shared/components/oncoprint/ResultsViewOncoprint.tsx @@ -101,6 +101,7 @@ import classnames from 'classnames'; import { OncoprintColorModal } from './OncoprintColorModal'; import JupyterNoteBookModal from 'pages/staticPages/tools/oncoprinter/JupyterNotebookModal'; import { convertToCSV } from 'shared/lib/calculation/JSONtoCSV'; +import { GAP_MODE_ENUM } from 'oncoprintjs'; interface IResultsViewOncoprintProps { divId: string; @@ -1671,9 +1672,8 @@ export default class ResultsViewOncoprint extends React.Component< * Called when a track gap is added from within oncoprintjs UI */ @action.bound - @action.bound - private onTrackGapChange(trackId: TrackId, gapOn: boolean) { - this.handleClinicalTrackChange(trackId, { gapOn }); + private onTrackGapChange(trackId: TrackId, mode: GAP_MODE_ENUM) { + this.handleClinicalTrackChange(trackId, { gapMode: mode }); } private handleClinicalTrackChange(