From b052e6c6b1a742d3fb99409427ac3dfb02f77505 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 3 Feb 2017 15:29:35 +0100 Subject: [PATCH] overview dialog extracted to separate class --- .../src/main/js/gui/AbstractGuiElement.js | 42 ++++ frontend-js/src/main/js/gui/OverviewDialog.js | 221 ++++++++++++++++ frontend-js/src/main/js/gui/Panel.js | 6 +- .../src/main/js/map/AbstractCustomMap.js | 2 +- frontend-js/src/main/js/map/ControlType.js | 1 - frontend-js/src/main/js/map/CustomMap.js | 235 ------------------ .../src/main/js/map/CustomMapOptions.js | 2 +- frontend-js/src/main/js/map/Submap.js | 3 +- frontend-js/src/main/js/minerva.js | 15 ++ .../src/test/js/gui/OverviewDialog-test.js | 54 ++++ frontend-js/src/test/js/helper.js | 18 ++ .../src/test/js/map/AbstractCustomMap-test.js | 7 + .../src/test/js/map/CustomMapOptions-test.js | 11 + frontend-js/src/test/js/minerva-test.js | 19 ++ frontend-js/testFiles/projectWithImages.json | 1 + .../model/map/OverviewModelLink.java | 8 +- .../api/project/ProjectMetaData.java | 35 --- .../api/project/ProjectRestImpl.java | 76 +++++- .../lcsb/mapviewer/api/RestTestFunctions.java | 47 +++- .../api/project/AllProjectTests.java | 1 - .../api/project/ProjectMetaDataTest.java | 41 --- .../api/project/ProjectRestImplTest.java | 29 +++ .../model/complex_model_with_submaps.zip | Bin 0 -> 8240 bytes .../view/OverviewLinkViewFactory.java | 11 +- web/src/main/webapp/index.xhtml | 17 +- web/src/main/webapp/resources/css/global.css | 7 + web/src/main/webapp/resources/css/style.css | 3 - 27 files changed, 562 insertions(+), 350 deletions(-) create mode 100644 frontend-js/src/main/js/gui/AbstractGuiElement.js create mode 100644 frontend-js/src/main/js/gui/OverviewDialog.js create mode 100644 frontend-js/src/test/js/gui/OverviewDialog-test.js create mode 100644 frontend-js/testFiles/projectWithImages.json delete mode 100644 rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java create mode 100644 rest-api/testFiles/model/complex_model_with_submaps.zip diff --git a/frontend-js/src/main/js/gui/AbstractGuiElement.js b/frontend-js/src/main/js/gui/AbstractGuiElement.js new file mode 100644 index 0000000000..fe83a4a46f --- /dev/null +++ b/frontend-js/src/main/js/gui/AbstractGuiElement.js @@ -0,0 +1,42 @@ +"use strict"; + +/* exported logger */ + +var ObjectWithListeners = require('../ObjectWithListeners'); + +var logger = require('../logger'); + +function AbstractGuiElement(params) { + ObjectWithListeners.call(this, params); + + var self = this; + + self.setElement(params.element); + self.setMap(params.customMap); +} + +AbstractGuiElement.prototype = Object.create(ObjectWithListeners.prototype); +AbstractGuiElement.prototype.constructor = AbstractGuiElement; + +AbstractGuiElement.prototype.setMap = function(map) { + if (map===undefined || map===null) { + throw new Error("map must be defined"); + } + this._map = map; +}; + +AbstractGuiElement.prototype.getMap = function() { + return this._map; +}; + +AbstractGuiElement.prototype.setElement = function(element) { + if (element === undefined || element === null) { + throw new Error("DOM Element must be defined"); + } + this._element = element; +}; + +AbstractGuiElement.prototype.getElement = function() { + return this._element; +}; +module.exports = AbstractGuiElement; diff --git a/frontend-js/src/main/js/gui/OverviewDialog.js b/frontend-js/src/main/js/gui/OverviewDialog.js new file mode 100644 index 0000000000..20245945eb --- /dev/null +++ b/frontend-js/src/main/js/gui/OverviewDialog.js @@ -0,0 +1,221 @@ +"use strict"; + +/* exported logger */ + +var AbstractGuiElement = require('./AbstractGuiElement'); +var GuiConnector = require('../GuiConnector'); + +var functions = require('../functions'); +var logger = require('../logger'); + +function OverviewDialog(params) { + AbstractGuiElement.call(this, params); + var self = this; + $(self.getElement()).dialog({ + autoOpen : false, + resizable : false, + }); +} + +OverviewDialog.prototype = Object.create(AbstractGuiElement.prototype); +OverviewDialog.prototype.constructor = OverviewDialog; + +OverviewDialog.prototype.showOverview = function(overviewImageId) { + var self = this; + var map = self.getMap(); + + var project = map.getProject(); + + // resize dialog + var htmlTag = self.getElement(); + + var width = Math.floor(window.innerWidth * 2 / 3); + var height = Math.floor(window.innerHeight * 2 / 3); + + $(self.getElement()).dialog("option", "width", width + 60); + $(self.getElement()).dialog("option", "height", height + 60); + + // remove all child nodes from overview div + while (htmlTag.hasChildNodes()) { + htmlTag.removeChild(htmlTag.lastChild); + } + + var content = document.createElement("div"); + htmlTag.appendChild(content); + + var canvasDebug = document.createElement("canvas"); + canvasDebug.className = "canvasDebugClass"; + canvasDebug.style.display = "none"; + htmlTag.appendChild(canvasDebug); + + if (overviewImageId === undefined) { + this.overviewImage = project.getTopOverviewImage(); + } else { + this.overviewImage = null; + var images = project.getOverviewImages(); + for (var i = 0; i < images.length; i++) { + if (images[i].idObject === overviewImageId) { + this.overviewImage = images[i]; + } + } + + if (this.overviewImage === null) { + logger.warn("Unknown overview image with id = " + overviewImageId); + this.overviewImage = project.getTopOverviewImage(); + } + } + + // add image to overview div + this.overviewImageTag = document.createElement("IMG"); + this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename; + content.appendChild(this.overviewImageTag); + + var ratio = 1.0; + + // check how image should be resized to fit dialog and resize it manually!!! + if (width / this.overviewImage.width > height / this.overviewImage.height) { + this.overviewImageTag.style.height = height + "px"; + ratio = height / this.overviewImage.height; + width = this.overviewImage.width * ratio; + $(self.getElement()).dialog("option", "width", width + 60); + } else { + this.overviewImageTag.style.width = width + "px"; + ratio = width / this.overviewImage.width; + height = this.overviewImage.height * ratio; + $(self.getElement()).dialog("option", "height", height + 60); + } + + // on click event (what should happen when we click on the image) + var onclickevent = function getClickPosition(e) { + var parentPosition = functions.getPosition(e.currentTarget); + var xPosition = e.clientX - parentPosition.x; + var yPosition = e.clientY - parentPosition.y; + + var imgWidth = self.overviewImageTag.offsetWidth; + + var currentRatio = imgWidth / self.overviewImage.width; + + var xNormal = xPosition / currentRatio; + var yNormal = yPosition / currentRatio; + var point = { + x : xNormal, + y : yNormal + }; + + var link = null; + for (var i = 0; i < self.overviewImage.links.length; i++) { + if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { + if (link === null) { + link = self.overviewImage.links[i]; + } else { + logger.warn("More than one link found. Skipping"); + } + } + } + if (link !== null) { + if (link.type === "OverviewModelLink") { + logger.debug("Opening model from overview. ModelId: " + link.modelLinkId); + logger.debug("link coordinates [" + link.idObject + "]: " + link.latLng); + // TODO min zoom value can be different for every map, it should be + // changed in the future + map.showModel(link.modelLinkId, link.latLng, link.zoomLevel + map.getMinZoom()); + overviewDialog.hide(); + } else if (link.type === "OverviewImageLink") { + logger.debug("Opening image from overview. ImageId: " + link.imageLinkId); + self.showOverview(link.imageLinkId); + } else if (link.type === "OverviewSearchLink") { + logger.debug("Sending search query. Query: " + link.query); + GuiConnector.search(link.query); + overviewDialog.hide(); + } else { + logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject); + } + } + }; + + this.overviewImageTag.onclick = onclickevent; + + // resize canvas where on mouse over highligh will appear + + // in debug mode draw clickable shapes + if (map.isDebug()) { + canvasDebug.style.display = ""; + canvasDebug.width = width; + canvasDebug.height = height; + canvasDebug.onclick = onclickevent; + this.drawClickableShapes(canvasDebug, ratio); + } + + this.overviewImage.mousePos = { + x : 0, + y : 0 + }; + + // this listener should be called when mouse moves over image, it purpose is + // to change coursor to pointer when mouse enters clickable polygon and back + // to normal when mouse leaves such region + var onmousemove = function getMouseOverPosition(e) { + var position = functions.getPosition(e.currentTarget); + position.x = e.clientX - position.x; + position.y = e.clientY - position.y; + + var imgWidth = self.overviewImageTag.offsetWidth; + + var currentRatio = imgWidth / self.overviewImage.width; + + var xNormal = position.x / currentRatio; + var yNormal = position.y / currentRatio; + var point = { + x : xNormal, + y : yNormal + }; + + if (self.overviewImage.mousePos.x !== position.x || self.overviewImage.mousePos.y !== position.y) { + self.overviewImage.mousePos = position; + var link = null; + for (var i = 0; i < self.overviewImage.links.length; i++) { + if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { + link = self.overviewImage.links[i]; + } + } + if (link === null) { + e.currentTarget.style.cursor = "auto"; + } else { + e.currentTarget.style.cursor = "pointer"; + } + } + }; + + // onmousemove listener should be assigned to canvas (which is on top of the + // image) and overviewimage (just in case something went wrong with resizing + // canvas) + canvasDebug.onmousemove = onmousemove; + this.overviewImageTag.onmousemove = onmousemove; + + $(self.getElement()).dialog("open"); +}; + +OverviewDialog.prototype.drawClickableShapes = function(canvas, ratio) { + var ctx = canvas.getContext("2d"); + // clear canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + for (var i = 0; i < this.overviewImage.links.length; i++) { + ctx.beginPath(); + var polygon = this.overviewImage.links[i].polygon; + for (var j = 0; j < polygon.length; j++) { + var x = polygon[j].x * ratio; + var y = polygon[j].y * ratio; + ctx.moveTo(x, y); + x = polygon[(j + 1) % polygon.length].x * ratio; + y = polygon[(j + 1) % polygon.length].y * ratio; + ctx.lineTo(x, y); + } + ctx.stroke(); + } +}; + +OverviewDialog.prototype.destroy = function() { + $(this.getElement()).dialog("destroy"); +}; + +module.exports = OverviewDialog; diff --git a/frontend-js/src/main/js/gui/Panel.js b/frontend-js/src/main/js/gui/Panel.js index 4d0f5e111d..370fcb4096 100644 --- a/frontend-js/src/main/js/gui/Panel.js +++ b/frontend-js/src/main/js/gui/Panel.js @@ -3,12 +3,12 @@ /* exported logger */ var GuiConnector = require('../GuiConnector'); -var ObjectWithListeners = require('../ObjectWithListeners'); +var AbstractGuiElement = require('./AbstractGuiElement'); var logger = require('../logger'); function Panel(params) { - ObjectWithListeners.call(this, params); + AbstractGuiElement.call(this, params); var self = this; @@ -18,7 +18,7 @@ function Panel(params) { } -Panel.prototype = Object.create(ObjectWithListeners.prototype); +Panel.prototype = Object.create(AbstractGuiElement.prototype); Panel.prototype.constructor = Panel; Panel.prototype.disablePanel = function(message) { diff --git a/frontend-js/src/main/js/map/AbstractCustomMap.js b/frontend-js/src/main/js/map/AbstractCustomMap.js index fda3320aa4..e91fee19c9 100644 --- a/frontend-js/src/main/js/map/AbstractCustomMap.js +++ b/frontend-js/src/main/js/map/AbstractCustomMap.js @@ -963,7 +963,7 @@ AbstractCustomMap.prototype.setDebug = function(debug) { }; AbstractCustomMap.prototype.isDebug = function() { - return this.debug === true; + return this._debug === true; }; AbstractCustomMap.prototype.getTopLeftLatLng = function() { diff --git a/frontend-js/src/main/js/map/ControlType.js b/frontend-js/src/main/js/map/ControlType.js index 2612e7d1b8..a6b80995c1 100644 --- a/frontend-js/src/main/js/map/ControlType.js +++ b/frontend-js/src/main/js/map/ControlType.js @@ -1,7 +1,6 @@ "use strict"; var ControlType = { - COMMENT_CHECKBOX : "COMMENT_CHECKBOX", SUBMAP_DIALOGS : "SUBMAP_DIALOGS", LOGO_IMG : "LOGO_IMG", LOGO_2_IMG : "LOGO_2_IMG", diff --git a/frontend-js/src/main/js/map/CustomMap.js b/frontend-js/src/main/js/map/CustomMap.js index 322dee81b1..1bbcea3e86 100644 --- a/frontend-js/src/main/js/map/CustomMap.js +++ b/frontend-js/src/main/js/map/CustomMap.js @@ -45,10 +45,6 @@ function CustomMap(options) { this.customizeGoogleMapView(options.getMapDiv()); - this.createBelt(); - - this.createMapMenu(); - this.createMapChangedCallbacks(); this.overlayCollections = []; @@ -127,15 +123,6 @@ CustomMap.prototype.createLogo = function() { this.getGoogleMap().controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(logoControlDiv); }; -CustomMap.prototype.createBelt = function() { - var self = this; - - this.divBelt = document.createElement('DIV'); - this.divBelt.className = "headerBelt"; - - this.getGoogleMap().controls[google.maps.ControlPosition.TOP_LEFT].push(this.divBelt); -}; - CustomMap.prototype.clearOverlays = function() { for ( var overlayName in this.overlayCollections) { if (this.overlayCollections.hasOwnProperty(overlayName)) { @@ -271,25 +258,6 @@ CustomMap.prototype.openLayoutByName = function(name) { } }; -CustomMap.prototype.createMapMenu = function() { - var selfMap = this; - - // create a button for overview images when the image is available - if (this.getTopOverviewImage() !== undefined && this.getTopOverviewImage() !== null) { - var submenuButtonDiv2 = document.createElement('button'); - submenuButtonDiv2.id = "overview_button"; - submenuButtonDiv2.innerHTML = "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> SHOW OVERVIEW"; - submenuButtonDiv2.className = "overview_button"; - submenuButtonDiv2.onclick = (function() { - return function() { - selfMap.showOverview(); - return false; - }; - })(); - this.divBelt.appendChild(submenuButtonDiv2); - } -}; - CustomMap.prototype.registerSource = function(overlayCollection) { var self = this; @@ -569,209 +537,6 @@ CustomMap.prototype.removeSelection = function() { } }; -/** - * This method will hide google map view and will present single image overview - * of the data. - */ -CustomMap.prototype.showOverview = function(overviewImageId) { - var overviewDialog = GuiConnector.getOverviewDialog(); - overviewDialog.syncWindowResize(); - if (this.getOverviewDiv() === undefined) { - logger.warn("Cannot show overview, because overview div is undefined"); - } else { - logger.debug("Show overview"); - overviewDialog.show(); - - // resize dialog - var htmlTag = GuiConnector.getOverviewHtmlTag(); - - var width = Math.floor(window.innerWidth * 2 / 3); - var height = Math.floor(window.innerHeight * 2 / 3); - - htmlTag.style.height = (height + 50) + "px"; - htmlTag.style.width = (width + 20) + "px"; - - var self = this; - - // remove all child nodes from overview div - while (this.getOverviewDiv().hasChildNodes()) { - this.getOverviewDiv().removeChild(this.getOverviewDiv().lastChild); - } - - if (overviewImageId === undefined || overviewImageId === null) { - this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; - } else { - this.overviewImage = null; - for (var i = 0; i < this.getConfiguration().OVERVIEW_IMAGES.length; i++) { - if (this.getConfiguration().OVERVIEW_IMAGES[i].idObject === overviewImageId) { - this.overviewImage = this.getConfiguration().OVERVIEW_IMAGES[i]; - } - } - - if (this.overviewImage === null) { - logger.warn("Unknown overview image with id = " + overviewImageId); - this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; - } - } - - // add image to overview div - this.overviewImageTag = document.createElement("IMG"); - this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename; - this.getOverviewDiv().appendChild(this.overviewImageTag); - - var ratio = 1.0; - - // check how image should be resized to fit dialog and resize it manually!!! - if (width / this.overviewImage.width > height / this.overviewImage.height) { - this.overviewImageTag.style.height = height + "px"; - ratio = height / this.overviewImage.height; - width = this.overviewImage.width * ratio; - - htmlTag.style.width = (width + 20) + "px"; - } else { - this.overviewImageTag.style.width = width + "px"; - ratio = width / this.overviewImage.width; - height = this.overviewImage.height * ratio; - - htmlTag.style.height = (height + 50) + "px"; - } - - // center dialog - overviewDialog.jq.css("top", Math.max(0, (($(window).height() - overviewDialog.jq.outerHeight()) / 2) - + $(window).scrollTop()) - + "px"); - overviewDialog.jq.css("left", Math.max(0, (($(window).width() - overviewDialog.jq.outerWidth()) / 2) - + $(window).scrollLeft()) - + "px"); - - // on click event (what should happen when we click on the image) - var onclickevent = function getClickPosition(e) { - var parentPosition = functions.getPosition(e.currentTarget); - var xPosition = e.clientX - parentPosition.x; - var yPosition = e.clientY - parentPosition.y; - - var imgWidth = self.overviewImageTag.offsetWidth; - - var currentRatio = imgWidth / self.overviewImage.width; - - var xNormal = xPosition / currentRatio; - var yNormal = yPosition / currentRatio; - var point = { - x : xNormal, - y : yNormal - }; - - var link = null; - for (var i = 0; i < self.overviewImage.links.length; i++) { - if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { - if (link === null) { - link = self.overviewImage.links[i]; - } else { - logger.warn("More than one link found. Skipping"); - } - } - } - if (link !== null) { - if (link.type === "OverviewModelLink") { - logger.debug("Opening model from overview. ModelId: " + link.modelLinkId); - logger.debug("link coordinates [" + link.idObject + "]: " + link.latLng); - // TODO min zoom value can be different for every map, it should be - // changed in the future - self.showModel(link.modelLinkId, link.latLng, link.zoomLevel + self.getConfiguration().MIN_ZOOM); - overviewDialog.hide(); - } else if (link.type === "OverviewImageLink") { - logger.debug("Opening image from overview. ImageId: " + link.imageLinkId); - self.showOverview(link.imageLinkId); - } else if (link.type === "OverviewSearchLink") { - logger.debug("Sending search query. Query: " + link.query); - GuiConnector.search(link.query); - overviewDialog.hide(); - } else { - logger.warn("Unknown type of link: " + link.type + ". Don't know what to do... LinkId: " + link.idObject); - } - } - }; - - this.overviewImageTag.onclick = onclickevent; - - // resize canvas where on mouse over highligh will appear - var canvas = document.getElementById("canvasDebug"); - canvas.width = width; - canvas.height = height; - canvas.onclick = onclickevent; - - // in debug mode draw clickable shapes - if (this.isDebug()) { - this.drawClickableShapes(canvas, ratio); - } - - this.overviewImage.mousePos = { - x : 0, - y : 0 - }; - - // this listener should be called when mouse moves over image, it purpose is - // to change coursor to pointer when mouse enters clickable polygon and back - // to normal when mouse leaves such region - var onmousemove = function getMouseOverPosition(e) { - var position = functions.getPosition(e.currentTarget); - position.x = e.clientX - position.x; - position.y = e.clientY - position.y; - - var imgWidth = self.overviewImageTag.offsetWidth; - - var currentRatio = imgWidth / self.overviewImage.width; - - var xNormal = position.x / currentRatio; - var yNormal = position.y / currentRatio; - var point = { - x : xNormal, - y : yNormal - }; - - if (self.overviewImage.mousePos.x !== position.x || self.overviewImage.mousePos.y !== position.y) { - self.overviewImage.mousePos = position; - var link = null; - for (var i = 0; i < self.overviewImage.links.length; i++) { - if (functions.pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { - link = self.overviewImage.links[i]; - } - } - if (link === null) { - e.currentTarget.style.cursor = "auto"; - } else { - e.currentTarget.style.cursor = "pointer"; - } - } - }; - - // onmousemove listener should be assigned to canvas (which is on top of the - // image) and overviewimage (just in case something went wrong with resizing - // canvas) - canvas.onmousemove = onmousemove; - this.overviewImageTag.onmousemove = onmousemove; - } -}; - -CustomMap.prototype.drawClickableShapes = function(canvas, ratio) { - var ctx = canvas.getContext("2d"); - // clear canvas - ctx.clearRect(0, 0, canvas.width, canvas.height); - for (var i = 0; i < this.overviewImage.links.length; i++) { - ctx.beginPath(); - var polygon = this.overviewImage.links[i].polygon; - for (var j = 0; j < polygon.length; j++) { - var x = polygon[j].x * ratio; - var y = polygon[j].y * ratio; - ctx.moveTo(x, y); - x = polygon[(j + 1) % polygon.length].x * ratio; - y = polygon[(j + 1) % polygon.length].y * ratio; - ctx.lineTo(x, y); - } - ctx.stroke(); - } -}; - CustomMap.prototype.showModel = function(id, point, zoomLevel) { if (point !== undefined) { this.setCenter(id, point); diff --git a/frontend-js/src/main/js/map/CustomMapOptions.js b/frontend-js/src/main/js/map/CustomMapOptions.js index 6a16eb0a6a..262e7748ad 100644 --- a/frontend-js/src/main/js/map/CustomMapOptions.js +++ b/frontend-js/src/main/js/map/CustomMapOptions.js @@ -110,7 +110,7 @@ CustomMapOptions.prototype.setMapDiv = function(mapDiv) { }; CustomMapOptions.prototype.isDebug = function() { - return this.debug === true; + return this._debug === true; }; module.exports = CustomMapOptions; diff --git a/frontend-js/src/main/js/map/Submap.js b/frontend-js/src/main/js/map/Submap.js index f24f4a01e3..18c3b3e7d6 100644 --- a/frontend-js/src/main/js/map/Submap.js +++ b/frontend-js/src/main/js/map/Submap.js @@ -24,7 +24,8 @@ function Submap(customMap, model) { markerOptimization : customMap.isMarkerOptimization(), bigLogo : customMap.isBigLogo(), customTouchInterface : customMap.isCustomTouchInterface(), - project : null + project : null, + debug: customMap.isDebug() })); this.initialized = false; diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js index 1c463a5d8d..5bdc7b08a3 100644 --- a/frontend-js/src/main/js/minerva.js +++ b/frontend-js/src/main/js/minerva.js @@ -14,6 +14,7 @@ var DrugPanel = require('./gui/DrugPanel'); var MiRnaDbOverlay = require('./map/overlay/MiRnaDbOverlay'); var MiRnaPanel = require('./gui/MiRnaPanel'); var OverlayPanel = require('./gui/OverlayPanel'); +var OverviewDialog = require('./gui/OverviewDialog'); var SearchDbOverlay = require('./map/overlay/SearchDbOverlay'); var SearchPanel = require('./gui/SearchPanel'); var SubmapPanel = require('./gui/SubmapPanel'); @@ -292,6 +293,20 @@ function create(params) { }; })(); + if (project.getTopOverviewImage()!== undefined && project.getTopOverviewImage()!== null) { + var overviewDialog = new OverviewDialog({ + customMap: result, + element: document.getElementsByName("overviewDialog")[0] + }); + var showOverviewButton = document.getElementsByName("showOverviewButton")[0]; + showOverviewButton.onclick = (function() { + return function() { + overviewDialog.showOverview(); + return false; + }; + })(); + showOverviewButton.style.display=""; + } if (ServerConnector.getSessionData().getShowComments()) { result.getControl(ControlType.COMMENT_CHECKBOX).checked=true; diff --git a/frontend-js/src/test/js/gui/OverviewDialog-test.js b/frontend-js/src/test/js/gui/OverviewDialog-test.js new file mode 100644 index 0000000000..3168c97275 --- /dev/null +++ b/frontend-js/src/test/js/gui/OverviewDialog-test.js @@ -0,0 +1,54 @@ +"use strict"; + +var Helper = require('../helper'); + +require("../mocha-config.js"); + +var CustomMap = require('../../../main/js/map/CustomMap'); +var OverviewDialog = require('../../../main/js/gui/OverviewDialog'); +var Project = require('../../../main/js/map/data/Project'); + +var chai = require('chai'); +var assert = chai.assert; +var logger = require('../logger'); + +describe('OverviewDialog', function() { + + var helper; + before(function() { + helper = new Helper(); + }); + + it('open image', function() { + return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) { + var project = new Project(JSON.parse(fileContent)); + var options = helper.createOptions(project); + var map = new CustomMap(options); + + var dialog = new OverviewDialog({ + element : testDiv, + customMap : map + }); + + dialog.showOverview(project.getOverviewImages()[1].idObject); + dialog.destroy(); + }); + }); + + it('open invalid image', function() { + return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) { + var project = new Project(JSON.parse(fileContent)); + var options = helper.createOptions(project); + var map = new CustomMap(options); + + var dialog = new OverviewDialog({ + element : testDiv, + customMap : map + }); + + dialog.showOverview(-1123); + dialog.destroy(); + }); + }); + +}); diff --git a/frontend-js/src/test/js/helper.js b/frontend-js/src/test/js/helper.js index 18d101d871..9990242cb1 100644 --- a/frontend-js/src/test/js/helper.js +++ b/frontend-js/src/test/js/helper.js @@ -65,6 +65,24 @@ Helper.prototype.createMenuDiv = function() { clearButton.setAttribute("name", "clearButton"); result.appendChild(clearButton); + var showOverviewButton = document.createElement("button"); + showOverviewButton.setAttribute("name", "showOverviewButton"); + result.appendChild(showOverviewButton); + + + return result; +}; + +Helper.prototype.createDialogsDiv = function() { + var result = document.createElement("div"); + result.setAttribute("name", "dialogs"); + result.appendChild(this.createOverviewDialogDiv()); + return result; +}; + +Helper.prototype.createOverviewDialogDiv = function() { + var result = document.createElement("div"); + result.setAttribute("name", "overviewDialog"); return result; }; diff --git a/frontend-js/src/test/js/map/AbstractCustomMap-test.js b/frontend-js/src/test/js/map/AbstractCustomMap-test.js index 50bfabb18b..47e295e032 100644 --- a/frontend-js/src/test/js/map/AbstractCustomMap-test.js +++ b/frontend-js/src/test/js/map/AbstractCustomMap-test.js @@ -368,4 +368,11 @@ describe('AbstractCustomMap', function() { }); }); + + it("getDebug", function() { + var map = helper.createAbstractCustomMap(); + map.setDebug(true); + assert.ok(map.isDebug()); + }); + }); diff --git a/frontend-js/src/test/js/map/CustomMapOptions-test.js b/frontend-js/src/test/js/map/CustomMapOptions-test.js index 42060a7a44..e5e6a1243e 100644 --- a/frontend-js/src/test/js/map/CustomMapOptions-test.js +++ b/frontend-js/src/test/js/map/CustomMapOptions-test.js @@ -48,4 +48,15 @@ describe('CustomMapOptions', function() { assert.equal(0, logger.getErrors().length); assert.equal(0, logger.getWarnings().length); }); + + it("getDebug", function() { + var project = helper.createProject(); + var options = new CustomMapOptions({ + mapDiv : testDiv, + project : project, + debug : true, + }); + + assert.ok(options.isDebug()); + }); }); diff --git a/frontend-js/src/test/js/minerva-test.js b/frontend-js/src/test/js/minerva-test.js index 43ee593d93..8a3499805c 100644 --- a/frontend-js/src/test/js/minerva-test.js +++ b/frontend-js/src/test/js/minerva-test.js @@ -5,6 +5,7 @@ var Helper = require('./helper'); require("./mocha-config.js"); var minerva = require('../../main/js/minerva'); +var Project = require('../../main/js/map/data/Project'); var chai = require('chai'); var assert = chai.assert; @@ -23,11 +24,15 @@ describe('minerva global', function() { global.menuDiv = helper.createMenuDiv(); document.body.appendChild(global.menuDiv); + + global.dialogsDiv = helper.createDialogsDiv(); + document.body.appendChild(global.dialogsDiv); }); afterEach(function() { document.body.removeChild(global.leftPanelTab); document.body.removeChild(global.menuDiv); + document.body.removeChild(global.dialogsDiv); }); it('create', function() { @@ -39,6 +44,20 @@ describe('minerva global', function() { }); }); + it('create with overview', function() { + return ServerConnector.readFile("testFiles/projectWithImages.json").then(function(fileContent) { + var project = new Project(JSON.parse(fileContent)); + var options = helper.createOptions(project); + + return minerva.create(options); + }).then(function(result) { + assert.ok(result); + assert.equal(logger.getWarnings().length, 1); + var showOverviewButton = document.getElementsByName("showOverviewButton")[0]; + showOverviewButton.onclick(); + }); + }); + it("showComments", function() { var options = helper.createCustomMapOptions(); return minerva.create(options).then(function() { diff --git a/frontend-js/testFiles/projectWithImages.json b/frontend-js/testFiles/projectWithImages.json new file mode 100644 index 0000000000..b989ec48df --- /dev/null +++ b/frontend-js/testFiles/projectWithImages.json @@ -0,0 +1 @@ +{"version":"0","idObject":18115,"name":"UNKNOWN DISEASE MAP","projectId":"complex_model_with_images","description":"","map":{"name":"main","idObject":19397,"tileSize":256,"width":495,"height":357,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19397,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested0","creator":"","inputDataAvailable":"false","idObject":17987},{"modelId":19397,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal0","creator":"","inputDataAvailable":"false","idObject":17988},{"modelId":19397,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty0","creator":"","inputDataAvailable":"false","idObject":17989}],"submodels":[{"name":"s2","idObject":19400,"tileSize":256,"width":451,"height":253,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19400,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested2","creator":"","inputDataAvailable":"false","idObject":17984},{"modelId":19400,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal2","creator":"","inputDataAvailable":"false","idObject":17985},{"modelId":19400,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty2","creator":"","inputDataAvailable":"false","idObject":17986}],"submodels":[],"centerLatLng":{"lat":79.19006423440219,"lng":-135.09977827050997},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":78.0903352323621,"lng":-90.0}},{"name":"s3","idObject":19399,"tileSize":256,"width":421,"height":315,"minZoom":2,"maxZoom":3,"layouts":[{"modelId":19399,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested3","creator":"","inputDataAvailable":"false","idObject":17978},{"modelId":19399,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal3","creator":"","inputDataAvailable":"false","idObject":17979},{"modelId":19399,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty3","creator":"","inputDataAvailable":"false","idObject":17980}],"submodels":[],"centerLatLng":{"lat":79.19139766235872,"lng":-135.10688836104512},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":74.06362505154212,"lng":-90.0}},{"name":"s1","idObject":19398,"tileSize":256,"width":571,"height":276,"minZoom":2,"maxZoom":4,"layouts":[{"modelId":19398,"name":"Pathways and compartments","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_nested1","creator":"","inputDataAvailable":"false","idObject":17981},{"modelId":19398,"name":"Network","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_normal1","creator":"","inputDataAvailable":"false","idObject":17982},{"modelId":19398,"name":"Empty","status":"Not available","progress":"0.00","directory":"fbdbe43de73fe38f62889b89cb863adb/_empty1","creator":"","inputDataAvailable":"false","idObject":17983}],"submodels":[],"centerLatLng":{"lat":79.18613072613702,"lng":-135.07880910683014},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":79.44906929997262,"lng":-90.0}}],"centerLatLng":{"lat":79.18840067864828,"lng":-135.0909090909091},"topLeftLatLng":{"lat":85.05112877980659,"lng":-180.0},"bottomRightLatLng":{"lat":74.71754541589858,"lng":-90.0}},"overviewImageViews":[{"filename":"fbdbe43de73fe38f62889b89cb863adb/sub_image.png","width":963,"height":639,"links":[{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":1,"latLng":{"lat":84.89177465079632,"lng":-161.8181818181818},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2369}],"idObject":1261},{"filename":"fbdbe43de73fe38f62889b89cb863adb/test.png","width":963,"height":639,"links":[{"polygon":[{"x":10.0,"y":10.0},{"x":100.0,"y":10.0},{"x":100.0,"y":100.0},{"x":10.0,"y":100.0}],"imageLinkId":1261,"type":"OverviewImageLink","idObject":2370},{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":0,"latLng":{"lat":84.89177465079632,"lng":-178.1818181818182},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2371}],"idObject":1262}],"topOverviewImage":{"filename":"fbdbe43de73fe38f62889b89cb863adb/test.png","width":963,"height":639,"links":[{"polygon":[{"x":10.0,"y":10.0},{"x":100.0,"y":10.0},{"x":100.0,"y":100.0},{"x":10.0,"y":100.0}],"imageLinkId":1261,"type":"OverviewImageLink","idObject":2370},{"polygon":[{"x":200.0,"y":200.0},{"x":200.0,"y":400.0},{"x":400.0,"y":400.0},{"x":400.0,"y":200.0}],"zoomLevel":0,"latLng":{"lat":84.89177465079632,"lng":-178.1818181818182},"modelLinkId":19397,"type":"OverviewModelLink","idObject":2371}],"idObject":1262}} \ No newline at end of file diff --git a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java index 60589e09f1..b3ecb4f642 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/OverviewModelLink.java @@ -71,12 +71,8 @@ public class OverviewModelLink extends OverviewLink { * @return the model * @see #linkedModel */ - public Model getLinkedModel() { - if (linkedModel != null) { - return linkedModel.getModel(); - } else { - return null; - } + public ModelData getLinkedModel() { + return linkedModel; } /** diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java index 6f8f5fcc44..090b6d0dc1 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java @@ -69,41 +69,6 @@ public class ProjectMetaData implements Serializable { protected ProjectMetaData() { } - public ProjectMetaData(Project project) { - OverviewImageViewFactory factory = new OverviewImageViewFactory(); - ModelData model = null; - if (project.getModels().size() > 0) { - model = project.getModels().iterator().next(); - } - - this.setName(project.getName()); - this.setProjectId(project.getProjectId()); - this.setIdObject(project.getId()); - - if (model != null) { - this.setOverviewImageViews(factory.createList(model.getOverviewImages())); - this.setVersion(model.getMapVersion()); - this.setDescription(model.getNotes()); - - Set<OverviewImage> set = new HashSet<OverviewImage>(); - set.addAll(model.getOverviewImages()); - for (OverviewImage image : model.getOverviewImages()) { - for (OverviewLink ol : image.getLinks()) { - if (ol instanceof OverviewImageLink) { - set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); - } - } - } - if (set.size() > 0) { - this.setTopOverviewImage(factory.create(set.iterator().next())); - } else if (model.getOverviewImages().size() > 0) { - logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename()); - this.setTopOverviewImage(factory.create(model.getOverviewImages().get(0))); - } - this.setMap(new ModelMetaData(model)); - - } - } /** * @return the version diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java index 0588b6d4ce..27157aa2be 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java @@ -17,7 +17,11 @@ import org.springframework.web.bind.annotation.RequestParam; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.map.OverviewImage; +import lcsb.mapviewer.model.map.OverviewImageLink; +import lcsb.mapviewer.model.map.OverviewLink; import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.map.reaction.Modifier; import lcsb.mapviewer.model.map.reaction.Product; import lcsb.mapviewer.model.map.reaction.Reactant; @@ -32,31 +36,35 @@ import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; import lcsb.mapviewer.services.search.data.LightReactionView; import lcsb.mapviewer.services.view.AnnotationViewFactory; +import lcsb.mapviewer.services.view.OverviewImageViewFactory; @Transactional(value = "txManager") public class ProjectRestImpl { - Logger logger = Logger.getLogger(ProjectRestImpl.class); + Logger logger = Logger.getLogger(ProjectRestImpl.class); @Autowired - private IUserService userService; + private IUserService userService; @Autowired - private IProjectService projectService; + private IProjectService projectService; @Autowired - private IModelService modelService; + private IModelService modelService; @Autowired - private ISearchService searchService; + private ISearchService searchService; @Autowired - AnnotationViewFactory annotationViewFactory; + AnnotationViewFactory annotationViewFactory; + + @Autowired + private OverviewImageViewFactory factory; public ProjectMetaData getMetaData(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token) throws SecurityException { Project project = projectService.getProjectByProjectId(projectId, userService.getToken(token)); - ProjectMetaData result = new ProjectMetaData(project); + ProjectMetaData result = createData(project); if (project.getOrganism() != null) { result.setOrganism(annotationViewFactory.create(project.getOrganism())); } @@ -66,6 +74,43 @@ public class ProjectRestImpl { return result; } + private ProjectMetaData createData(Project project) { + ProjectMetaData result = new ProjectMetaData(); + ModelData model = null; + if (project.getModels().size() > 0) { + model = project.getModels().iterator().next(); + } + + result.setName(project.getName()); + result.setProjectId(project.getProjectId()); + result.setIdObject(project.getId()); + + if (model != null) { + result.setOverviewImageViews(factory.createList(model.getOverviewImages())); + result.setVersion(model.getMapVersion()); + result.setDescription(model.getNotes()); + + Set<OverviewImage> set = new HashSet<OverviewImage>(); + set.addAll(model.getOverviewImages()); + for (OverviewImage image : model.getOverviewImages()) { + for (OverviewLink ol : image.getLinks()) { + if (ol instanceof OverviewImageLink) { + set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); + } + } + } + if (set.size() > 0) { + result.setTopOverviewImage(factory.create(set.iterator().next())); + } else if (model.getOverviewImages().size() > 0) { + logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename()); + result.setTopOverviewImage(factory.create(model.getOverviewImages().get(0))); + } + result.setMap(new ModelMetaData(model)); + } + + return result; + } + /** * @return the userService * @see #userService @@ -355,4 +400,21 @@ public class ProjectRestImpl { return searchService.getSuggestedQueryList(model); } + /** + * @return the factory + * @see #factory + */ + public OverviewImageViewFactory getFactory() { + return factory; + } + + /** + * @param factory + * the factory to set + * @see #factory + */ + public void setFactory(OverviewImageViewFactory factory) { + this.factory = factory; + } + } diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java b/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java index 336cd7a914..52f66532ff 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/RestTestFunctions.java @@ -46,11 +46,18 @@ import org.xml.sax.SAXException; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.exception.InvalidXmlSchemaException; +import lcsb.mapviewer.converter.ComplexZipConverter; +import lcsb.mapviewer.converter.ComplexZipConverterParams; import lcsb.mapviewer.converter.ConverterParams; +import lcsb.mapviewer.converter.InvalidInputDataExecption; import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.converter.zip.ModelZipEntryFile; +import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.SubmodelType; import lcsb.mapviewer.persist.DbUtils; import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.utils.CreateProjectParams; import lcsb.mapviewer.services.view.AuthenticationToken; @Transactional(value = "txManager") @@ -160,19 +167,43 @@ public abstract class RestTestFunctions { private static Map<String, Model> models = new HashMap<String, Model>(); protected Model getModelForFile(String fileName, boolean fromCache) throws Exception { + Model result = null; if (!fromCache) { logger.debug("File without cache: " + fileName); - return new CellDesignerXmlParser().createModel(new ConverterParams().filename(fileName)); + result = getModelForFile(fileName); + } else { + result = RestTestFunctions.models.get(fileName); + if (result == null) { + logger.debug("File to cache: " + fileName); + + result = getModelForFile(fileName); + RestTestFunctions.models.put(fileName, result); + } } - Model result = RestTestFunctions.models.get(fileName); - if (result == null) { - logger.debug("File to cache: " + fileName); + return result; + } - CellDesignerXmlParser parser = new CellDesignerXmlParser(); - result = parser.createModel(new ConverterParams().filename(fileName).sizeAutoAdjust(false)); - RestTestFunctions.models.put(fileName, result); + private Model getModelForFile(String fileName) throws InvalidInputDataExecption, IOException { + if (fileName.endsWith("zip")) { + ComplexZipConverter<CellDesignerXmlParser> parser = new ComplexZipConverter<CellDesignerXmlParser>(CellDesignerXmlParser.class); + ComplexZipConverterParams complexParams; + complexParams = new ComplexZipConverterParams().zipFile(fileName); + ZipEntryFile entry1 = new ModelZipEntryFile("main.xml", "main", true, false, SubmodelType.UNKNOWN); + ZipEntryFile entry2 = new ModelZipEntryFile("submaps/s1.xml", "s1", false, false, SubmodelType.UNKNOWN); + ZipEntryFile entry3 = new ModelZipEntryFile("submaps/s2.xml", "s2", false, false, SubmodelType.UNKNOWN); + ZipEntryFile entry4 = new ModelZipEntryFile("submaps/s3.xml", "s3", false, false, SubmodelType.UNKNOWN); + ZipEntryFile entry5 = new ModelZipEntryFile("submaps/mapping.xml", "mapping", false, true, SubmodelType.UNKNOWN); + complexParams.entry(entry1); + complexParams.entry(entry2); + complexParams.entry(entry3); + complexParams.entry(entry4); + complexParams.entry(entry5); + + return parser.createModel(complexParams); + + } else { + return new CellDesignerXmlParser().createModel(new ConverterParams().filename(fileName)); } - return result; } protected String createTmpFileName() { diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java index befbc95854..0453ff0272 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java @@ -6,7 +6,6 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ ModelMetaDataTest.class,// - ProjectMetaDataTest.class,// ProjectRestImplTest.class }) public class AllProjectTests { diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java deleted file mode 100644 index 706e7db2f9..0000000000 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectMetaDataTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package lcsb.mapviewer.api.project; - -import static org.junit.Assert.assertNotNull; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; - -import com.google.gson.Gson; - -import lcsb.mapviewer.model.Project; - -public class ProjectMetaDataTest { - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testToGson() { - try { - Project project = new Project(); - ProjectMetaData data = new ProjectMetaData(project); - Gson gson = new Gson(); - assertNotNull(gson.toJson(data)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - -} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java index f3ffe752fd..6155d0b7a0 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java @@ -2,6 +2,7 @@ package lcsb.mapviewer.api.project; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -17,6 +18,8 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; +import com.google.gson.Gson; + import lcsb.mapviewer.api.RestTestFunctions; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.services.interfaces.IModelService; @@ -75,6 +78,32 @@ public class ProjectRestImplTest extends RestTestFunctions { } } + @Test + public void testGetMetaData() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + ProjectMetaData result = projectRest.getMetaData("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetMetaDataForComplexWithImages() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/complex_model_with_submaps.zip"); + ProjectMetaData result = projectRest.getMetaData("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + private ProjectRestImpl createMockProjectRest(String string) throws Exception { Model model = super.getModelForFile(string, true); IModelService mockModelService = Mockito.mock(IModelService.class); diff --git a/rest-api/testFiles/model/complex_model_with_submaps.zip b/rest-api/testFiles/model/complex_model_with_submaps.zip new file mode 100644 index 0000000000000000000000000000000000000000..5985c849bbeff096451d99b43a430ec6c266cf5b GIT binary patch literal 8240 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 literal 0 HcmV?d00001 diff --git a/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java index 40d88478e4..c602505e0c 100644 --- a/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/view/OverviewLinkViewFactory.java @@ -25,7 +25,7 @@ public class OverviewLinkViewFactory extends AbstractViewFactory<OverviewLink, O /** * Default class logger. */ - private static Logger logger = Logger.getLogger(OverviewLinkViewFactory.class); + private static Logger logger = Logger.getLogger(OverviewLinkViewFactory.class); @Override public OverviewLinkView create(OverviewLink object) { @@ -37,10 +37,11 @@ public class OverviewLinkViewFactory extends AbstractViewFactory<OverviewLink, O result.setPolygon(object.getPolygon()); if (object instanceof OverviewModelLink) { - result.setModelLinkId(((OverviewModelLink) object).getLinkedModel().getId()); - CoordinationConverter cc = new CoordinationConverter(((OverviewModelLink) object).getLinkedModel()); - result.setLatLng(cc.toLatLng(new Point2D.Double(((OverviewModelLink) object).getxCoord(), ((OverviewModelLink) object).getyCoord()))); - result.setZoomLevel(((OverviewModelLink) object).getZoomLevel()); + OverviewModelLink modelLink = (OverviewModelLink) object; + result.setModelLinkId(modelLink.getLinkedModel().getId()); + CoordinationConverter cc = new CoordinationConverter(modelLink.getLinkedModel()); + result.setLatLng(cc.toLatLng(new Point2D.Double(modelLink.getxCoord(), modelLink.getyCoord()))); + result.setZoomLevel(modelLink.getZoomLevel()); } else if (object instanceof OverviewImageLink) { result.setImageLinkId(((OverviewImageLink) object).getLinkedOverviewImage().getId()); diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml index f7208909b3..6e0199f6ad 100644 --- a/web/src/main/webapp/index.xhtml +++ b/web/src/main/webapp/index.xhtml @@ -47,7 +47,7 @@ function initMap(){ bigLogo : windowsTouchInterface, overviewDiv : overviewDiv, customTouchInterface: windowsTouchInterface, - debug:true, + debug:minerva.GuiConnector.getParams['debug']!==undefined, dataCollections: [ {name: "search"}, @@ -122,6 +122,14 @@ function initMap(){ </button> </div> <div name="versionDiv" class="headerTextBold"/> + + <div style="float: left;"> + <button name="showOverviewButton" class="overview_button" style="display:none" > + <i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> + SHOW OVERVIEW + </button> + </div> + <div class="rightHeaderMenu"> <div class="div4checkboxes"> <input type="checkbox" name ="legendCheckbox" /> @@ -130,7 +138,7 @@ function initMap(){ <input type="checkbox" name="commentCheckbox"/> <label for ="commentCheckbox" >COMMENTS</label> - <button class="overview_button" name="refreshCommentButton" style="display:none"> + <button name="refreshCommentButton" class="overview_button" style="display:none"> <i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i> </button> </div> @@ -172,6 +180,11 @@ function initMap(){ <ui:include src="/WEB-INF/components/map/feedbackDialog.xhtml" /> <ui:include src="/WEB-INF/components/map/missingConnectionDialog.xhtml" /> + +<div name="dialogs"> + <div name="overviewDialog"/> +</div> + </h:body> </f:view> </html> diff --git a/web/src/main/webapp/resources/css/global.css b/web/src/main/webapp/resources/css/global.css index 64a70301ce..e66f255d45 100644 --- a/web/src/main/webapp/resources/css/global.css +++ b/web/src/main/webapp/resources/css/global.css @@ -1,3 +1,10 @@ +.canvasDebugClass { + border: 0; + position: absolute; + top: 0; + left: 0 +} + .menuBelt { width: 100%; min-height: 36px; diff --git a/web/src/main/webapp/resources/css/style.css b/web/src/main/webapp/resources/css/style.css index 432256d043..f58853b336 100644 --- a/web/src/main/webapp/resources/css/style.css +++ b/web/src/main/webapp/resources/css/style.css @@ -1113,9 +1113,6 @@ input[type=file] {width:280px !important; top:15px !important;} #content p span {font-weight:400} -.overviewContainerClass {width:100%; height:100%;} -.overviewDivClass {background-color: #ffffff;border:0; margin-left:10px; position: absolute; top:2; left:0} -.canvasDebugClass {border:0; position: absolute; top:2; left:0} .labelTextBold {font-size: 13px; font-weight: 900;} .labelText {font-size: 13px;} -- GitLab