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 0000000000000000000000000000000000000000..fe83a4a46fa505dd659cc1df17c50f9a3ef9fc50 --- /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 0000000000000000000000000000000000000000..20245945ebf58196dabe0024e24f1eaf32feb071 --- /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 4d0f5e111d5c536f048be81c4319e7687e964f37..370fcb409630cfddd6d59a3e8684c270717286d2 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 fda3320aa419b179b7e5703294a442810a0636c1..e91fee19c9ceb95dba3c39b26c279acea9b24bf4 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 2612e7d1b81119a1edcd6051a918e1291db986c1..a6b80995c12afff5f1335c6f027a29870814d807 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 322dee81b14a7b31aa6149c17cdc94b888e00027..1bbcea3e86a59ef41036e4311b042da1488163e4 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 6a16eb0a6a9b335fc2ac42eff82ef687f8d55e5a..262e7748ad7ce3b4bb343d6f93b2d2aeff71e170 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 f24f4a01e3d1f91d0646b5172bfa78baf32741dc..18c3b3e7d6f76d98f33db7051f668b2d46a205c8 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 1c463a5d8d36e36edf7177d0e2edf707943fcaad..5bdc7b08a3d5d5d5e277839a18f894288e0d94c8 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 0000000000000000000000000000000000000000..3168c9727582f1968750b425bbe063b1077b8047 --- /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 18d101d871f9cf42084b0d1b0c613e170a23d30b..9990242cb10609427081dad6ecef028612477c18 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 50bfabb18ba67cfedd9a2cb1fa7c25673a72c751..47e295e032e2d0e154ef858c10a1a3700cec9e1c 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 42060a7a44e36631fc111176f01d16e09d59e02c..e5e6a1243ee2774d82d8ccfa20820c8e183f48a1 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 43ee593d931527a3c5efed12d74747bbc05ddac5..8a3499805c2df0b38d0b61420a9012a84105024d 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 0000000000000000000000000000000000000000..b989ec48df62f47ce57be130dd7028861f6240a5 --- /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 60589e09f138629a4e943b1edf8a1f4e87a2e025..b3ecb4f6428892a2144431c6d4d6ae713c3989d4 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 6f8f5fcc44d609b57ba02c3b2932f8cd839734c4..090b6d0dc13c2a43c7005fc4a70001697d7d5272 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 0588b6d4cef169988978cde0c4d0baac0e58b7bf..27157aa2be15a0e8e93e71ae6a7a61583954955c 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 336cd7a914496ea050327c148503df5a27dc71f7..52f66532ff47c7eb78d7af1ad879fd29b8dc1954 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 befbc9585493716e716ed955aa67ed14c9cba576..0453ff0272fbe24a3bb6757ceb917126556ea02c 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 706e7db2f95a2b6fc05f53943f32494f3af11d00..0000000000000000000000000000000000000000 --- 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 f3ffe752fd34822f4d89bd2f9e69af0afc49304e..6155d0b7a0ea33727fcad7811839d282456e854d 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 Binary files /dev/null and b/rest-api/testFiles/model/complex_model_with_submaps.zip differ 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 40d88478e46a0246d242db6d34425eeaf56cfe4e..c602505e0cf3bd8e9284724bcfb8254e6ab13a9d 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 f7208909b305aaca2e3ced22a29043b906917b69..6e0199f6adeaab667694c5c091608918b200fa91 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 64a70301ce3be7e8aaf3a6a05f0fbfc2abe36329..e66f255d45a83f2c96f73b0c4a0e4338933014cf 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 432256d04398c5c354bca25a13df2d4abcdc03b0..f58853b33638d7efd4f516307f09213eff5c6232 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;}