mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-12 07:40:26 -08:00
new UI StackBox
This commit is contained in:
committed by
Matthieu Baumann
parent
116ba0d2e3
commit
63aebf738a
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## 3.3.3
|
## 3.3.3
|
||||||
|
|
||||||
|
* [feat] New `hipsList` option parameter when instancing a new Aladin object.
|
||||||
* [feat] Zoom smoothing using hermite cubic interpolation functions
|
* [feat] Zoom smoothing using hermite cubic interpolation functions
|
||||||
* [feat] shape option of Catalog and ProgressiveCat accepts a function returning a Footprint. This allow user to
|
* [feat] shape option of Catalog and ProgressiveCat accepts a function returning a Footprint. This allow user to
|
||||||
associate a footprint to a specific source
|
associate a footprint to a specific source
|
||||||
|
|||||||
5
assets/icons/add.svg
Normal file
5
assets/icons/add.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11 8C11 7.44772 11.4477 7 12 7C12.5523 7 13 7.44771 13 8V11H16C16.5523 11 17 11.4477 17 12C17 12.5523 16.5523 13 16 13H13V16C13 16.5523 12.5523 17 12 17C11.4477 17 11 16.5523 11 16V13H8C7.44772 13 7 12.5523 7 12C7 11.4477 7.44771 11 8 11H11V8Z" fill="#0F0F0F"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M23 4C23 2.34315 21.6569 1 20 1H4C2.34315 1 1 2.34315 1 4V20C1 21.6569 2.34315 23 4 23H20C21.6569 23 23 21.6569 23 20V4ZM21 4C21 3.44772 20.5523 3 20 3H4C3.44772 3 3 3.44772 3 4V20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20V4Z" fill="#0F0F0F"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 811 B |
@@ -10,26 +10,8 @@
|
|||||||
import A from '../src/js/A.js';
|
import A from '../src/js/A.js';
|
||||||
let aladin;
|
let aladin;
|
||||||
A.init.then(() => {
|
A.init.then(() => {
|
||||||
aladin = A.aladin('#aladin-lite-div', {target: '12 25 41.512 +12 48 47.2', fov: 1, showContextMenu: true});
|
aladin = A.aladin('#aladin-lite-div', {target: '12 25 41.512 +12 48 47.2', inertia: false, fov: 1, showContextMenu: true});
|
||||||
// define custom draw function
|
// define custom draw function
|
||||||
var drawFunction = function(source, canvasCtx, viewParams) {
|
|
||||||
canvasCtx.beginPath();
|
|
||||||
canvasCtx.arc(source.x, source.y, source.data['coo_err_min'] * 5, 0, 2 * Math.PI, false);
|
|
||||||
canvasCtx.closePath();
|
|
||||||
canvasCtx.strokeStyle = '#c38';
|
|
||||||
canvasCtx.lineWidth = 3;
|
|
||||||
canvasCtx.globalAlpha = 0.7,
|
|
||||||
canvasCtx.stroke();
|
|
||||||
var fov = Math.max(viewParams['fov'][0], viewParams['fov'][1]);
|
|
||||||
|
|
||||||
// object name is displayed only if fov<10°
|
|
||||||
if (fov>10) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvasCtx.globalAlpha = 0.9;
|
|
||||||
canvasCtx.globalAlpha = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
var drawFunctionFootprint = function(s) {
|
var drawFunctionFootprint = function(s) {
|
||||||
let a = +s.data.size_maj;
|
let a = +s.data.size_maj;
|
||||||
@@ -39,8 +21,8 @@
|
|||||||
if (!galaxy)
|
if (!galaxy)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let angle = +s.data.size_angle || 0.0;
|
let theta = +s.data.size_angle || 0.0;
|
||||||
return A.ellipse(s.ra, s.dec, a / 60, b / 60, angle, {color: 'cyan'});
|
return A.ellipse(s.ra, s.dec, a / 60, b / 60, theta, {color: 'cyan'});
|
||||||
};
|
};
|
||||||
|
|
||||||
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad', color: 'cyan', hoverColor: 'red', shape: drawFunctionFootprint});
|
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad', color: 'cyan', hoverColor: 'red', shape: drawFunctionFootprint});
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
|
|
||||||
A.init.then(() => {
|
A.init.then(() => {
|
||||||
var hipsDir="http://alasky.u-strasbg.fr/CDS_P_Coronelli";
|
var hipsDir="http://alasky.u-strasbg.fr/CDS_P_Coronelli";
|
||||||
aladin = A.aladin("#aladin-lite-div", {showSimbadPointerControl: true, realFullscreen: true, fov: 100, allowFullZoomout: true, showReticle: false });
|
aladin = A.aladin("#aladin-lite-div", {showSimbadPointerControl: true, expandLayersControl: true, realFullscreen: true, fov: 100, allowFullZoomout: true, showReticle: false });
|
||||||
aladin.createImageSurvey('illenoroC', 'illenoroC', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: false});
|
aladin.createImageSurvey('illenoroC', 'illenoroC', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: false});
|
||||||
aladin.createImageSurvey('Coronelli', 'Coronelli', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: true});
|
aladin.createImageSurvey('Coronelli', 'Coronelli', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: true});
|
||||||
aladin.setImageSurvey('Coronelli');
|
aladin.setImageSurvey('Coronelli');
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||||
})
|
})
|
||||||
|
|
||||||
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 100, {onClick: 'showTable', hoverColor: 'purple', limit: 1000});
|
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', hoverColor: 'purple', limit: 10000});
|
||||||
aladin.addCatalog(cat);
|
aladin.addCatalog(cat);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
32
examples/al-save-colormap.html
Normal file
32
examples/al-save-colormap.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--<link rel="stylesheet" href="./layers.css" />-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import A from '../src/js/A.js';
|
||||||
|
var aladin;
|
||||||
|
A.init.then(() => {
|
||||||
|
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, cooFrame: "ICRSd", showSimbadPointerControl: true, showShareControl: true, showShareControl: true, survey: 'https://alasky.cds.unistra.fr/DSS/DSSColor/', fov: 180, showContextMenu: true});
|
||||||
|
// manage URL parameters
|
||||||
|
let survey1 = aladin.getBaseImageLayer();
|
||||||
|
survey1.setColormap('magma', {stretch: 'linear'});
|
||||||
|
|
||||||
|
let survey2 = aladin.newImageSurvey("CSIRO/P/RACS/low/I");
|
||||||
|
aladin.setImageLayer(survey2)
|
||||||
|
survey2.setColormap('rdbu', {stretch: 'linear'});
|
||||||
|
|
||||||
|
let survey3 = aladin.newImageSurvey("CSIRO/P/RACS/mid/I");
|
||||||
|
aladin.setImageLayer(survey3)
|
||||||
|
survey3.setColormap('cubehelix', {stretch: 'asinh'});
|
||||||
|
|
||||||
|
aladin.setImageLayer(survey2);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -429,7 +429,7 @@ canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.aladin-input-text.aladin-dark-theme.search {
|
.aladin-input-text.aladin-dark-theme.search {
|
||||||
width: 14rem;
|
width: 15rem;
|
||||||
text-shadow: 0px 0px 2px #000;
|
text-shadow: 0px 0px 2px #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,6 +824,7 @@ canvas {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aladin-input-text.aladin-dark-theme, .aladin-input-number.aladin-dark-theme {
|
.aladin-input-text.aladin-dark-theme, .aladin-input-number.aladin-dark-theme {
|
||||||
@@ -853,18 +854,20 @@ canvas {
|
|||||||
/* Remove focus outline */
|
/* Remove focus outline */
|
||||||
/* Remove IE arrow */
|
/* Remove IE arrow */
|
||||||
}
|
}
|
||||||
|
|
||||||
.aladin-input-select option {
|
.aladin-input-select option {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
background-color: #320a28;
|
background-color: #320a28;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aladin-input-select:focus {
|
.aladin-input-select:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aladin-input-select::-ms-expand {
|
.aladin-input-select::-ms-expand {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Frames */
|
/* Frames */
|
||||||
.aladin-input-color {
|
.aladin-input-color {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
@@ -1104,6 +1107,19 @@ canvas {
|
|||||||
height: 1.7rem;
|
height: 1.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aladin-input-text.aladin-dark-theme.search.aladin-HiPS-search {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.aladin-stack-box {
|
||||||
|
width: 17rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aladin-stack-box .content > * {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.aladin-location {
|
.aladin-location {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.2rem;
|
top: 0.2rem;
|
||||||
@@ -1122,6 +1138,8 @@ canvas {
|
|||||||
bottom: 0.2rem;
|
bottom: 0.2rem;
|
||||||
left: 0.2rem;
|
left: 0.2rem;
|
||||||
|
|
||||||
|
background-color: red;
|
||||||
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -1129,6 +1147,16 @@ canvas {
|
|||||||
line-height: 1.7rem;
|
line-height: 1.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aladin-fov .aladin-zoom-in {
|
||||||
|
margin-right: 0;
|
||||||
|
border-right: none;
|
||||||
|
border-radius: 5px 0px 0px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aladin-fov .aladin-zoom-out {
|
||||||
|
border-radius: 0px 5px 5px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.aladin-status-bar {
|
.aladin-status-bar {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 0.4rem;
|
padding: 0.4rem;
|
||||||
|
|||||||
172
src/js/Aladin.js
172
src/js/Aladin.js
@@ -40,6 +40,7 @@ import { MeasurementTable } from "./MeasurementTable.js";
|
|||||||
import { ImageSurvey } from "./ImageSurvey.js";
|
import { ImageSurvey } from "./ImageSurvey.js";
|
||||||
import { Coo } from "./libs/astro/coo.js";
|
import { Coo } from "./libs/astro/coo.js";
|
||||||
import { CooConversion } from "./CooConversion.js";
|
import { CooConversion } from "./CooConversion.js";
|
||||||
|
import { MocServer } from './MocServer';
|
||||||
|
|
||||||
import { ProjectionEnum } from "./ProjectionEnum.js";
|
import { ProjectionEnum } from "./ProjectionEnum.js";
|
||||||
|
|
||||||
@@ -77,6 +78,10 @@ import { CooFrame } from './gui/Input/CooFrame';
|
|||||||
* @property {string} [survey="CDS/P/DSS2/color"] URL or ID of the survey to use
|
* @property {string} [survey="CDS/P/DSS2/color"] URL or ID of the survey to use
|
||||||
* @property {string[]} [surveyUrl]
|
* @property {string[]} [surveyUrl]
|
||||||
* Array of URLs for the survey images. This replaces the survey parameter.
|
* Array of URLs for the survey images. This replaces the survey parameter.
|
||||||
|
* @property {Object[]|string[]} [hipsList] A list of predefined HiPS for the Aladin instance.
|
||||||
|
* This option is used for searching for a HiPS in a list of surveys
|
||||||
|
* This list can have string item (either a CDS ID or an HiPS url) or an object that describes the HiPS
|
||||||
|
* more exhaustively. See the example below to see the different form that this item can have to describe a HiPS.
|
||||||
* @property {string} [target="0 +0"] - Target coordinates for the initial view.
|
* @property {string} [target="0 +0"] - Target coordinates for the initial view.
|
||||||
* @property {CooFrame} [cooFrame="J2000"] - Coordinate frame.
|
* @property {CooFrame} [cooFrame="J2000"] - Coordinate frame.
|
||||||
* @property {number} [fov=60] - Field of view in degrees.
|
* @property {number} [fov=60] - Field of view in degrees.
|
||||||
@@ -86,6 +91,8 @@ import { CooFrame } from './gui/Input/CooFrame';
|
|||||||
* This element belongs to the FoV UI thus its CSS class is `aladin-fov`
|
* This element belongs to the FoV UI thus its CSS class is `aladin-fov`
|
||||||
* @property {boolean} [showLayersControl=true] - Whether to show the layers control toolbar.
|
* @property {boolean} [showLayersControl=true] - Whether to show the layers control toolbar.
|
||||||
* CSS class for that button is `aladin-stack-control`
|
* CSS class for that button is `aladin-stack-control`
|
||||||
|
* @property {boolean} [expandLayersControl=false] - Whether to show the stack box at starting
|
||||||
|
* CSS class for the stack box is `aladin-stack-box`
|
||||||
* @property {boolean} [showFullscreenControl=true] - Whether to show the fullscreen control toolbar.
|
* @property {boolean} [showFullscreenControl=true] - Whether to show the fullscreen control toolbar.
|
||||||
* CSS class for that button is `aladin-fullScreen-control`
|
* CSS class for that button is `aladin-fullScreen-control`
|
||||||
* @property {boolean} [showSimbadPointerControl=false] - Whether to show the Simbad pointer control toolbar.
|
* @property {boolean} [showSimbadPointerControl=false] - Whether to show the Simbad pointer control toolbar.
|
||||||
@@ -133,7 +140,53 @@ import { CooFrame } from './gui/Input/CooFrame';
|
|||||||
* @property {boolean} [samp=false] - Whether to enable SAMP (Simple Application Messaging Protocol).
|
* @property {boolean} [samp=false] - Whether to enable SAMP (Simple Application Messaging Protocol).
|
||||||
* @property {boolean} [realFullscreen=false] - Whether to use real fullscreen mode.
|
* @property {boolean} [realFullscreen=false] - Whether to use real fullscreen mode.
|
||||||
* @property {boolean} [pixelateCanvas=true] - Whether to pixelate the canvas.
|
* @property {boolean} [pixelateCanvas=true] - Whether to pixelate the canvas.
|
||||||
*/
|
* @example
|
||||||
|
* let aladin = A.aladin({
|
||||||
|
target: 'galactic center',
|
||||||
|
fov: 10,
|
||||||
|
hipsList: [
|
||||||
|
// url
|
||||||
|
"https://alaskybis.unistra.fr/DSS/DSSColor",
|
||||||
|
// ID from HiPS list
|
||||||
|
"CDS/P/2MASS/color",
|
||||||
|
// Not full HiPS described
|
||||||
|
{
|
||||||
|
name: 'DESI Legacy Surveys color (g, r, i, z)',
|
||||||
|
id: 'CDS/P/DESI-Legacy-Surveys/DR10/color',
|
||||||
|
},
|
||||||
|
// Fully described HiPS
|
||||||
|
{
|
||||||
|
name: "DECaPS DR2 color",
|
||||||
|
url: "https://alasky.cds.unistra.fr/DECaPS/DR2/CDS_P_DECaPS_DR2_color/",
|
||||||
|
properties: {
|
||||||
|
creatorDid: "ivo://CDS/P/DECaPS/DR2/color",
|
||||||
|
maxOrder: 11,
|
||||||
|
cooFrame: "equatorial",
|
||||||
|
tileSize: 512,
|
||||||
|
imgFormat: 'png',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// HiPS with options
|
||||||
|
{
|
||||||
|
name: "SDSS9 band-g",
|
||||||
|
id: "P/SDSS9/g",
|
||||||
|
properties: {
|
||||||
|
creatorDid: "ivo://CDS/P/SDSS9/g",
|
||||||
|
maxOrder: 10,
|
||||||
|
tileSize: 512,
|
||||||
|
numBitsPerPixel: 16,
|
||||||
|
imgFormat: 'fits',
|
||||||
|
cooFrame: 'equatorial',
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
minCut: 0,
|
||||||
|
maxCut: 1.8,
|
||||||
|
stretch: 'linear',
|
||||||
|
colormap: "redtemperature",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} CircleSelection
|
* @typedef {Object} CircleSelection
|
||||||
@@ -335,6 +388,84 @@ export let Aladin = (function () {
|
|||||||
this.setBaseImageLayer(url);
|
this.setBaseImageLayer(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hipsList = [].concat(options.hipsList);
|
||||||
|
|
||||||
|
const fillHiPSCache = () => {
|
||||||
|
for (var survey of hipsList) {
|
||||||
|
let id, url, name;
|
||||||
|
let cachedSurvey = {};
|
||||||
|
|
||||||
|
if (typeof survey === "string") {
|
||||||
|
try {
|
||||||
|
url = new URL(survey).href;
|
||||||
|
} catch(e) {
|
||||||
|
id = survey;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = url || id;
|
||||||
|
} else if (survey instanceof Object) {
|
||||||
|
if (survey.id) {
|
||||||
|
id = survey.id;
|
||||||
|
}
|
||||||
|
if (survey.url) {
|
||||||
|
url = survey.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = survey.name || survey.id || survey.url;
|
||||||
|
|
||||||
|
if (id && url) {
|
||||||
|
console.warn('Both "CDS ID" and url are given for ', survey, '. ID is chosen.')
|
||||||
|
url = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (survey.properties) {
|
||||||
|
cachedSurvey = {...cachedSurvey, ...survey.properties}
|
||||||
|
}
|
||||||
|
if (survey.options) {
|
||||||
|
cachedSurvey = {...cachedSurvey, ...survey.options}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('unable to parse the survey list item: ', survey)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
cachedSurvey['id'] = id;
|
||||||
|
}
|
||||||
|
if (url) {
|
||||||
|
cachedSurvey['url'] = url;
|
||||||
|
}
|
||||||
|
if (name) {
|
||||||
|
cachedSurvey['name'] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// at least id or url is defined
|
||||||
|
let key = id || url;
|
||||||
|
|
||||||
|
if (!(key in ImageSurvey.cache)) {
|
||||||
|
ImageSurvey.cache[key] = cachedSurvey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALEvent.HIPS_LIST_UPDATED.dispatchedTo(this.aladinDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hipsList.length === 0) {
|
||||||
|
MocServer.getAllHiPSes()
|
||||||
|
.then((HiPSes) => {
|
||||||
|
HiPSes.forEach((h) => {
|
||||||
|
hipsList.push({
|
||||||
|
id: h.ID,
|
||||||
|
name: h.obs_title
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
fillHiPSCache();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fillHiPSCache();
|
||||||
|
}
|
||||||
|
|
||||||
this.view.showCatalog(options.showCatalog);
|
this.view.showCatalog(options.showCatalog);
|
||||||
|
|
||||||
// FullScreen toolbar icon
|
// FullScreen toolbar icon
|
||||||
@@ -412,6 +543,7 @@ export let Aladin = (function () {
|
|||||||
if (!options.showLayersControl) {
|
if (!options.showLayersControl) {
|
||||||
stack._hide();
|
stack._hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the simbad pointer control
|
// Add the simbad pointer control
|
||||||
if (!options.showSimbadPointerControl) {
|
if (!options.showSimbadPointerControl) {
|
||||||
simbad._hide();
|
simbad._hide();
|
||||||
@@ -443,6 +575,10 @@ export let Aladin = (function () {
|
|||||||
this.addUI(new FullScreenActionButton(self))
|
this.addUI(new FullScreenActionButton(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.expandLayersControl) {
|
||||||
|
stack.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
this._applyMediaQueriesUI();
|
this._applyMediaQueriesUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,6 +630,8 @@ export let Aladin = (function () {
|
|||||||
Aladin.wasmLibs = {};
|
Aladin.wasmLibs = {};
|
||||||
Aladin.DEFAULT_OPTIONS = {
|
Aladin.DEFAULT_OPTIONS = {
|
||||||
survey: ImageSurvey.DEFAULT_SURVEY_ID,
|
survey: ImageSurvey.DEFAULT_SURVEY_ID,
|
||||||
|
// surveys suggestion list
|
||||||
|
hipsList: [],
|
||||||
//surveyUrl: ["https://alaskybis.unistra.fr/DSS/DSSColor", "https://alasky.unistra.fr/DSS/DSSColor"],
|
//surveyUrl: ["https://alaskybis.unistra.fr/DSS/DSSColor", "https://alasky.unistra.fr/DSS/DSSColor"],
|
||||||
target: "0 +0",
|
target: "0 +0",
|
||||||
cooFrame: "J2000",
|
cooFrame: "J2000",
|
||||||
@@ -504,6 +642,7 @@ export let Aladin = (function () {
|
|||||||
showZoomControl: false,
|
showZoomControl: false,
|
||||||
// Menu toolbar
|
// Menu toolbar
|
||||||
showLayersControl: true,
|
showLayersControl: true,
|
||||||
|
expandLayersControl: false,
|
||||||
showFullscreenControl: true,
|
showFullscreenControl: true,
|
||||||
showSimbadPointerControl: false,
|
showSimbadPointerControl: false,
|
||||||
showCooGridControl: false,
|
showCooGridControl: false,
|
||||||
@@ -539,7 +678,7 @@ export let Aladin = (function () {
|
|||||||
log: true,
|
log: true,
|
||||||
samp: false,
|
samp: false,
|
||||||
realFullscreen: false,
|
realFullscreen: false,
|
||||||
pixelateCanvas: true
|
pixelateCanvas: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
// realFullscreen: AL div expands not only to the size of its parent, but takes the whole available screen estate
|
// realFullscreen: AL div expands not only to the size of its parent, but takes the whole available screen estate
|
||||||
@@ -851,10 +990,11 @@ export let Aladin = (function () {
|
|||||||
// try to parse as a position
|
// try to parse as a position
|
||||||
if (!isObjectName) {
|
if (!isObjectName) {
|
||||||
var coo = new Coo();
|
var coo = new Coo();
|
||||||
|
|
||||||
coo.parse(targetName);
|
coo.parse(targetName);
|
||||||
// Convert from view coo sys to icrs
|
// Convert from view coo sys to icrs
|
||||||
|
|
||||||
const [ra, dec] = this.wasm.viewToICRSCooSys(coo.lon, coo.lat);
|
const [ra, dec] = this.wasm.viewToICRSCooSys(coo.lon, coo.lat);
|
||||||
|
|
||||||
this.view.pointTo(ra, dec);
|
this.view.pointTo(ra, dec);
|
||||||
|
|
||||||
(typeof successCallback === 'function') && successCallback(this.getRaDec());
|
(typeof successCallback === 'function') && successCallback(this.getRaDec());
|
||||||
@@ -914,14 +1054,14 @@ export let Aladin = (function () {
|
|||||||
* @memberof Aladin
|
* @memberof Aladin
|
||||||
* @param {number} lon - longitude in degrees
|
* @param {number} lon - longitude in degrees
|
||||||
* @param {number} lat - latitude in degrees
|
* @param {number} lat - latitude in degrees
|
||||||
* @param {string} frame - Optional callback options.
|
* @param {string} [frame] - The name of the coordinate frame. Possible values: 'j2000d', 'j2000', 'gal', 'icrs'. The given string is case insensitive.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // Move to position
|
* // Move to position
|
||||||
* const aladin = A.aladin('#aladin-lite-div');
|
* const aladin = A.aladin('#aladin-lite-div');
|
||||||
* aladin.gotoPosition(20, 10, "galactic");
|
* aladin.gotoPosition(20, 10, "galactic");
|
||||||
*/
|
*/
|
||||||
Aladin.prototype.gotoPosition = function (lon, lat, frame = undefined) {
|
Aladin.prototype.gotoPosition = function (lon, lat, frame) {
|
||||||
var radec;
|
var radec;
|
||||||
// convert the frame from string to CooFrameEnum
|
// convert the frame from string to CooFrameEnum
|
||||||
if (frame) {
|
if (frame) {
|
||||||
@@ -936,7 +1076,7 @@ export let Aladin = (function () {
|
|||||||
radec = [lon, lat];
|
radec = [lon, lat];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.view.pointTo(radec[0], radec[1]);
|
this.gotoRaDec(radec[0], radec[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
var idTimeoutAnim;
|
var idTimeoutAnim;
|
||||||
@@ -1140,9 +1280,15 @@ export let Aladin = (function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* point to a given position, expressed as a ra,dec coordinate
|
* Moves the Aladin instance to the specified position given in ICRS frame
|
||||||
*
|
*
|
||||||
* @API
|
* @memberof Aladin
|
||||||
|
* @param {number} ra - Right-ascension in degrees
|
||||||
|
* @param {number} dec - Declination in degrees
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const aladin = A.aladin('#aladin-lite-div');
|
||||||
|
* aladin.gotoRaDec(20, 10);
|
||||||
*/
|
*/
|
||||||
Aladin.prototype.gotoRaDec = function (ra, dec) {
|
Aladin.prototype.gotoRaDec = function (ra, dec) {
|
||||||
this.view.pointTo(ra, dec);
|
this.view.pointTo(ra, dec);
|
||||||
@@ -1239,7 +1385,15 @@ export let Aladin = (function () {
|
|||||||
let surveyOptions = ImageSurvey.cache[id];
|
let surveyOptions = ImageSurvey.cache[id];
|
||||||
|
|
||||||
if (!surveyOptions) {
|
if (!surveyOptions) {
|
||||||
surveyOptions = {url, name, maxOrder, cooFrame, ...options};
|
surveyOptions = {name, maxOrder, cooFrame, ...options};
|
||||||
|
|
||||||
|
// differenciate url from CDS Id in the url param given
|
||||||
|
if (!Utils.isUrl(url)) {
|
||||||
|
surveyOptions.id = url;
|
||||||
|
} else {
|
||||||
|
surveyOptions.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
ImageSurvey.cache[id] = surveyOptions;
|
ImageSurvey.cache[id] = surveyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,14 +214,15 @@ HiPSProperties.getFasterMirrorUrl = function (metadata, currUrl) {
|
|||||||
newUrlResp = validResponses[0];
|
newUrlResp = validResponses[0];
|
||||||
} else {
|
} else {
|
||||||
// no valid response => we return an error
|
// no valid response => we return an error
|
||||||
return Promise.reject('Survey not found. All mirrors urls have been tested:' + urls)
|
return Promise.reject('All mirrors urls have been tested:' + urls)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there is a big difference from the current one
|
// check if there is a big difference from the current one
|
||||||
let currUrlResp = validResponses.find((r) => r.baseUrl === currUrl)
|
let currUrlResp = validResponses.find((r) => r.baseUrl === currUrl)
|
||||||
|
// it may happen that the url requested by the user is too slow hence discarded
|
||||||
|
// for these cases, we automatically switch to the new fastest url.
|
||||||
let urlChosen;
|
let urlChosen;
|
||||||
if (Math.abs(currUrlResp.duration - newUrlResp.duration) / Math.min(currUrlResp.duration, newUrlResp.duration) < 0.10) {
|
if (currUrlResp && Math.abs(currUrlResp.duration - newUrlResp.duration) / Math.min(currUrlResp.duration, newUrlResp.duration) < 0.10) {
|
||||||
// there is not enough difference => do not switch
|
// there is not enough difference => do not switch
|
||||||
urlChosen = currUrlResp.baseUrl;
|
urlChosen = currUrlResp.baseUrl;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -144,8 +144,7 @@ export let ImageSurvey = (function () {
|
|||||||
* @class
|
* @class
|
||||||
* @constructs ImageSurvey
|
* @constructs ImageSurvey
|
||||||
*
|
*
|
||||||
* @param {string} id - Mandatory unique identifier for the layer.
|
* @param {string} id - Mandatory unique identifier for the layer. Can be an arbitrary name
|
||||||
* Can be an arbitrary name
|
|
||||||
* @param {string} url - Can be an url to the survey or a "CDS" ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}
|
* @param {string} url - Can be an url to the survey or a "CDS" ID pointing towards a HiPS. One can found the list of IDs {@link https://aladin.cds.unistra.fr/hips/list| here}
|
||||||
* @param {ImageSurveyOptions} [options] - The option for the survey
|
* @param {ImageSurveyOptions} [options] - The option for the survey
|
||||||
*
|
*
|
||||||
@@ -193,32 +192,29 @@ export let ImageSurvey = (function () {
|
|||||||
|
|
||||||
self.query = (async () => {
|
self.query = (async () => {
|
||||||
if (isMOCServerToBeQueried) {
|
if (isMOCServerToBeQueried) {
|
||||||
let properties;
|
|
||||||
let isCDSId = false;
|
let isCDSId = false;
|
||||||
try {
|
|
||||||
properties = await HiPSProperties.fetchFromUrl(self.url)
|
|
||||||
/*.catch((e) => {
|
|
||||||
// try with the proxy
|
|
||||||
url = Utils.handleCORSNotSameOrigin(url).href;
|
|
||||||
|
|
||||||
return HiPSProperties.fetchFromUrl(url);
|
let properties = await HiPSProperties.fetchFromUrl(self.url)
|
||||||
})*/
|
/*.catch((e) => {
|
||||||
.catch(async (e) => {
|
// try with the proxy
|
||||||
// url not valid so we try with the id
|
url = Utils.handleCORSNotSameOrigin(url).href;
|
||||||
try {
|
|
||||||
isCDSId = true;
|
return HiPSProperties.fetchFromUrl(url);
|
||||||
// the url stores a "CDS ID" we take it prioritaly
|
})*/
|
||||||
// if the url is null, take the id, this is for some tests
|
.catch(async (e) => {
|
||||||
// to pass because some users might just give null as url param and a "CDS ID" as id param
|
// url not valid so we try with the id
|
||||||
let id = self.url || self.id;
|
try {
|
||||||
return await HiPSProperties.fetchFromID(id);
|
isCDSId = true;
|
||||||
} catch(e) {
|
// the url stores a "CDS ID" we take it prioritaly
|
||||||
throw e;
|
// if the url is null, take the id, this is for some tests
|
||||||
}
|
// to pass because some users might just give null as url param and a "CDS ID" as id param
|
||||||
})
|
let id = self.url || self.id;
|
||||||
} catch(e) {
|
return await HiPSProperties.fetchFromID(id);
|
||||||
throw e;
|
} catch(e) {
|
||||||
}
|
throw e;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
//obsTitle = properties.obs_title;
|
//obsTitle = properties.obs_title;
|
||||||
self.creatorDid = properties.creator_did || self.creatorDid;
|
self.creatorDid = properties.creator_did || self.creatorDid;
|
||||||
@@ -238,24 +234,25 @@ export let ImageSurvey = (function () {
|
|||||||
if (self.url !== url) {
|
if (self.url !== url) {
|
||||||
console.info("Change url of ", self.id, " from ", self.url, " to ", url)
|
console.info("Change url of ", self.id, " from ", self.url, " to ", url)
|
||||||
|
|
||||||
|
self.url = url;
|
||||||
|
|
||||||
|
// save the new url to the cache
|
||||||
|
self._saveInCache();
|
||||||
|
|
||||||
// If added to the backend, then we need to tell it the url has changed
|
// If added to the backend, then we need to tell it the url has changed
|
||||||
if (self.added) {
|
if (self.added) {
|
||||||
self.view.wasm.setHiPSUrl(self.creatorDid, url);
|
self.view.wasm.setHiPSUrl(self.creatorDid, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.url = url;
|
|
||||||
|
|
||||||
// save the new url to the cache
|
|
||||||
ImageSurvey.cache[self.id].url = self.url;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
/*.catch(e => {
|
.catch(e => {
|
||||||
//alert(e);
|
//alert(e);
|
||||||
|
console.error(self)
|
||||||
console.error(e);
|
console.error(e);
|
||||||
// the survey has been added so we remove it from the stack
|
// the survey has been added so we remove it from the stack
|
||||||
self.view.removeImageLayer(self.layer)
|
//self.view.removeImageLayer(self.layer)
|
||||||
//throw e;
|
//throw e;
|
||||||
})*/
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Max order
|
// Max order
|
||||||
@@ -402,7 +399,13 @@ export let ImageSurvey = (function () {
|
|||||||
// append new important infos from the properties queried
|
// append new important infos from the properties queried
|
||||||
...surveyOpt,
|
...surveyOpt,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//console.log('new CACHE', ImageSurvey.cache, self.id, surveyOpt, ImageSurvey.cache[self.id], ImageSurvey.cache["CSIRO/P/RACS/mid/I"])
|
||||||
|
|
||||||
|
// Tell that the HiPS List has been updated
|
||||||
|
ALEvent.HIPS_LIST_UPDATED.dispatchedTo(this.view.aladin.aladinDiv);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the ImageSurvey represents a planetary body.
|
* Checks if the ImageSurvey represents a planetary body.
|
||||||
@@ -704,7 +707,7 @@ export let ImageSurvey = (function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.added = true;
|
//this.added = true;
|
||||||
|
|
||||||
return Promise.resolve(this);
|
return Promise.resolve(this);
|
||||||
}
|
}
|
||||||
@@ -748,7 +751,7 @@ export let ImageSurvey = (function () {
|
|||||||
|
|
||||||
// A cache storing directly surveys important information to not query for the properties each time
|
// A cache storing directly surveys important information to not query for the properties each time
|
||||||
ImageSurvey.cache = {
|
ImageSurvey.cache = {
|
||||||
DSS2_color: {
|
/*DSS2_color: {
|
||||||
creatorDid: "ivo://CDS/P/DSS2/color",
|
creatorDid: "ivo://CDS/P/DSS2/color",
|
||||||
name: "DSS colored",
|
name: "DSS colored",
|
||||||
url: "https://alasky.cds.unistra.fr/DSS/DSSColor",
|
url: "https://alasky.cds.unistra.fr/DSS/DSSColor",
|
||||||
@@ -913,6 +916,7 @@ export let ImageSurvey = (function () {
|
|||||||
stretch: 'linear',
|
stretch: 'linear',
|
||||||
colormap: "redtemperature",
|
colormap: "redtemperature",
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
id: "P/Finkbeiner",
|
id: "P/Finkbeiner",
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export let MOC = (function() {
|
|||||||
* set MOC data by parsing a MOC serialized in JSON
|
* set MOC data by parsing a MOC serialized in JSON
|
||||||
* (as defined in IVOA MOC document, section 3.1.1)
|
* (as defined in IVOA MOC document, section 3.1.1)
|
||||||
*/
|
*/
|
||||||
MOC.prototype.parse = function(data, successCallback) {
|
MOC.prototype.parse = function(data, successCallback, errorCallback) {
|
||||||
if (typeof data === 'string' || data instanceof String) {
|
if (typeof data === 'string' || data instanceof String) {
|
||||||
let url = data;
|
let url = data;
|
||||||
this.promiseFetchData = fetch(url)
|
this.promiseFetchData = fetch(url)
|
||||||
@@ -120,7 +120,7 @@ export let MOC = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.successCallback = successCallback;
|
this.successCallback = successCallback;
|
||||||
this.errorCallback = this.errorCallback;
|
this.errorCallback = errorCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
MOC.prototype.setView = function(view) {
|
MOC.prototype.setView = function(view) {
|
||||||
@@ -166,7 +166,11 @@ export let MOC = (function() {
|
|||||||
|
|
||||||
self.view.requestRedraw();
|
self.view.requestRedraw();
|
||||||
})
|
})
|
||||||
.catch(e => alert('MOC load error:' + e))
|
.catch(e => {
|
||||||
|
console.error('MOC load error:' + e)
|
||||||
|
if (self.errorCallback)
|
||||||
|
self.errorCallback(self);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
MOC.prototype.reportChange = function() {
|
MOC.prototype.reportChange = function() {
|
||||||
|
|||||||
@@ -469,6 +469,14 @@ Utils.fixURLForHTTPS = function (url) {
|
|||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils.isUrl = function(url) {
|
||||||
|
try {
|
||||||
|
return new URL(url).href;
|
||||||
|
} catch(e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate an absolute URL from a relative URL
|
// generate an absolute URL from a relative URL
|
||||||
// example: getAbsoluteURL('foo/bar/toto') return http://cds.unistra.fr/AL/foo/bar/toto if executed from page http://cds.unistra.fr/AL/
|
// example: getAbsoluteURL('foo/bar/toto') return http://cds.unistra.fr/AL/foo/bar/toto if executed from page http://cds.unistra.fr/AL/
|
||||||
Utils.getAbsoluteURL = function (url) {
|
Utils.getAbsoluteURL = function (url) {
|
||||||
|
|||||||
@@ -488,8 +488,10 @@ export let View = (function () {
|
|||||||
|
|
||||||
View.prototype.selectLayer = function (layer) {
|
View.prototype.selectLayer = function (layer) {
|
||||||
if (!this.imageLayers.has(layer)) {
|
if (!this.imageLayers.has(layer)) {
|
||||||
throw layer + ' does not exists. So cannot be selected';
|
console.warn(layer + ' does not exists. So cannot be selected');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectedLayer = layer;
|
this.selectedLayer = layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1167,7 +1169,7 @@ export let View = (function () {
|
|||||||
}
|
}
|
||||||
//requestAnimFrame(moveTo)
|
//requestAnimFrame(moveTo)
|
||||||
}*/
|
}*/
|
||||||
}, 30);
|
}, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
view.throttledTouchPadZoom();
|
view.throttledTouchPadZoom();
|
||||||
@@ -1578,10 +1580,20 @@ export let View = (function () {
|
|||||||
if (idxOverlayLayer == -1) {
|
if (idxOverlayLayer == -1) {
|
||||||
// it does not exist so we add it to the stack
|
// it does not exist so we add it to the stack
|
||||||
this.overlayLayers.push(layerName);
|
this.overlayLayers.push(layerName);
|
||||||
|
} else {
|
||||||
|
// it exists
|
||||||
|
let alreadyPresentImageLayer = this.imageLayers.get(layerName);
|
||||||
|
alreadyPresentImageLayer.added = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageLayer.added = true;
|
||||||
this.imageLayers.set(layerName, imageLayer);
|
this.imageLayers.set(layerName, imageLayer);
|
||||||
|
|
||||||
|
// select the layer if he is on top
|
||||||
|
if (idxOverlayLayer == -1) {
|
||||||
|
this.selectLayer(layerName);
|
||||||
|
}
|
||||||
|
|
||||||
ALEvent.HIPS_LAYER_ADDED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
ALEvent.HIPS_LAYER_ADDED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1678,11 +1690,6 @@ export let View = (function () {
|
|||||||
this.imageLayers.delete(layer);
|
this.imageLayers.delete(layer);
|
||||||
this.imageLayers.set(newLayer, imageLayer);
|
this.imageLayers.set(newLayer, imageLayer);
|
||||||
|
|
||||||
// Change the selected layer if this is the one renamed
|
|
||||||
/*if (this.selectedLayer === layer) {
|
|
||||||
this.selectedLayer = newLayer;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Tell the layer hierarchy has changed
|
// Tell the layer hierarchy has changed
|
||||||
ALEvent.HIPS_LAYER_RENAMED.dispatchedTo(this.aladinDiv, { layer, newLayer });
|
ALEvent.HIPS_LAYER_RENAMED.dispatchedTo(this.aladinDiv, { layer, newLayer });
|
||||||
}
|
}
|
||||||
@@ -1734,7 +1741,7 @@ export let View = (function () {
|
|||||||
this.empty = true;
|
this.empty = true;
|
||||||
} else if (this.selectedLayer === layer) {
|
} else if (this.selectedLayer === layer) {
|
||||||
// If the layer removed was selected then we select the base layer
|
// If the layer removed was selected then we select the base layer
|
||||||
this.selectedLayer = 'base';
|
this.selectLayer(this.overlayLayers[this.overlayLayers.length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALEvent.HIPS_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer });
|
ALEvent.HIPS_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer });
|
||||||
@@ -1857,11 +1864,11 @@ export let View = (function () {
|
|||||||
ra = parseFloat(ra);
|
ra = parseFloat(ra);
|
||||||
dec = parseFloat(dec);
|
dec = parseFloat(dec);
|
||||||
|
|
||||||
if (isNaN(ra) || isNaN(dec)) {
|
if (!ra || !dec) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.viewCenter.lon = ra;
|
this.viewCenter.lon = ra;
|
||||||
this.viewCenter.lat = dec;
|
this.viewCenter.lat = dec;
|
||||||
//this.updateLocation({lon: this.viewCenter.lon, lat: this.viewCenter.lat});
|
//this.updateLocation({lon: this.viewCenter.lon, lat: this.viewCenter.lat});
|
||||||
|
|
||||||
// Put a javascript code here to do some animation
|
// Put a javascript code here to do some animation
|
||||||
@@ -1905,7 +1912,13 @@ export let View = (function () {
|
|||||||
this.catalogs = [];
|
this.catalogs = [];
|
||||||
this.overlays = [];
|
this.overlays = [];
|
||||||
this.mocs = [];
|
this.mocs = [];
|
||||||
|
|
||||||
|
this.allOverlayLayers.forEach((overlay) => {
|
||||||
|
ALEvent.GRAPHIC_OVERLAY_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: overlay });
|
||||||
|
})
|
||||||
this.allOverlayLayers = [];
|
this.allOverlayLayers = [];
|
||||||
|
|
||||||
|
this.mustClearCatalog = true;
|
||||||
this.requestRedraw();
|
this.requestRedraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1929,7 +1942,7 @@ export let View = (function () {
|
|||||||
this.overlays.splice(indexToDelete, 1);
|
this.overlays.splice(indexToDelete, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALEvent.GRAPHIC_OVERLAY_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: layer });
|
ALEvent.GRAPHIC_OVERLAY_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer });
|
||||||
|
|
||||||
this.mustClearCatalog = true;
|
this.mustClearCatalog = true;
|
||||||
this.requestRedraw();
|
this.requestRedraw();
|
||||||
@@ -2000,7 +2013,7 @@ export let View = (function () {
|
|||||||
let closest = null;
|
let closest = null;
|
||||||
|
|
||||||
footprints.forEach((footprint) => {
|
footprints.forEach((footprint) => {
|
||||||
if (!footprint.source.tooSmallFootprint) {
|
if (!footprint.source || !footprint.source.tooSmallFootprint) {
|
||||||
// Hidden footprints are not considered
|
// Hidden footprints are not considered
|
||||||
let lineWidth = footprint.getLineWidth();
|
let lineWidth = footprint.getLineWidth();
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export class ALEvent {
|
|||||||
static HIPS_LAYER_RENAMED = new ALEvent("AL:HiPSLayer.renamed");
|
static HIPS_LAYER_RENAMED = new ALEvent("AL:HiPSLayer.renamed");
|
||||||
static HIPS_LAYER_SWAP = new ALEvent("AL:HiPSLayer.swap");
|
static HIPS_LAYER_SWAP = new ALEvent("AL:HiPSLayer.swap");
|
||||||
|
|
||||||
|
static HIPS_LIST_UPDATED = new ALEvent("AL:HiPSList.updated");
|
||||||
|
|
||||||
static HIPS_LAYER_CHANGED = new ALEvent("AL:HiPSLayer.changed");
|
static HIPS_LAYER_CHANGED = new ALEvent("AL:HiPSLayer.changed");
|
||||||
|
|
||||||
static GRAPHIC_OVERLAY_LAYER_ADDED = new ALEvent("AL:GraphicOverlayLayer.added");
|
static GRAPHIC_OVERLAY_LAYER_ADDED = new ALEvent("AL:GraphicOverlayLayer.added");
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
|||||||
}, aladin)
|
}, aladin)
|
||||||
|
|
||||||
super({
|
super({
|
||||||
|
close: false,
|
||||||
content: Layout.horizontal({
|
content: Layout.horizontal({
|
||||||
layout: [inputText, loadBtn]
|
layout: [inputText, loadBtn]
|
||||||
}),
|
}),
|
||||||
@@ -238,10 +239,10 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
|||||||
this.loadBtn.update({disable: true}, aladin)
|
this.loadBtn.update({disable: true}, aladin)
|
||||||
} else {
|
} else {
|
||||||
let self = this;
|
let self = this;
|
||||||
let layout = [];
|
let ctxMenu = [];
|
||||||
|
|
||||||
if (item && item.cs_service_url) {
|
if (item && item.cs_service_url) {
|
||||||
layout.push({
|
ctxMenu.push({
|
||||||
label: 'Cone search',
|
label: 'Cone search',
|
||||||
disable: !item.cs_service_url,
|
disable: !item.cs_service_url,
|
||||||
action(o) {
|
action(o) {
|
||||||
@@ -263,6 +264,8 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
|||||||
})
|
})
|
||||||
|
|
||||||
self._hide();
|
self._hide();
|
||||||
|
|
||||||
|
self.callback && self.callback();
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
anchor: 'center center',
|
anchor: 'center center',
|
||||||
@@ -270,13 +273,12 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
|||||||
})
|
})
|
||||||
self.box._show();
|
self.box._show();
|
||||||
self.loadBtn.hideMenu()
|
self.loadBtn.hideMenu()
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item && item.hips_service_url) {
|
if (item && item.hips_service_url) {
|
||||||
layout.push({
|
ctxMenu.push({
|
||||||
label: 'HiPS catalogue',
|
label: 'HiPS catalogue',
|
||||||
disable: !item.hips_service_url,
|
disable: !item.hips_service_url,
|
||||||
action(o) {
|
action(o) {
|
||||||
@@ -286,15 +288,22 @@ import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
|||||||
})
|
})
|
||||||
|
|
||||||
self._hide();
|
self._hide();
|
||||||
|
|
||||||
|
self.callback && self.callback();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.loadBtn.update({ctxMenu: layout, disable: false}, aladin)
|
this.loadBtn.update({ctxMenu, disable: false}, aladin)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadBtn.hideMenu()
|
this.loadBtn.hideMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attach(options) {
|
||||||
|
this.callback = options.callback;
|
||||||
|
super.update(options)
|
||||||
|
}
|
||||||
|
|
||||||
_hide() {
|
_hide() {
|
||||||
if (this.box) {
|
if (this.box) {
|
||||||
this.box.remove();
|
this.box.remove();
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ import { Input } from "../Widgets/Input.js";
|
|||||||
|
|
||||||
super(
|
super(
|
||||||
{
|
{
|
||||||
|
close: false,
|
||||||
content: Layout.horizontal({
|
content: Layout.horizontal({
|
||||||
layout: [
|
layout: [
|
||||||
inputText,
|
inputText,
|
||||||
|
|||||||
@@ -40,15 +40,15 @@ import { ColorCfg } from "../../ColorCfg.js";
|
|||||||
import { Layout } from "../Layout.js";
|
import { Layout } from "../Layout.js";
|
||||||
import { Input } from "../Widgets/Input.js";
|
import { Input } from "../Widgets/Input.js";
|
||||||
|
|
||||||
export class LayerEditBox extends Box {
|
export class HiPSSettingsBox extends Box {
|
||||||
// Constructor
|
// Constructor
|
||||||
constructor(aladin, options) {
|
constructor(aladin, options) {
|
||||||
super(
|
super({
|
||||||
{
|
|
||||||
cssStyle: {
|
cssStyle: {
|
||||||
padding: '4px',
|
padding: '4px',
|
||||||
backgroundColor: 'black',
|
backgroundColor: 'black',
|
||||||
},
|
},
|
||||||
|
close: false,
|
||||||
...options
|
...options
|
||||||
},
|
},
|
||||||
aladin.aladinDiv
|
aladin.aladinDiv
|
||||||
@@ -162,21 +162,19 @@ import { ColorCfg } from "../../ColorCfg.js";
|
|||||||
|
|
||||||
let layerOpacity = layer.getOpacity()
|
let layerOpacity = layer.getOpacity()
|
||||||
|
|
||||||
self.opacitySettingsContent = Layout.horizontal([
|
self.opacitySettingsContent = Input.slider({
|
||||||
Input.slider({
|
tooltip: {content: layerOpacity, position: {direction: 'bottom'}},
|
||||||
tooltip: {content: layerOpacity, position: {direction: 'bottom'}},
|
name: 'opacitySlider',
|
||||||
name: 'opacitySlider',
|
type: 'range',
|
||||||
type: 'range',
|
min: 0.0,
|
||||||
min: 0.0,
|
max: 1.0,
|
||||||
max: 1.0,
|
value: layerOpacity,
|
||||||
value: layerOpacity,
|
change(e, slider) {
|
||||||
change(e, slider) {
|
const opacity = +e.target.value;
|
||||||
const opacity = +e.target.value;
|
layer.setOpacity(opacity)
|
||||||
layer.setOpacity(opacity)
|
slider.update({value: opacity, tooltip: {content: opacity.toFixed(2), position: {direction: 'bottom'}}})
|
||||||
slider.update({value: opacity, tooltip: {content: opacity.toFixed(2), position: {direction: 'bottom'}}})
|
}
|
||||||
}
|
})
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let brightness = layer.getColorCfg().getBrightness()
|
let brightness = layer.getColorCfg().getBrightness()
|
||||||
let saturation = layer.getColorCfg().getSaturation()
|
let saturation = layer.getColorCfg().getSaturation()
|
||||||
@@ -311,10 +309,10 @@ import { ColorCfg } from "../../ColorCfg.js";
|
|||||||
|
|
||||||
_addListeners() {
|
_addListeners() {
|
||||||
ALEvent.HIPS_LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, (e) => {
|
ALEvent.HIPS_LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, (e) => {
|
||||||
const layerChanged = e.detail.layer;
|
const hips = e.detail.layer;
|
||||||
let selectedLayer = this.options.layer;
|
let selectedLayer = this.options.layer;
|
||||||
if (selectedLayer && layerChanged.layer === selectedLayer.layer) {
|
if (selectedLayer && hips.layer === selectedLayer.layer) {
|
||||||
let colorCfg = layerChanged.getColorCfg();
|
let colorCfg = hips.getColorCfg();
|
||||||
|
|
||||||
let cmap = colorCfg.getColormap();
|
let cmap = colorCfg.getColormap();
|
||||||
let reversed = colorCfg.getReversed();
|
let reversed = colorCfg.getReversed();
|
||||||
@@ -323,7 +321,9 @@ import { ColorCfg } from "../../ColorCfg.js";
|
|||||||
let [minCut, maxCut] = colorCfg.getCuts();
|
let [minCut, maxCut] = colorCfg.getCuts();
|
||||||
this.minCutInput.set(+minCut.toFixed(2));
|
this.minCutInput.set(+minCut.toFixed(2));
|
||||||
this.maxCutInput.set(+maxCut.toFixed(2));
|
this.maxCutInput.set(+maxCut.toFixed(2));
|
||||||
this.stretchSelector.update({value: stretch})
|
this.stretchSelector.update({value: stretch});
|
||||||
|
|
||||||
|
this.opacitySettingsContent.set(hips.getOpacity())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ export class ShortLivedBox extends Box {
|
|||||||
constructor(aladin) {
|
constructor(aladin) {
|
||||||
super(
|
super(
|
||||||
{
|
{
|
||||||
|
close: false,
|
||||||
cssStyle: {
|
cssStyle: {
|
||||||
color: 'white',
|
color: 'white',
|
||||||
backgroundColor: 'black',
|
backgroundColor: 'black',
|
||||||
|
|||||||
874
src/js/gui/Box/StackBox.js
Normal file
874
src/js/gui/Box/StackBox.js
Normal file
@@ -0,0 +1,874 @@
|
|||||||
|
// Copyright 2013 - UDS/CNRS
|
||||||
|
// The Aladin Lite program is distributed under the terms
|
||||||
|
// of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// This file is part of Aladin Lite.
|
||||||
|
//
|
||||||
|
// Aladin Lite is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 3 of the License.
|
||||||
|
//
|
||||||
|
// Aladin Lite is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// The GNU General Public License is available in COPYING file
|
||||||
|
// along with Aladin Lite.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Aladin Lite project
|
||||||
|
*
|
||||||
|
* File gui/Stack/Menu.js
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: Matthieu Baumann [CDS, matthieu.baumann@astro.unistra.fr]
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
import { CatalogQueryBox } from "./CatalogQueryBox.js";
|
||||||
|
import { ALEvent } from "../../events/ALEvent.js";
|
||||||
|
import { Layout } from "../Layout.js";
|
||||||
|
import { ContextMenu } from "../Widgets/ContextMenu.js";
|
||||||
|
import { ActionButton } from "../Widgets/ActionButton.js";
|
||||||
|
import A from "../../A.js";
|
||||||
|
import { Utils } from "../../Utils";
|
||||||
|
import { View } from "../../View.js";
|
||||||
|
import { HiPSSettingsBox } from "./HiPSSettingsBox.js";
|
||||||
|
import searchIconUrl from '../../../../assets/icons/search.svg';
|
||||||
|
import showIconUrl from '../../../../assets/icons/show.svg';
|
||||||
|
import addIconUrl from '../../../../assets/icons/plus.svg';
|
||||||
|
import hideIconUrl from '../../../../assets/icons/hide.svg';
|
||||||
|
import removeIconUrl from '../../../../assets/icons/remove.svg';
|
||||||
|
import settingsIconUrl from '../../../../assets/icons/settings.svg';
|
||||||
|
import { ImageFITS } from "../../ImageFITS.js";
|
||||||
|
import searchIconImg from '../../../../assets/icons/search.svg';
|
||||||
|
import { TogglerActionButton } from "../Button/Toggler.js";
|
||||||
|
import { Icon } from "../Widgets/Icon.js";
|
||||||
|
import { ImageSurvey } from "../../ImageSurvey.js";
|
||||||
|
import { Box } from "../Widgets/Box.js";
|
||||||
|
import { CtxMenuActionButtonOpener } from "../Button/CtxMenuOpener.js";
|
||||||
|
import { HiPSSearch } from "../Input/HiPSSearch.js";
|
||||||
|
|
||||||
|
export class OverlayStackBox extends Box {
|
||||||
|
/*static previewImagesUrl = {
|
||||||
|
'AllWISE color': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_allWISE_color.jpg',
|
||||||
|
'DSS colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_DSS2_color.jpg',
|
||||||
|
'DSS2 Red (F+R)': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_DSS2_red.jpg',
|
||||||
|
'Fermi color': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_Fermi_color.jpg',
|
||||||
|
'GALEXGR6_7 NUV': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_GALEXGR6_7_color.jpg',
|
||||||
|
'GLIMPSE360': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_GLIMPSE360.jpg',
|
||||||
|
'Halpha': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_VTSS_Ha.jpg',
|
||||||
|
'IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_SPITZER_color.jpg',
|
||||||
|
'IRIS colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_IRIS_color.jpg',
|
||||||
|
'Mellinger colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_Mellinger_color.jpg',
|
||||||
|
'PanSTARRS DR1 color': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_PanSTARRS_DR1_color-z-zg-g.jpg',
|
||||||
|
'2MASS colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_2MASS_color.jpg',
|
||||||
|
'AKARI colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_AKARI_FIS_Color.jpg',
|
||||||
|
'SWIFT': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_SWIFT_BAT_FLUX.jpg',
|
||||||
|
'VTSS-Ha': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_Finkbeiner.jpg',
|
||||||
|
'XMM PN colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_XMM_PN_color.jpg',
|
||||||
|
'SDSS9 colored': 'https://aladin.cds.unistra.fr/AladinLite/survey-previews/P_SDSS9_color.jpg',
|
||||||
|
};*/
|
||||||
|
static predefinedCats = {
|
||||||
|
simbad: {url: 'https://axel.u-strasbg.fr/HiPSCatService/SIMBAD', options: {id: 'simbad', name: 'SIMBAD', shape: 'circle', sourceSize: 8, color: '#318d80', onClick: 'showTable'}},
|
||||||
|
gaia: {url: 'https://axel.u-strasbg.fr/HiPSCatService/I/355/gaiadr3', options: {id: 'gaia-dr3', name: 'Gaia DR3', shape: 'square', sourceSize: 8, color: '#6baed6', onClick: 'showTable'}},
|
||||||
|
twomass: {url: 'https://axel.u-strasbg.fr/HiPSCatService/II/246/out', options: {id: '2mass', name: '2MASS', shape: 'plus', sourceSize: 8, color: '#dd2233', onClick: 'showTable'}}
|
||||||
|
};
|
||||||
|
// Constructor
|
||||||
|
constructor(aladin) {
|
||||||
|
super({
|
||||||
|
close: false,
|
||||||
|
header: {
|
||||||
|
title: 'Stack',
|
||||||
|
},
|
||||||
|
classList: ['aladin-stack-box'],
|
||||||
|
content: []
|
||||||
|
},
|
||||||
|
aladin.aladinDiv);
|
||||||
|
this.aladin = aladin;
|
||||||
|
|
||||||
|
this.mode = 'stack';
|
||||||
|
|
||||||
|
this._addListeners();
|
||||||
|
|
||||||
|
this.mocHiPSUrls = {}
|
||||||
|
this.HiPSui = {}
|
||||||
|
let self = this;
|
||||||
|
// Add overlay button
|
||||||
|
this.addOverlayBtn = new CtxMenuActionButtonOpener({
|
||||||
|
icon: {
|
||||||
|
url: addIconUrl,
|
||||||
|
size: 'small',
|
||||||
|
monochrome: true,
|
||||||
|
},
|
||||||
|
tooltip: {content: 'A catalog, MOC or footprint', position: { direction: 'top' }},
|
||||||
|
ctxMenu: [
|
||||||
|
{
|
||||||
|
label: 'Catalogue',
|
||||||
|
subMenu: [
|
||||||
|
{
|
||||||
|
label: {
|
||||||
|
icon: {
|
||||||
|
url: 'https://aladin.cds.unistra.fr/AladinLite/logos/SIMBAD.svg',
|
||||||
|
cssStyle: {
|
||||||
|
width: '3rem',
|
||||||
|
height: '3rem',
|
||||||
|
cursor: 'help',
|
||||||
|
},
|
||||||
|
action(o) {
|
||||||
|
window.open('https://simbad.cds.unistra.fr/simbad/')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content: 'database',
|
||||||
|
tooltip: {content: 'Click to go to the SIMBAD database', position: {direction: 'bottom'}},
|
||||||
|
},
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
const simbadHiPS = A.catalogHiPS(OverlayStackBox.predefinedCats.simbad.url, OverlayStackBox.predefinedCats.simbad.options);
|
||||||
|
self.aladin.addCatalog(simbadHiPS);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gaia DR3',
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
const simbadHiPS = A.catalogHiPS(OverlayStackBox.predefinedCats.gaia.url, OverlayStackBox.predefinedCats.gaia.options);
|
||||||
|
self.aladin.addCatalog(simbadHiPS);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '2MASS',
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
const simbadHiPS = A.catalogHiPS(OverlayStackBox.predefinedCats.twomass.url, OverlayStackBox.predefinedCats.twomass.options);
|
||||||
|
self.aladin.addCatalog(simbadHiPS);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ContextMenu.fileLoaderItem({
|
||||||
|
label: 'From a VOTable File',
|
||||||
|
accept: '.xml,.vot',
|
||||||
|
action(file) {
|
||||||
|
let url = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
A.catalogFromURL(
|
||||||
|
url,
|
||||||
|
{onClick: 'showTable'},
|
||||||
|
(catalog) => {
|
||||||
|
self.aladin.addCatalog(catalog)
|
||||||
|
},
|
||||||
|
e => alert(e)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
label: {
|
||||||
|
icon: {
|
||||||
|
url: searchIconImg,
|
||||||
|
monochrome: true,
|
||||||
|
tooltip: {content: 'Find a specific catalogue <br /> in our database...', position: { direction: 'top' }},
|
||||||
|
cssStyle: {
|
||||||
|
cursor: 'help',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
content: 'More...'
|
||||||
|
},
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
self._hide();
|
||||||
|
|
||||||
|
if (!self.catBox) {
|
||||||
|
self.catBox = new CatalogQueryBox(self.aladin);
|
||||||
|
self.catBox.attach({callback: () => {
|
||||||
|
self._show();
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.catBox._show({position: self.position});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: {
|
||||||
|
icon: {
|
||||||
|
url: Icon.dataURLFromSVG({svg: Icon.SVG_ICONS.MOC}),
|
||||||
|
size: 'small',
|
||||||
|
tooltip: {content: 'Define a selection coverage', position: {direction: 'bottom'}},
|
||||||
|
monochrome: true,
|
||||||
|
cssStyle: {
|
||||||
|
cursor: 'pointer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
content: 'MOC'
|
||||||
|
},
|
||||||
|
subMenu: [
|
||||||
|
ContextMenu.fileLoaderItem({
|
||||||
|
label: 'FITS File',
|
||||||
|
accept: '.fits',
|
||||||
|
action(file) {
|
||||||
|
let url = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
let moc = A.MOCFromURL(
|
||||||
|
url,
|
||||||
|
{name: file.name, lineWidth: 3.0},
|
||||||
|
);
|
||||||
|
self.aladin.addMOC(moc)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
label: 'From selection',
|
||||||
|
subMenu: [
|
||||||
|
{
|
||||||
|
label: '◌ Circle',
|
||||||
|
disabled: self.aladin.view.mode !== View.PAN ? {
|
||||||
|
reason: 'Exit your current mode<br/>(e.g. disable the SIMBAD pointer mode)'
|
||||||
|
} : false,
|
||||||
|
action(o) {
|
||||||
|
o.preventDefault();
|
||||||
|
o.stopPropagation();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
self.aladin.select('circle', c => {
|
||||||
|
try {
|
||||||
|
let [ra, dec] = self.aladin.pix2world(c.x, c.y, 'j2000');
|
||||||
|
let radius = self.aladin.angularDist(c.x, c.y, c.x + c.r, c.y);
|
||||||
|
|
||||||
|
// the moc needs a
|
||||||
|
let moc = A.MOCFromCone(
|
||||||
|
{ra, dec, radius},
|
||||||
|
{name: 'cone', lineWidth: 3.0},
|
||||||
|
);
|
||||||
|
self.aladin.addMOC(moc)
|
||||||
|
} catch {
|
||||||
|
console.error('Circle out of projection. Selection canceled')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '⬚ Rect',
|
||||||
|
disabled: self.aladin.view.mode !== View.PAN ? {
|
||||||
|
reason: 'Exit your current mode<br/>(e.g. disable the SIMBAD pointer mode)'
|
||||||
|
} : false,
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
self.aladin.select('rect', r => {
|
||||||
|
try {
|
||||||
|
let [ra1, dec1] = self.aladin.pix2world(r.x, r.y, 'j2000');
|
||||||
|
let [ra2, dec2] = self.aladin.pix2world(r.x + r.w, r.y, 'j2000');
|
||||||
|
let [ra3, dec3] = self.aladin.pix2world(r.x + r.w, r.y + r.h, 'j2000');
|
||||||
|
let [ra4, dec4] = self.aladin.pix2world(r.x, r.y + r.h, 'j2000');
|
||||||
|
|
||||||
|
let moc = A.MOCFromPolygon(
|
||||||
|
{
|
||||||
|
ra: [ra1, ra2, ra3, ra4],
|
||||||
|
dec: [dec1, dec2, dec3, dec4]
|
||||||
|
},
|
||||||
|
{name: 'rect', lineWidth: 3.0},
|
||||||
|
);
|
||||||
|
self.aladin.addMOC(moc)
|
||||||
|
} catch(_) {
|
||||||
|
alert('Selection covers a region out of the projection definition domain.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '⛉ Polygon',
|
||||||
|
disabled: self.aladin.view.mode !== View.PAN ? {
|
||||||
|
reason: 'Exit your current mode<br/>(e.g. disable the SIMBAD pointer mode)'
|
||||||
|
} : false,
|
||||||
|
action(o) {
|
||||||
|
o.stopPropagation();
|
||||||
|
o.preventDefault();
|
||||||
|
|
||||||
|
//self._hide();
|
||||||
|
|
||||||
|
self.aladin.select('poly', p => {
|
||||||
|
try {
|
||||||
|
let ra = []
|
||||||
|
let dec = []
|
||||||
|
for (const v of p.vertices) {
|
||||||
|
let [lon, lat] = self.aladin.pix2world(v.x, v.y, 'j2000');
|
||||||
|
ra.push(lon)
|
||||||
|
dec.push(lat)
|
||||||
|
}
|
||||||
|
|
||||||
|
let moc = A.MOCFromPolygon(
|
||||||
|
{ra, dec},
|
||||||
|
{name: 'poly', lineWidth: 3.0},
|
||||||
|
);
|
||||||
|
self.aladin.addMOC(moc)
|
||||||
|
|
||||||
|
} catch(_) {
|
||||||
|
alert('Selection covers a region out of the projection definition domain.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}, this.aladin)
|
||||||
|
|
||||||
|
this.addHiPSBtn = new CtxMenuActionButtonOpener({
|
||||||
|
icon: {
|
||||||
|
url: addIconUrl,
|
||||||
|
size: 'small',
|
||||||
|
monochrome: true,
|
||||||
|
},
|
||||||
|
ctxMenu: [
|
||||||
|
{
|
||||||
|
label: {
|
||||||
|
icon: {
|
||||||
|
url: searchIconUrl,
|
||||||
|
monochrome: true,
|
||||||
|
tooltip: {content: 'From our database...', position: { direction: 'right' }},
|
||||||
|
cssStyle: {
|
||||||
|
cursor: 'help',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
content: 'Add new survey'
|
||||||
|
},
|
||||||
|
action: (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
/*self._hide();
|
||||||
|
|
||||||
|
self.hipsSelectorBox = new HiPSSelectorBox(self.aladin);
|
||||||
|
// attach a callback
|
||||||
|
self.hipsSelectorBox.attach(
|
||||||
|
(HiPSId) => {
|
||||||
|
let name = Utils.uuidv4()
|
||||||
|
self.aladin.setOverlayImageLayer(HiPSId, name)
|
||||||
|
|
||||||
|
self.show();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
self.hipsSelectorBox._show({
|
||||||
|
position: self.position,
|
||||||
|
});*/
|
||||||
|
self.aladin.addNewImageLayer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ContextMenu.fileLoaderItem({
|
||||||
|
label: 'FITS image file',
|
||||||
|
accept: '.fits',
|
||||||
|
action(file) {
|
||||||
|
let url = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
const image = self.aladin.createImageFITS(
|
||||||
|
url,
|
||||||
|
file.name,
|
||||||
|
undefined,
|
||||||
|
(ra, dec, fov, _) => {
|
||||||
|
// Center the view around the new fits object
|
||||||
|
self.aladin.gotoRaDec(ra, dec);
|
||||||
|
self.aladin.setFoV(fov * 1.1);
|
||||||
|
//self.aladin.selectLayer(image.layer);
|
||||||
|
},
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
self.aladin.setOverlayImageLayer(image, Utils.uuidv4())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
tooltip: { content: 'Add a HiPS or an FITS image', position: {direction: 'top'} },
|
||||||
|
}, this.aladin);
|
||||||
|
|
||||||
|
this.update({content: this.createLayout()});
|
||||||
|
}
|
||||||
|
|
||||||
|
_addListeners() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
let updateOverlayList = () => {
|
||||||
|
let wasHidden = self.isHidden;
|
||||||
|
self._hide();
|
||||||
|
// recompute the ui
|
||||||
|
// If it is shown, update it
|
||||||
|
// show will update the content of the stack
|
||||||
|
self.update({content: self.createLayout()});
|
||||||
|
|
||||||
|
if (!wasHidden)
|
||||||
|
self._show();
|
||||||
|
};
|
||||||
|
|
||||||
|
ALEvent.GRAPHIC_OVERLAY_LAYER_ADDED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.GRAPHIC_OVERLAY_LAYER_REMOVED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.GRAPHIC_OVERLAY_LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.HIPS_LAYER_ADDED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.HIPS_LAYER_RENAMED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.HIPS_LAYER_SWAP.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.HIPS_LAYER_REMOVED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
updateOverlayList();
|
||||||
|
});
|
||||||
|
|
||||||
|
ALEvent.HIPS_LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||||
|
const hips = e.detail.layer;
|
||||||
|
let ui = self.HiPSui[hips.layer];
|
||||||
|
|
||||||
|
// change the ui from parameter changes
|
||||||
|
// show button
|
||||||
|
const opacity = hips.getOpacity();
|
||||||
|
if (opacity !== 0.0) {
|
||||||
|
ui.showBtn.update({icon: {monochrome: true, url: showIconUrl}, tooltip: {content: 'Hide'}});
|
||||||
|
} else {
|
||||||
|
ui.showBtn.update({icon: {monochrome: true, url: hideIconUrl}, tooltip: {content: 'Show'}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateOverlayList();
|
||||||
|
|
||||||
|
// Add a listener for HiPS list changes
|
||||||
|
ALEvent.HIPS_LIST_UPDATED.listenedBy(this.aladin.aladinDiv, () => {
|
||||||
|
// Recompute the autocompletion as the cache has changed
|
||||||
|
HiPSSearch.HiPSList = {};
|
||||||
|
for (var key in ImageSurvey.cache) {
|
||||||
|
let HiPS = ImageSurvey.cache[key];
|
||||||
|
// search with the name or id
|
||||||
|
HiPSSearch.HiPSList[HiPS.name] = HiPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
let keys = Object.keys(HiPSSearch.HiPSList)
|
||||||
|
// change the autocomplete of all the search input text
|
||||||
|
for (var key in this.HiPSui) {
|
||||||
|
let hips = this.HiPSui[key];
|
||||||
|
hips.searchInput.setAutocompletionList(keys)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_hide() {
|
||||||
|
for (var key in this.HiPSui) {
|
||||||
|
let hips = this.HiPSui[key];
|
||||||
|
if (hips.settingsBtn.toggled) {
|
||||||
|
// toggle off
|
||||||
|
hips.settingsBtn.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.catBox) {
|
||||||
|
this.catBox._hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.addOverlayBtn)
|
||||||
|
this.addOverlayBtn.hideMenu();
|
||||||
|
|
||||||
|
if (this.addHiPSBtn)
|
||||||
|
this.addHiPSBtn.hideMenu();
|
||||||
|
|
||||||
|
super._hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
createLayout() {
|
||||||
|
this.HiPSui = {};
|
||||||
|
|
||||||
|
let layout = [
|
||||||
|
Layout.horizontal([this.addOverlayBtn, 'Overlays'])
|
||||||
|
];
|
||||||
|
|
||||||
|
layout = layout.concat(this._createOverlaysList());
|
||||||
|
|
||||||
|
layout.push(Layout.horizontal({
|
||||||
|
layout: [this.addHiPSBtn, 'Surveys'],
|
||||||
|
}))
|
||||||
|
layout = layout.concat(this._createSurveysList());
|
||||||
|
|
||||||
|
return new Layout({layout, classList: ['content']});
|
||||||
|
}
|
||||||
|
|
||||||
|
_createOverlaysList() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
let layout = []
|
||||||
|
const overlays = Array.from(this.aladin.getOverlays()).reverse().map((overlay) => {
|
||||||
|
return overlay;
|
||||||
|
});
|
||||||
|
// list of overlays
|
||||||
|
for(const overlay of overlays) {
|
||||||
|
const name = overlay.name;
|
||||||
|
let showBtn = new ActionButton({
|
||||||
|
size: 'small',
|
||||||
|
icon: {
|
||||||
|
url: overlay.isShowing ? showIconUrl : hideIconUrl,
|
||||||
|
monochrome: true,
|
||||||
|
},
|
||||||
|
/*cssStyle: {
|
||||||
|
visibility: Utils.hasTouchScreen() ? 'visible' : 'hidden',
|
||||||
|
},*/
|
||||||
|
tooltip: {content: overlay.isShowing ? 'Hide' : 'Show', position: {direction: 'top'}},
|
||||||
|
action(e, btn) {
|
||||||
|
if (overlay.isShowing) {
|
||||||
|
overlay.hide()
|
||||||
|
btn.update({icon: {monochrome: true, url: hideIconUrl}, tooltip: {content: 'Show'}});
|
||||||
|
} else {
|
||||||
|
overlay.show()
|
||||||
|
btn.update({icon: {monochrome: true, url: showIconUrl}, tooltip: {content: 'Hide'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let deleteBtn = new ActionButton({
|
||||||
|
icon: {
|
||||||
|
url: removeIconUrl,
|
||||||
|
monochrome: true,
|
||||||
|
},
|
||||||
|
size: 'small',
|
||||||
|
/*cssStyle: {
|
||||||
|
visibility: Utils.hasTouchScreen() ? 'visible' : 'hidden',
|
||||||
|
},*/
|
||||||
|
tooltip: {
|
||||||
|
content: 'Remove',
|
||||||
|
position: {direction: 'top'}
|
||||||
|
},
|
||||||
|
action(e) {
|
||||||
|
self.aladin.removeLayer(overlay)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let item = Layout.horizontal({
|
||||||
|
layout: [
|
||||||
|
this._addOverlayIcon(overlay),
|
||||||
|
'<div style="background-color: rgba(0, 0, 0, 0.6); padding: 3px; border-radius: 3px; word-break: break-word;">' + name + '</div>',
|
||||||
|
Layout.horizontal({layout: [showBtn, deleteBtn]})
|
||||||
|
],
|
||||||
|
cssStyle: {
|
||||||
|
textAlign: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
listStyle: 'none',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
width: '100%',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*if(!Utils.hasTouchScreen()) {
|
||||||
|
layout.push({
|
||||||
|
label: item,
|
||||||
|
cssStyle,
|
||||||
|
hover(e) {
|
||||||
|
showBtn.el.style.visibility = 'visible'
|
||||||
|
deleteBtn.el.style.visibility = 'visible'
|
||||||
|
},
|
||||||
|
unhover(e) {
|
||||||
|
showBtn.el.style.visibility = 'hidden'
|
||||||
|
deleteBtn.el.style.visibility = 'hidden'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
layout.push({
|
||||||
|
label: item,
|
||||||
|
cssStyle
|
||||||
|
})
|
||||||
|
}*/
|
||||||
|
layout.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createSurveysList() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
const layers = Array.from(self.aladin.getImageOverlays()).reverse().map((name) => {
|
||||||
|
let overlay = self.aladin.getOverlayImageLayer(name);
|
||||||
|
return overlay;
|
||||||
|
});
|
||||||
|
// survey list
|
||||||
|
let selectedLayer = self.aladin.getSelectedLayer();
|
||||||
|
|
||||||
|
/*if (!layers) {
|
||||||
|
super.attach(layout);
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
let layout = [];
|
||||||
|
const defaultLayers = Object.entries(ImageSurvey.cache).sort(function (e1, e2) {
|
||||||
|
let a = e1[1]
|
||||||
|
let b = e2[1]
|
||||||
|
|
||||||
|
if (!a.order) {
|
||||||
|
return a.name > b.name ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.maxOrder && a.maxOrder > b.maxOrder ? 1 : -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
for(const layer of layers) {
|
||||||
|
let searchInput = new HiPSSearch(self.aladin, {layer})
|
||||||
|
|
||||||
|
let deleteBtn = ActionButton.createSmallSizedIconBtn({
|
||||||
|
icon: {url: removeIconUrl, monochrome: true},
|
||||||
|
|
||||||
|
disable: layer.layer === 'base',
|
||||||
|
tooltip: {content: 'Remove', position: {direction: 'top'}},
|
||||||
|
action(e) {
|
||||||
|
self.aladin.removeImageLayer(layer.layer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let showBtn = ActionButton.createSmallSizedIconBtn({
|
||||||
|
icon: {
|
||||||
|
url: layer.getOpacity() === 0.0 ? hideIconUrl : showIconUrl,
|
||||||
|
monochrome: true,
|
||||||
|
},
|
||||||
|
tooltip: {content: layer.getOpacity() === 0.0 ? 'Show' : 'Hide', position: {direction: 'top'}},
|
||||||
|
action(e, btn) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
let opacity = layer.getOpacity();
|
||||||
|
if (opacity === 0.0) {
|
||||||
|
layer.setOpacity(1.0);
|
||||||
|
btn.update({icon: {monochrome: true, url: showIconUrl}, tooltip: {content: 'Hide'}});
|
||||||
|
} else {
|
||||||
|
layer.setOpacity(0.0);
|
||||||
|
btn.update({icon: {monochrome: true, url: hideIconUrl}, tooltip: {content: 'Show'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let settingsBox = new HiPSSettingsBox(self.aladin);
|
||||||
|
settingsBox.update({layer})
|
||||||
|
settingsBox._hide();
|
||||||
|
|
||||||
|
let settingsBtn = new TogglerActionButton({
|
||||||
|
icon: {url: settingsIconUrl, monochrome: true},
|
||||||
|
size: 'small',
|
||||||
|
tooltip: {content: 'Settings', position: {direction: 'top'}},
|
||||||
|
toggled: false,
|
||||||
|
actionOn: (e) => {
|
||||||
|
settingsBox._show({position: {nextTo: settingsBtn, direction: 'right', aladin: self.aladin}});
|
||||||
|
},
|
||||||
|
actionOff: (e) => {
|
||||||
|
settingsBox._hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let loadMOCBtn = new ActionButton({
|
||||||
|
size: 'small',
|
||||||
|
|
||||||
|
icon: {url: Icon.dataURLFromSVG({svg: Icon.SVG_ICONS.MOC}), monochrome: true},
|
||||||
|
tooltip: {content: 'Add coverage', position: {direction: 'top'}},
|
||||||
|
toggled: (() => {
|
||||||
|
let overlays = self.aladin.getOverlays();
|
||||||
|
let found = overlays.find((o) => o.type === "moc" && o.name === layer.name);
|
||||||
|
return found !== undefined;
|
||||||
|
})(),
|
||||||
|
action: (e, btn) => {
|
||||||
|
if (!btn.options.toggled) {
|
||||||
|
// load the moc
|
||||||
|
let moc = A.MOCFromURL(
|
||||||
|
layer.url + '/Moc.fits',
|
||||||
|
{lineWidth: 3, name: layer.name},
|
||||||
|
() => {
|
||||||
|
self.mocHiPSUrls[layer.url] = moc;
|
||||||
|
|
||||||
|
if (self.aladin.statusBar) {
|
||||||
|
self.aladin.statusBar.appendMessage({
|
||||||
|
message: 'Coverage of ' + layer.name + ' loaded',
|
||||||
|
duration: 2000,
|
||||||
|
type: 'info'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.update({
|
||||||
|
toggled: true,
|
||||||
|
tooltip: {content: 'Remove coverage',
|
||||||
|
position: {direction: 'top'}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.aladin.addMOC(moc)
|
||||||
|
} else {
|
||||||
|
// unload the moc
|
||||||
|
let moc = self.mocHiPSUrls[layer.url];
|
||||||
|
self.aladin.removeLayer(moc)
|
||||||
|
|
||||||
|
delete self.mocHiPSUrls[layer.url];
|
||||||
|
|
||||||
|
if (self.aladin.statusBar) {
|
||||||
|
self.aladin.statusBar.appendMessage({
|
||||||
|
message: 'Coverage of ' + layer.name + ' removed',
|
||||||
|
duration: 2000,
|
||||||
|
type: 'info'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.update({
|
||||||
|
toggled: false,
|
||||||
|
tooltip: {content: 'Add coverage', position: {direction: 'top'}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let layerClassName = 'a' + layer.layer.replace(/[.\/ ]/g, '')
|
||||||
|
|
||||||
|
let btns = [showBtn, settingsBtn];
|
||||||
|
|
||||||
|
if (layer.subtype !== 'fits') {
|
||||||
|
btns.push(loadMOCBtn)
|
||||||
|
}
|
||||||
|
btns.push(deleteBtn)
|
||||||
|
|
||||||
|
let item = Layout.horizontal({
|
||||||
|
layout: [
|
||||||
|
searchInput,
|
||||||
|
//'<div class="' + layerClassName + '" style="background-color: rgba(0, 0, 0, 0.6); line-height: 1rem; padding: 3px; border-radius: 3px; word-break: break-word;' + (selectedLayer === layer.layer ? 'border: 1px solid white;' : '') + '">' + (layer.name) + '</div>',
|
||||||
|
Layout.horizontal(btns)
|
||||||
|
],
|
||||||
|
cssStyle: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
listStyle: 'none',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
width: '100%',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layout.push(item);
|
||||||
|
|
||||||
|
if (!(layer.layer in self.HiPSui)) {
|
||||||
|
self.HiPSui[layer.layer] = {
|
||||||
|
searchInput,
|
||||||
|
settingsBox,
|
||||||
|
settingsBtn,
|
||||||
|
showBtn,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*_findPreviewImageUrl(layer) {
|
||||||
|
if (layer instanceof ImageFITS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layer.creatorDid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const creatorDid = layer.creatorDid;
|
||||||
|
|
||||||
|
for (const key in Stack.previewImagesUrl) {
|
||||||
|
if (creatorDid.includes(key)) {
|
||||||
|
return Stack.previewImagesUrl[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if not found
|
||||||
|
return layer.url + '/preview.jpg'
|
||||||
|
}*/
|
||||||
|
|
||||||
|
_addOverlayIcon(overlay) {
|
||||||
|
var tooltipText;
|
||||||
|
var svg = '';
|
||||||
|
if (overlay.type == 'catalog' || overlay.type == 'progressivecat') {
|
||||||
|
var nbSources = overlay.getSources().length;
|
||||||
|
tooltipText = nbSources + ' source' + (nbSources > 1 ? 's' : '');
|
||||||
|
|
||||||
|
svg = Icon.SVG_ICONS.CATALOG;
|
||||||
|
}
|
||||||
|
else if (overlay.type == 'moc') {
|
||||||
|
tooltipText = 'Coverage: ' + (100 * overlay.skyFraction()).toFixed(2) + ' % of sky';
|
||||||
|
|
||||||
|
svg = Icon.SVG_ICONS.MOC;
|
||||||
|
}
|
||||||
|
else if (overlay.type == 'overlay') {
|
||||||
|
svg = Icon.SVG_ICONS.OVERLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tooltip;
|
||||||
|
if (tooltipText) {
|
||||||
|
tooltip = { content: tooltipText, position: {direction: 'bottom'} }
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve SVG icon, and apply the layer color
|
||||||
|
return new Icon({
|
||||||
|
size: 'small',
|
||||||
|
url: Icon.dataURLFromSVG({svg, color: overlay.color}),
|
||||||
|
tooltip
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_show(options) {
|
||||||
|
if (!this.aladin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.position = (options && options.position) || this.position;
|
||||||
|
|
||||||
|
if (!this.position)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.position.aladin = this.aladin;
|
||||||
|
|
||||||
|
super._show({
|
||||||
|
...options,
|
||||||
|
...{position: this.position},
|
||||||
|
})
|
||||||
|
|
||||||
|
const innerHeight = this.aladin.aladinDiv.offsetHeight;
|
||||||
|
this.element().querySelectorAll(".surveyItem")
|
||||||
|
.forEach((surveyItem) => {
|
||||||
|
surveyItem.querySelectorAll(".aladin-context-sub-menu")
|
||||||
|
// skip the first menu
|
||||||
|
.forEach((subMenu) => {
|
||||||
|
subMenu.style.display = 'block'
|
||||||
|
|
||||||
|
let Y = innerHeight - (subMenu.getBoundingClientRect().y - this.aladin.aladinDiv.getBoundingClientRect().y);
|
||||||
|
subMenu.style.display = 'none'
|
||||||
|
|
||||||
|
subMenu.style.maxHeight = Y + 'px';
|
||||||
|
subMenu.style.overflowY = 'scroll';
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ import { Icon } from "../Widgets/Icon";
|
|||||||
|
|
||||||
export class StatusBarBox extends Box {
|
export class StatusBarBox extends Box {
|
||||||
constructor(aladin, options) {
|
constructor(aladin, options) {
|
||||||
super(options, aladin.aladinDiv)
|
super({...options, close: false}, aladin.aladinDiv)
|
||||||
|
|
||||||
this.addClass("aladin-status-bar");
|
this.addClass("aladin-status-bar");
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
import { CtxMenuActionButtonOpener } from "./CtxMenuOpener";
|
import { CtxMenuActionButtonOpener } from "./CtxMenuOpener";
|
||||||
import stackOverlayIconUrl from './../../../../assets/icons/stack.svg';
|
import stackOverlayIconUrl from './../../../../assets/icons/stack.svg';
|
||||||
import { OverlayStack } from "../CtxMenu/OverlayStack";
|
import { OverlayStack } from "../CtxMenu/OverlayStack";
|
||||||
|
import { OverlayStackBox } from "../Box/StackBox";
|
||||||
|
import { TogglerActionButton } from "./Toggler";
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Aladin Lite project
|
* Aladin Lite project
|
||||||
*
|
*
|
||||||
@@ -35,14 +37,15 @@ import { OverlayStack } from "../CtxMenu/OverlayStack";
|
|||||||
* Class representing a Tabs layout
|
* Class representing a Tabs layout
|
||||||
* @extends CtxMenuActionButtonOpener
|
* @extends CtxMenuActionButtonOpener
|
||||||
*/
|
*/
|
||||||
export class OverlayStackButton extends CtxMenuActionButtonOpener {
|
export class OverlayStackButton extends TogglerActionButton {
|
||||||
/**
|
/**
|
||||||
* UI responsible for displaying the viewport infos
|
* UI responsible for displaying the viewport infos
|
||||||
* @param {Aladin} aladin - The aladin instance.
|
* @param {Aladin} aladin - The aladin instance.
|
||||||
*/
|
*/
|
||||||
constructor(aladin, options) {
|
constructor(aladin, options) {
|
||||||
let self;
|
let self;
|
||||||
let stack = new OverlayStack(aladin);
|
let stack = new OverlayStackBox(aladin);
|
||||||
|
|
||||||
super({
|
super({
|
||||||
icon: {
|
icon: {
|
||||||
size: 'medium',
|
size: 'medium',
|
||||||
@@ -56,7 +59,18 @@ import { OverlayStack } from "../CtxMenu/OverlayStack";
|
|||||||
direction: 'top right'
|
direction: 'top right'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ctxMenu: stack,
|
toggled: false,
|
||||||
|
actionOn: (e) => {
|
||||||
|
stack._show({
|
||||||
|
position: {
|
||||||
|
nextTo: self,
|
||||||
|
direction: 'right'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
actionOff: (e) => {
|
||||||
|
stack._hide()
|
||||||
|
},
|
||||||
...options
|
...options
|
||||||
}, aladin);
|
}, aladin);
|
||||||
|
|
||||||
|
|||||||
@@ -43,20 +43,26 @@ export class TogglerActionButton extends ActionButton {
|
|||||||
...options,
|
...options,
|
||||||
toggled,
|
toggled,
|
||||||
action(o) {
|
action(o) {
|
||||||
toggled = !toggled;
|
self.toggle(o);
|
||||||
|
|
||||||
self.update({toggled, tooltip: toggled ? options.tooltipOn : options.tooltipOff})
|
|
||||||
if (toggled && options.actionOn) {
|
|
||||||
options.actionOn(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toggled && options.actionOff) {
|
|
||||||
options.actionOff(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
options.action && options.action(o)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.toggled = toggled;
|
||||||
|
|
||||||
self = this;
|
self = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggle(o) {
|
||||||
|
this.toggled = !this.toggled;
|
||||||
|
|
||||||
|
if (this.toggled && this.options.actionOn) {
|
||||||
|
this.options.actionOn(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.toggled && this.options.actionOff) {
|
||||||
|
this.options.actionOff(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
// once the actions has been executed, modify the styling
|
||||||
|
this.update({toggled: this.toggled, tooltip: this.toggled ? this.options.tooltipOn : this.options.tooltipOff})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ import { CatalogQueryBox } from "../Box/CatalogQueryBox.js";
|
|||||||
import A from "../../A.js";
|
import A from "../../A.js";
|
||||||
import { Utils } from "../../../js/Utils";
|
import { Utils } from "../../../js/Utils";
|
||||||
import { View } from "../../View.js";
|
import { View } from "../../View.js";
|
||||||
import { LayerEditBox } from "../Box/SurveyEditBox.js";
|
import { HiPSSettingsBox } from "../Box/HiPSSettingsBox.js";
|
||||||
import { HiPSSelectorBox } from "../Box/HiPSSelectorBox.js";
|
import { HiPSSelectorBox } from "../Box/HiPSSelectorBox.js";
|
||||||
import searchIconUrl from '../../../../assets/icons/search.svg';
|
import searchIconUrl from '../../../../assets/icons/search.svg';
|
||||||
import showIconUrl from '../../../../assets/icons/show.svg';
|
import showIconUrl from '../../../../assets/icons/show.svg';
|
||||||
@@ -456,70 +456,6 @@ export class OverlayStack extends ContextMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layout.push({
|
|
||||||
label: 'Add survey',
|
|
||||||
subMenu: [
|
|
||||||
{
|
|
||||||
label: {
|
|
||||||
icon: {
|
|
||||||
url: searchIconUrl,
|
|
||||||
monochrome: true,
|
|
||||||
tooltip: {content: 'From our database...', position: { direction: 'right' }},
|
|
||||||
cssStyle: {
|
|
||||||
cursor: 'help',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
content: 'Search for a survey'
|
|
||||||
},
|
|
||||||
action: (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
self._hide();
|
|
||||||
|
|
||||||
self.hipsSelectorBox = new HiPSSelectorBox(self.aladin);
|
|
||||||
// attach a callback
|
|
||||||
self.hipsSelectorBox.attach(
|
|
||||||
(HiPSId) => {
|
|
||||||
let name = Utils.uuidv4()
|
|
||||||
self.aladin.setOverlayImageLayer(HiPSId, name)
|
|
||||||
|
|
||||||
self.show();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
self.hipsSelectorBox._show({
|
|
||||||
position: self.position,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.mode = 'hips';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ContextMenu.fileLoaderItem({
|
|
||||||
label: 'FITS image file',
|
|
||||||
accept: '.fits',
|
|
||||||
action(file) {
|
|
||||||
let url = URL.createObjectURL(file);
|
|
||||||
|
|
||||||
const image = self.aladin.createImageFITS(
|
|
||||||
url,
|
|
||||||
file.name,
|
|
||||||
undefined,
|
|
||||||
(ra, dec, fov, _) => {
|
|
||||||
// Center the view around the new fits object
|
|
||||||
self.aladin.gotoRaDec(ra, dec);
|
|
||||||
self.aladin.setFoV(fov * 1.1);
|
|
||||||
//self.aladin.selectLayer(image.layer);
|
|
||||||
},
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
self.aladin.setOverlayImageLayer(image, Utils.uuidv4())
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
// survey list
|
// survey list
|
||||||
let selectedLayer = self.aladin.getSelectedLayer();
|
let selectedLayer = self.aladin.getSelectedLayer();
|
||||||
|
|
||||||
@@ -669,7 +605,7 @@ export class OverlayStack extends ContextMenu {
|
|||||||
let item = Layout.horizontal({
|
let item = Layout.horizontal({
|
||||||
layout: [
|
layout: [
|
||||||
'<div class="' + layerClassName + '" style="background-color: rgba(0, 0, 0, 0.6); line-height: 1rem; padding: 3px; border-radius: 3px; word-break: break-word;' + (selectedLayer === layer.layer ? 'border: 1px solid white;' : '') + '">' + (layer.name) + '</div>',
|
'<div class="' + layerClassName + '" style="background-color: rgba(0, 0, 0, 0.6); line-height: 1rem; padding: 3px; border-radius: 3px; word-break: break-word;' + (selectedLayer === layer.layer ? 'border: 1px solid white;' : '') + '">' + (layer.name) + '</div>',
|
||||||
Layout.horizontal({layout: btns})
|
Layout.horizontal(btns)
|
||||||
],
|
],
|
||||||
/*cssStyle: {
|
/*cssStyle: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|||||||
@@ -42,29 +42,25 @@ export class FoV extends DOMElement {
|
|||||||
// constructor
|
// constructor
|
||||||
constructor(aladin, options) {
|
constructor(aladin, options) {
|
||||||
let layout = [];
|
let layout = [];
|
||||||
|
|
||||||
if (options.showZoomControl) {
|
if (options.showZoomControl) {
|
||||||
layout.push(new ActionButton({
|
let zoomIn = new ActionButton({
|
||||||
|
classList: 'aladin-zoom-in',
|
||||||
size: 'small',
|
size: 'small',
|
||||||
|
tooltip: {content: 'zoom in', position: {direction: 'top'}},
|
||||||
icon: {
|
icon: {
|
||||||
monochrome: true,
|
monochrome: true,
|
||||||
size: 'small',
|
size: 'small',
|
||||||
url: plusIconUrl,
|
url: plusIconUrl,
|
||||||
},
|
},
|
||||||
cssStyle: {
|
|
||||||
marginRight: 0,
|
|
||||||
borderRight: 'none',
|
|
||||||
borderRadius: '5px 0px 0px 5px'
|
|
||||||
},
|
|
||||||
action(o) {
|
action(o) {
|
||||||
aladin.increaseZoom();
|
aladin.increaseZoom();
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
layout.push(new ActionButton({
|
let zoomOut = new ActionButton({
|
||||||
size: 'small',
|
size: 'small',
|
||||||
cssStyle: {
|
classList: 'aladin-zoom-out',
|
||||||
borderRadius: '0px 5px 5px 0px'
|
tooltip: {content: 'zoom out', position: {direction: 'top'}},
|
||||||
},
|
|
||||||
icon: {
|
icon: {
|
||||||
monochrome: true,
|
monochrome: true,
|
||||||
size: 'small',
|
size: 'small',
|
||||||
@@ -73,7 +69,12 @@ export class FoV extends DOMElement {
|
|||||||
action(o) {
|
action(o) {
|
||||||
aladin.decreaseZoom();
|
aladin.decreaseZoom();
|
||||||
}
|
}
|
||||||
}))
|
});
|
||||||
|
zoomIn.el.classList.add('aladin-zoom-in');
|
||||||
|
zoomOut.el.classList.add('aladin-zoom-out');
|
||||||
|
|
||||||
|
layout.push(zoomIn)
|
||||||
|
layout.push(zoomOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.showFov) {
|
if (options.showFov) {
|
||||||
@@ -82,10 +83,10 @@ export class FoV extends DOMElement {
|
|||||||
'<div class="aladin-monospace-text"></div>'])
|
'<div class="aladin-monospace-text"></div>'])
|
||||||
}
|
}
|
||||||
|
|
||||||
let el = Layout.horizontal({layout, tooltip: { content: 'FoV', position: {direction: "top"}}});
|
let el = Layout.horizontal({layout});
|
||||||
if (el.tooltip) {
|
if (el) {
|
||||||
el.tooltip.addClass('aladin-fov');
|
el.addClass('aladin-fov');
|
||||||
el.tooltip.addClass('aladin-dark-theme')
|
el.addClass('aladin-dark-theme')
|
||||||
}
|
}
|
||||||
|
|
||||||
super(el)
|
super(el)
|
||||||
|
|||||||
149
src/js/gui/Input/HiPSSearch.js
Normal file
149
src/js/gui/Input/HiPSSearch.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2013 - UDS/CNRS
|
||||||
|
// The Aladin Lite program is distributed under the terms
|
||||||
|
// of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// This file is part of Aladin Lite.
|
||||||
|
//
|
||||||
|
// Aladin Lite is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 3 of the License.
|
||||||
|
//
|
||||||
|
// Aladin Lite is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// The GNU General Public License is available in COPYING file
|
||||||
|
// along with Aladin Lite.
|
||||||
|
//
|
||||||
|
|
||||||
|
import { Box } from "../Widgets/Box.js";
|
||||||
|
import { Layout } from "../Layout.js";
|
||||||
|
import { ActionButton } from "../Widgets/ActionButton.js";
|
||||||
|
import { ALEvent } from "../../events/ALEvent.js";
|
||||||
|
/******************************************************************************
|
||||||
|
* Aladin Lite project
|
||||||
|
*
|
||||||
|
* File gui/HiPSSelector.js
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: Thomas Boch, Matthieu Baumann[CDS]
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// Copyright 2013 - UDS/CNRS
|
||||||
|
// The Aladin Lite program is distributed under the terms
|
||||||
|
// of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// This file is part of Aladin Lite.
|
||||||
|
//
|
||||||
|
// Aladin Lite is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 3 of the License.
|
||||||
|
//
|
||||||
|
// Aladin Lite is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// The GNU General Public License is available in COPYING file
|
||||||
|
// along with Aladin Lite.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Aladin Lite project
|
||||||
|
*
|
||||||
|
* File Location.js
|
||||||
|
*
|
||||||
|
* Author: Thomas Boch[CDS]
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import { Input } from "./../Widgets/Input.js";
|
||||||
|
|
||||||
|
export class HiPSSearch extends Input {
|
||||||
|
static HiPSList = {};
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
constructor(aladin, options) {
|
||||||
|
let self;
|
||||||
|
let layer = options && options.layer;
|
||||||
|
|
||||||
|
aladin.view.catalogCanvas.addEventListener('click', (e) => {
|
||||||
|
self.el.blur();
|
||||||
|
});
|
||||||
|
|
||||||
|
let prevKey = layer.name;
|
||||||
|
super({
|
||||||
|
name: 'HiPS search',
|
||||||
|
type: 'text',
|
||||||
|
classList: ['search'],
|
||||||
|
name: 'survey',
|
||||||
|
placeholder: "Survey keywords or url",
|
||||||
|
autocomplete: {options: Object.keys(HiPSSearch.HiPSList)},
|
||||||
|
title: layer.name,
|
||||||
|
actions: {
|
||||||
|
change(e) {
|
||||||
|
const key = e.target.value;
|
||||||
|
if (!key) {
|
||||||
|
self.update({value: prevKey, title: prevKey});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let image;
|
||||||
|
// A user can put an url
|
||||||
|
try {
|
||||||
|
image = new URL(key).href;
|
||||||
|
} catch(e) {
|
||||||
|
// Or he can select a HiPS from the list given
|
||||||
|
let hips = HiPSSearch.HiPSList[key]
|
||||||
|
//console.log("HIPS", key, hips)
|
||||||
|
if (hips) {
|
||||||
|
image = hips.id || hips.url || undefined;
|
||||||
|
} else {
|
||||||
|
// Finally if not found, interpret the input text value as the HiPS (e.g. ID)
|
||||||
|
image = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.el.blur();
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
prevKey = key;
|
||||||
|
aladin.setOverlayImageLayer(image, layer.layer);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*input(e) {
|
||||||
|
let value = e.target.value;
|
||||||
|
|
||||||
|
self.update({value, title: value})
|
||||||
|
}*/
|
||||||
|
},
|
||||||
|
value: layer.name,
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
this.addClass('aladin-HiPS-search')
|
||||||
|
|
||||||
|
self = this;
|
||||||
|
this.layer = layer;
|
||||||
|
|
||||||
|
this._addEventListeners(aladin);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAutocompletionList(options) {
|
||||||
|
this.update({autocomplete: {options}})
|
||||||
|
}
|
||||||
|
|
||||||
|
_addEventListeners(aladin) {
|
||||||
|
let self = this;
|
||||||
|
ALEvent.HIPS_LAYER_ADDED.listenedBy(aladin.aladinDiv, (e) => {
|
||||||
|
const layer = e.detail.layer;
|
||||||
|
if (layer.layer === self.layer.layer) {
|
||||||
|
let value = layer.name
|
||||||
|
self.update({value, title: value})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import { CooConversion } from "../CooConversion.js";
|
||||||
import { Coo } from "../libs/astro/coo.js";
|
import { Coo } from "../libs/astro/coo.js";
|
||||||
import { CooFrameEnum } from "../CooFrameEnum.js";
|
import { CooFrameEnum } from "../CooFrameEnum.js";
|
||||||
|
|
||||||
@@ -146,7 +146,15 @@ export class Location extends DOMElement {
|
|||||||
let param = e.detail;
|
let param = e.detail;
|
||||||
|
|
||||||
if (param.type === 'mouseout') {
|
if (param.type === 'mouseout') {
|
||||||
let [lon, lat] = aladin.getRaDec();
|
let radec = aladin.getRaDec();
|
||||||
|
// convert to the view frame
|
||||||
|
let lonlat = radec;
|
||||||
|
if (aladin.getFrame() === "Galactic") {
|
||||||
|
lonlat = CooConversion.J2000ToGalactic(radec)
|
||||||
|
}
|
||||||
|
|
||||||
|
let [lon, lat] = lonlat;
|
||||||
|
|
||||||
self.update({
|
self.update({
|
||||||
lon, lat,
|
lon, lat,
|
||||||
frame: aladin.view.cooFrame,
|
frame: aladin.view.cooFrame,
|
||||||
|
|||||||
@@ -67,6 +67,25 @@ export class Box extends DOMElement {
|
|||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
|
let close = this.options.close === false ? false : true;
|
||||||
|
if (close) {
|
||||||
|
new ActionButton({
|
||||||
|
size: 'small',
|
||||||
|
content: '❌',
|
||||||
|
//tooltip: {content: 'Close the window', position: {direction: 'bottom'}},
|
||||||
|
action(e) {
|
||||||
|
self._hide();
|
||||||
|
},
|
||||||
|
cssStyle: {
|
||||||
|
position: 'absolute',
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
}
|
||||||
|
}, this.el);
|
||||||
|
}
|
||||||
|
|
||||||
// Check for the title
|
// Check for the title
|
||||||
if (this.options.header) {
|
if (this.options.header) {
|
||||||
let header = this.options.header;
|
let header = this.options.header;
|
||||||
@@ -98,23 +117,11 @@ export class Box extends DOMElement {
|
|||||||
titleEl.style.cursor = 'move'
|
titleEl.style.cursor = 'move'
|
||||||
}
|
}
|
||||||
|
|
||||||
let closedEl = new ActionButton({
|
|
||||||
size: 'small',
|
|
||||||
content: '❌',
|
|
||||||
tooltip: {content: 'Close the window', position: {direction: 'bottom'}},
|
|
||||||
cssStyle: {
|
|
||||||
cursor: 'pointer',
|
|
||||||
},
|
|
||||||
action(e) {
|
|
||||||
self._hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Layout.horizontal({
|
Layout.horizontal({
|
||||||
cssStyle: {
|
cssStyle: {
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
},
|
},
|
||||||
layout: [draggableEl, titleEl, closedEl]
|
layout: [draggableEl, titleEl]
|
||||||
}, this.el);
|
}, this.el);
|
||||||
|
|
||||||
let separatorEl = document.createElement('div')
|
let separatorEl = document.createElement('div')
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export class Input extends DOMElement {
|
|||||||
}
|
}
|
||||||
this.el.appendChild(datalist);
|
this.el.appendChild(datalist);
|
||||||
|
|
||||||
this.el.autocomplete = 'on';
|
this.el.autocomplete = 'off';
|
||||||
} else {
|
} else {
|
||||||
this.el.autocomplete = autocomplete;
|
this.el.autocomplete = autocomplete;
|
||||||
}
|
}
|
||||||
@@ -199,6 +199,10 @@ export class Input extends DOMElement {
|
|||||||
this.el.name = this.options.name;
|
this.el.name = this.options.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.options.title) {
|
||||||
|
this.el.title = this.options.title;
|
||||||
|
}
|
||||||
|
|
||||||
this.el.classList.add('aladin-input');
|
this.el.classList.add('aladin-input');
|
||||||
this.el.classList.add('aladin-dark-theme');
|
this.el.classList.add('aladin-dark-theme');
|
||||||
|
|
||||||
|
|||||||
@@ -146,9 +146,9 @@ export class DOMElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const aladinDiv = options && options.aladin && options.aladin.aladinDiv;
|
const aladinDiv = options && options.aladin && options.aladin.aladinDiv;
|
||||||
if (!aladinDiv) {
|
let innerWidth = aladinDiv && aladinDiv.offsetWidth;
|
||||||
return;
|
let innerHeight = aladinDiv && aladinDiv.offsetHeight;
|
||||||
}
|
|
||||||
|
|
||||||
let left, top, bottom, right;
|
let left, top, bottom, right;
|
||||||
let x, y;
|
let x, y;
|
||||||
@@ -156,11 +156,8 @@ export class DOMElement {
|
|||||||
// handle the anchor/dir case with higher priority
|
// handle the anchor/dir case with higher priority
|
||||||
const {offsetWidth, offsetHeight} = el;
|
const {offsetWidth, offsetHeight} = el;
|
||||||
|
|
||||||
const innerWidth = aladinDiv.offsetWidth;
|
|
||||||
const innerHeight = aladinDiv.offsetHeight;
|
|
||||||
|
|
||||||
// take on less priority the left and top
|
// take on less priority the left and top
|
||||||
if (options && (options.left || options.top || options.right || options.bottom)) {
|
if (options && (options.left !== undefined || options.top !== undefined || options.right !== undefined || options.bottom !== undefined)) {
|
||||||
el.style.position = 'absolute';
|
el.style.position = 'absolute';
|
||||||
|
|
||||||
if (options.top !== undefined) {
|
if (options.top !== undefined) {
|
||||||
@@ -177,7 +174,7 @@ export class DOMElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof top === 'number') {
|
if (typeof top === 'number') {
|
||||||
if (top + offsetHeight >= innerHeight) {
|
if (innerHeight && top + offsetHeight >= innerHeight) {
|
||||||
y = '-' + (top + offsetHeight - innerHeight) + 'px';
|
y = '-' + (top + offsetHeight - innerHeight) + 'px';
|
||||||
} else if (top < 0) {
|
} else if (top < 0) {
|
||||||
y = Math.abs(top) + 'px';
|
y = Math.abs(top) + 'px';
|
||||||
@@ -189,7 +186,7 @@ export class DOMElement {
|
|||||||
bottom = bottom + 'px';
|
bottom = bottom + 'px';
|
||||||
}
|
}
|
||||||
if (typeof left === 'number') {
|
if (typeof left === 'number') {
|
||||||
if (left + offsetWidth > innerWidth) {
|
if (innerWidth && left + offsetWidth > innerWidth) {
|
||||||
x = '-' + (left + offsetWidth - innerWidth) + 'px';
|
x = '-' + (left + offsetWidth - innerWidth) + 'px';
|
||||||
} else if (left < 0) {
|
} else if (left < 0) {
|
||||||
x = Math.abs(left) + 'px';
|
x = Math.abs(left) + 'px';
|
||||||
|
|||||||
Reference in New Issue
Block a user