Skip to content

Commit 2ffa46b

Browse files
committed
Improve styling of overview map
1 parent fc93dd5 commit 2ffa46b

File tree

1 file changed

+77
-87
lines changed

1 file changed

+77
-87
lines changed

src/viewer.js

Lines changed: 77 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -200,40 +200,6 @@ function _getRotation (metadata) {
200200
return angle + correction
201201
}
202202

203-
/**
204-
* Determine size of browser window.
205-
*
206-
* @return {number[]} Width and height of the window
207-
*
208-
* @private
209-
*/
210-
function _getWindowSize () {
211-
let width = 0
212-
let height = 0
213-
if (typeof window.innerWidth === 'number') {
214-
// Non-IE
215-
width = window.innerWidth
216-
height = window.innerHeight
217-
} else if (
218-
document.documentElement && (
219-
document.documentElement.clientWidth || document.documentElement.clientHeight
220-
)
221-
) {
222-
// IE 6+ in 'standards compliant mode'
223-
width = document.documentElement.clientWidth
224-
height = document.documentElement.clientHeight
225-
} else if (
226-
document.body && (
227-
document.body.clientWidth || document.body.clientHeight
228-
)
229-
) {
230-
// IE 4 compatible
231-
width = document.body.clientWidth
232-
height = document.body.clientHeight
233-
}
234-
return [width, height]
235-
}
236-
237203
/**
238204
* Map style options to OpenLayers style.
239205
*
@@ -729,6 +695,7 @@ const _tileGrid = Symbol('tileGrid')
729695
const _annotationManager = Symbol('annotationManager')
730696
const _annotationGroups = Symbol('annotationGroups')
731697
const _overviewMap = Symbol('overviewMap')
698+
const _updateOverviewMapSize = Symbol('updateOverviewMapSize')
732699

733700
/**
734701
* Interactive viewer for DICOM VL Whole Slide Microscopy Image instances
@@ -936,7 +903,6 @@ class VolumeImageViewer {
936903
rotation: this[_rotation],
937904
constrainOnlyCenter: false,
938905
smoothResolutionConstraint: true,
939-
smoothExtentConstraint: false,
940906
showFullExtent: true,
941907
extent: this[_pyramid].extent
942908
})
@@ -1207,26 +1173,75 @@ class VolumeImageViewer {
12071173
}
12081174

12091175
if (Math.max(...this[_pyramid].gridSizes[0]) <= 10) {
1210-
const overviewView = new View({
1211-
projection: this[_projection],
1212-
rotation: this[_rotation],
1213-
constrainOnlyCenter: false,
1214-
smoothExtentConstraint: true,
1215-
smoothResolutionConstraint: true,
1216-
minZoom: 0,
1217-
maxZoom: 0,
1218-
extent: this[_pyramid].extent
1219-
})
1220-
1176+
const center = view.getCenter()
12211177
this[_overviewMap] = new OverviewMap({
1222-
view: overviewView,
1178+
view: new View({
1179+
projection: this[_projection],
1180+
rotation: this[_rotation],
1181+
constrainOnlyCenter: true,
1182+
resolutions: this[_tileGrid].getResolutions(),
1183+
// minResolution: this[_tileGrid].getResolution(0),
1184+
minZoom: 0,
1185+
maxZoom: 0,
1186+
center: center,
1187+
extent: center.concat(center),
1188+
showFullExtent: true
1189+
}),
12231190
layers: overviewLayers,
12241191
collapsed: false,
12251192
collapsible: true,
12261193
rotateWithView: true
12271194
})
1195+
this[_updateOverviewMapSize] = () => {
1196+
const overviewElement = this[_controls].overview.element
1197+
const overviewChildren = overviewElement.children
1198+
const overviewmapElement = Object.values(overviewChildren).find(
1199+
c => c.className === 'ol-overviewmap-map'
1200+
)
1201+
// Try to fit the overview map into the target control overlay container
1202+
const height = this[_pyramid].metadata[0].TotalPixelMatrixRows
1203+
const width = this[_pyramid].metadata[0].TotalPixelMatrixColumns
1204+
const rotation = this[_rotation] / Math.PI * 180
1205+
const isRotated = !(
1206+
Math.abs(rotation - 180) < 0.01 || Math.abs(rotation - 0) < 0.01
1207+
)
1208+
const viewport = this[_map].getViewport()
1209+
const viewportHeight = viewport.clientHeight
1210+
const viewportWidth = viewport.clientWidth
1211+
const viewportHeightFraction = 0.3
1212+
const viewportWidthFraction = 0.25
1213+
const maxTargetHeight = viewportHeight * viewportHeightFraction
1214+
const maxTargetWidth = viewportWidth * viewportWidthFraction
1215+
let targetHeight
1216+
let targetWidth
1217+
if (isRotated) {
1218+
targetHeight = width
1219+
targetWidth = height
1220+
} else {
1221+
targetHeight = height
1222+
targetWidth = width
1223+
}
1224+
let resizeFactor = 1
1225+
resizeFactor = (
1226+
maxTargetWidth / targetWidth +
1227+
maxTargetHeight / targetHeight
1228+
) / 2
1229+
targetHeight *= resizeFactor
1230+
targetWidth *= resizeFactor
1231+
overviewmapElement.style.width = `${targetWidth}px`
1232+
overviewmapElement.style.height = `${targetHeight}px`
1233+
const map = this[_overviewMap].getOverviewMap()
1234+
map.updateSize()
1235+
const view = map.getView()
1236+
const center = view.getCenter()
1237+
view.fit(
1238+
center.concat(center),
1239+
{ size: map.getSize() }
1240+
)
1241+
}
12281242
} else {
12291243
this[_overviewMap] = null
1244+
this[_updateOverviewMapSize] = () => {}
12301245
}
12311246

12321247
this[_drawingSource] = new VectorSource({
@@ -1721,6 +1736,7 @@ class VolumeImageViewer {
17211736
*/
17221737
resize () {
17231738
this[_map].updateSize()
1739+
this[_updateOverviewMapSize]()
17241740
}
17251741

17261742
/**
@@ -1776,6 +1792,13 @@ class VolumeImageViewer {
17761792
...Object.values(this[_mappings])
17771793
]
17781794

1795+
const styleControlElement = (element) => {
1796+
element.style.backgroundColor = 'rgba(255,255,255,.75)'
1797+
element.style.color = 'black'
1798+
element.style.padding = '2px'
1799+
element.style.margin = '1px'
1800+
}
1801+
17791802
itemsRequiringDecodersAndTransformers.forEach(item => {
17801803
const metadata = item.pyramid.metadata
17811804
_getIccProfiles(metadata, this[_options].client).then(profiles => {
@@ -1848,6 +1871,7 @@ class VolumeImageViewer {
18481871
})
18491872

18501873
if (this[_controls].overview && this[_overviewMap]) {
1874+
// Style overview element (overriding Openlayers CSS "ol-overviewmap")
18511875
const overviewElement = this[_controls].overview.element
18521876
const overviewChildren = overviewElement.children
18531877
const overviewmapElement = Object.values(overviewChildren).find(
@@ -1865,40 +1889,10 @@ class VolumeImageViewer {
18651889
spanElement.style.color = 'black'
18661890
spanElement.style.backgroundColor = 'white'
18671891
}
1892+
styleControlElement(overviewmapElement)
18681893
overviewmapElement.style.border = '1px solid black'
18691894
overviewmapElement.style.color = 'black'
1870-
// Try to fit the overview map into the target control overlay container
1871-
const height = Math.abs(this[_pyramid].extent[1])
1872-
const width = Math.abs(this[_pyramid].extent[2])
1873-
const rotation = this[_rotation] / Math.PI * 180
1874-
const windowSize = _getWindowSize()
1875-
let targetHeight
1876-
let resizeFactor
1877-
let targetWidth
1878-
if (Math.abs(rotation - 180) < 0.01 || Math.abs(rotation - 0) < 0.01) {
1879-
if (windowSize[1] > windowSize[0]) {
1880-
targetHeight = Math.ceil(windowSize[1] * 0.2)
1881-
resizeFactor = targetHeight / height
1882-
targetWidth = width * resizeFactor
1883-
} else {
1884-
targetWidth = Math.ceil(windowSize[0] * 0.15)
1885-
resizeFactor = targetWidth / width
1886-
targetHeight = height * resizeFactor
1887-
}
1888-
} else {
1889-
if (windowSize[1] > windowSize[0]) {
1890-
targetHeight = Math.ceil(windowSize[1] * 0.2)
1891-
resizeFactor = targetHeight / width
1892-
targetWidth = height * resizeFactor
1893-
} else {
1894-
targetWidth = Math.ceil(windowSize[0] * 0.15)
1895-
resizeFactor = targetWidth / height
1896-
targetHeight = width * resizeFactor
1897-
}
1898-
}
1899-
overviewmapElement.style.width = `${targetWidth}px`
1900-
overviewmapElement.style.height = `${targetHeight}px`
1901-
this[_overviewMap].getOverviewMap().updateSize()
1895+
this[_updateOverviewMapSize]()
19021896
}
19031897
})
19041898
})
@@ -1909,10 +1903,8 @@ class VolumeImageViewer {
19091903
scaleElement.style.right = '.5em'
19101904
scaleElement.style.bottom = '.5em'
19111905
scaleElement.style.left = 'auto'
1912-
scaleElement.style.padding = '2px'
1913-
scaleElement.style.backgroundColor = 'rgba(255,255,255,.5)'
19141906
scaleElement.style.borderRadius = '4px'
1915-
scaleElement.style.margin = '1px'
1907+
styleControlElement(scaleElement)
19161908
const scaleInnerElement = this[_controls].scale.innerElement_
19171909
scaleInnerElement.style.color = 'black'
19181910
scaleInnerElement.style.fontWeight = '600'
@@ -1935,14 +1927,11 @@ class VolumeImageViewer {
19351927
positionElement.style.top = '.5em'
19361928
positionElement.style.left = 'auto'
19371929
positionElement.style.bottom = 'auto'
1938-
positionElement.style.padding = '2px'
1939-
positionElement.style.backgroundColor = 'rgba(255,255,255,.5)'
1940-
positionElement.style.borderRadius = '4px'
1941-
positionElement.style.margin = '1px'
1942-
positionElement.style.color = 'black'
19431930
positionElement.style.fontWeight = '600'
19441931
positionElement.style.fontSize = '10px'
19451932
positionElement.style.textAlign = 'center'
1933+
positionElement.style.borderRadius = '4px'
1934+
styleControlElement(positionElement)
19461935
}
19471936
}
19481937

@@ -2850,6 +2839,7 @@ class VolumeImageViewer {
28502839
return
28512840
}
28522841

2842+
// TODO: Only fetch measurements if required.
28532843
const promises = [
28542844
_fetchGraphicData({ metadataItem, bulkdataItem, client }),
28552845
_fetchGraphicIndex({ metadataItem, bulkdataItem, client }),

0 commit comments

Comments
 (0)