From d3301d3a1e33a62fa3f77a646e546d881d916650 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 13 Jan 2025 14:58:56 +0100 Subject: [PATCH 01/22] docs: switch logos' txt to path rather than font (more robust for svg readers) --- docs/_static/ipyaladin_dark.svg | 50 ++++++++++++---------------- docs/_static/ipyaladin_light.svg | 56 ++++++++++++-------------------- 2 files changed, 40 insertions(+), 66 deletions(-) diff --git a/docs/_static/ipyaladin_dark.svg b/docs/_static/ipyaladin_dark.svg index 1521f60e..a0e62765 100644 --- a/docs/_static/ipyaladin_dark.svg +++ b/docs/_static/ipyaladin_dark.svg @@ -27,10 +27,10 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="11.313709" - inkscape:cx="23.643883" - inkscape:cy="0.61871843" + inkscape:cx="23.643882" + inkscape:cy="0.70710675" inkscape:window-width="2560" - inkscape:window-height="1368" + inkscape:window-height="1412" inkscape:window-x="2560" inkscape:window-y="0" inkscape:window-maximized="1" @@ -239,34 +239,24 @@ id="circle72" cx="110.3422" cy="145.58806" - r="0.14031649" />A l a d i niPy + style="font-size:8px;line-height:100%;font-family:'Mukti Narrow';-inkscape-font-specification:'Mukti Narrow, Normal';letter-spacing:-1.51px;word-spacing:0px;white-space:pre;fill:#8e8e8e;stroke:#ffffff;stroke-width:0.188976;stroke-linejoin:bevel" + transform="matrix(0.26458333,0,0,0.26458333,107.57034,149.41287)" + aria-label="y" /> diff --git a/docs/_static/ipyaladin_light.svg b/docs/_static/ipyaladin_light.svg index a3bf5464..dcabe617 100644 --- a/docs/_static/ipyaladin_light.svg +++ b/docs/_static/ipyaladin_light.svg @@ -11,8 +11,8 @@ inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)" sodipodi:docname="ipyaladin_light.svg" inkscape:export-filename="ipyaladin_light.png" - inkscape:export-xdpi="300" - inkscape:export-ydpi="300" + inkscape:export-xdpi="2000" + inkscape:export-ydpi="2000" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" @@ -31,7 +31,7 @@ inkscape:cy="12.551145" inkscape:window-width="2560" inkscape:window-height="1368" - inkscape:window-x="2560" + inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1" />A l a d i niPy + r="0.14031649" /> From 2b3de29ce6a6c7ddc3bdf8dbc07abfe3ba579043 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 15 Jan 2025 11:25:59 +0100 Subject: [PATCH 02/22] docs: add upstream fix into changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 496c9b09..d51844c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## Fixed + +- footprints will now appear immediately after adding them, without requiring an other + event (fixed in https://github.com/cds-astro/aladin-lite/pull/218) + ## [0.5.2] ### Fixed From a5cdbbaac0c0d0ba9299fd0e6f225bd09cba58ea Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 5 Mar 2025 09:48:52 +0100 Subject: [PATCH 03/22] maint: update supported python versions --- .github/workflows/python-tests.yml | 5 ++--- CHANGELOG.md | 4 ++++ pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index daeb660a..b220008c 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8, 3.12] + python-version: [3.9, 3.13] steps: - name: "Checkout branch" uses: actions/checkout@v4 @@ -22,8 +22,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: "Python codestyle" + - name: "Pytest" run: | pip install ".[dev]" - pip install pytest pytest . diff --git a/CHANGELOG.md b/CHANGELOG.md index d51844c7..68107890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## Changed + +- supported python versions are now 3.9 - 3.13 [#141] + ## Fixed - footprints will now appear immediately after adding them, without requiring an other diff --git a/pyproject.toml b/pyproject.toml index 486941e9..ae75b8ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] dependencies = ["anywidget", "astropy"] readme = "README.md" license = "BSD-3-Clause" -requires-python = ">=3.8" +requires-python = ">=3.9" [project.optional-dependencies] dev = ["pytest", "watchfiles", "jupyterlab", "ruff", "nbconvert"] From 3a83049eaeaf5dd07d73a7631bfbba81fd9a9d0c Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 5 Mar 2025 10:13:41 +0100 Subject: [PATCH 04/22] maint: upgrade aladin lite version --- CHANGELOG.md | 1 + README.md | 2 +- js/aladin_lite.js | 2 +- src/ipyaladin/__about__.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68107890..f35be927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed - supported python versions are now 3.9 - 3.13 [#141] +- aladin-lite version is now 3.6.1-beta [#141] ## Fixed diff --git a/README.md b/README.md index 574a0701..f97dc44e 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Correspondence table between ipyaladin versions and Aladin Lite versions: | ipyaladin | Aladin-Lite | | ---------- | ----------- | -| Unreleased | 3.5.1-beta | +| Unreleased | 3.6.1-beta | | 0.5.2 | 3.5.1-beta | | 0.5.1 | 3.5.1-beta | | 0.5.0 | 3.5.1-beta | diff --git a/js/aladin_lite.js b/js/aladin_lite.js index e6fe8e63..d40545ab 100644 --- a/js/aladin_lite.js +++ b/js/aladin_lite.js @@ -1,3 +1,3 @@ -import A from "https://esm.sh/aladin-lite@3.5.1-beta"; +import A from "https://esm.sh/aladin-lite@3.6.1-beta"; export default A; diff --git a/src/ipyaladin/__about__.py b/src/ipyaladin/__about__.py index 7a9c1a68..caadf290 100644 --- a/src/ipyaladin/__about__.py +++ b/src/ipyaladin/__about__.py @@ -1,2 +1,2 @@ __version__ = "0.5.2" -__aladin_lite_version__ = "3.5.1-beta" +__aladin_lite_version__ = "3.6.1-beta" From 076afb5fcc408b44a2113f0723e6fb88ca36a699 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 5 Mar 2025 10:16:16 +0100 Subject: [PATCH 05/22] maint: switch to more recent astroquery version --- examples/08_Rectangular-selection.ipynb | 40 ++++++++----------------- pyproject.toml | 2 +- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/examples/08_Rectangular-selection.ipynb b/examples/08_Rectangular-selection.ipynb index 94782833..3de73b47 100644 --- a/examples/08_Rectangular-selection.ipynb +++ b/examples/08_Rectangular-selection.ipynb @@ -79,12 +79,12 @@ " The sources selected in the Aladin widget.\n", " \"\"\"\n", " s = ''\n", - " s += \"\"\n", + " s += \"\"\n", " for source in sources:\n", " s += \"\" % (\n", - " source[\"data\"][\"MAIN_ID\"],\n", - " source[\"data\"][\"RA\"],\n", - " source[\"data\"][\"DEC\"],\n", + " source[\"data\"][\"main_id\"],\n", + " source[\"data\"][\"ra\"],\n", + " source[\"data\"][\"dec\"],\n", " )\n", " s += \"
MAIN_IDRADEC
main_idradec
%s%s%s
\"\n", " table_info.value = s\n", @@ -92,32 +92,16 @@ "\n", "aladin.set_listener(\"select\", process_result)" ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.3" }, - "vscode": { - "interpreter": { - "hash": "85bb43f988bdbdc027a50b6d744a62eda8a76617af1f4f9b115d38242716dbac" - } + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } - }, + ], + "metadata": {}, "nbformat": 4, "nbformat_minor": 4 } diff --git a/pyproject.toml b/pyproject.toml index ae75b8ad..944f5a63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ requires-python = ">=3.9" [project.optional-dependencies] dev = ["pytest", "watchfiles", "jupyterlab", "ruff", "nbconvert"] -recommended = ["mocpy", "regions", "astroquery"] +recommended = ["mocpy", "regions", "astroquery>=0.4.8"] notebooks = ["requests"] docs = ["autoapi", "jupyterlab", From a8373bf242f1b6fcdbc53e896aaae1f70779b40e Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Mon, 10 Mar 2025 04:49:09 -0400 Subject: [PATCH 06/22] enhancement: accepting iterables overlay stcs (#140) * initial changes to allow for iterables beyond lists * Updated changelog * Separating out stcs string parsing and incorporating new tests * incorporating suggested changes to use monkeypatch for testing * removing unused monkeypatch from noniterable testing * adding frame to test iterables for future compatability --- CHANGELOG.md | 1 + src/ipyaladin/widget.py | 17 +++++----- src/tests/test_aladin.py | 72 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f35be927..8459b215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - supported python versions are now 3.9 - 3.13 [#141] - aladin-lite version is now 3.6.1-beta [#141] +- `add_graphic_overlay_from_stcs` accepts iterables besides lists [#140] ## Fixed diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index db2bdd37..5661d361 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -5,7 +5,7 @@ It allows to display astronomical images and catalogs in an interactive way. """ -from collections.abc import Callable +from collections.abc import Callable, Iterable import functools from json import JSONDecodeError import io @@ -838,14 +838,14 @@ def add_graphic_overlay_from_region( @widget_should_be_loaded def add_overlay_from_stcs( - self, stc_string: Union[List[str], str], **overlay_options: any + self, stc_string: Union[Iterable[str], str], **overlay_options: any ) -> None: """Add an overlay layer defined by an STC-S string. Parameters ---------- - stc_string : str, list[str] - The STC-S string or a list of STC-S strings. + stc_string : str, Iterable[str] + The STC-S string or an iterable of STC-S strings. overlay_options : keyword arguments The overlay options for all the STC-S strings See `Aladin Lite's graphic overlay options @@ -863,14 +863,14 @@ def add_overlay_from_stcs( @widget_should_be_loaded def add_graphic_overlay_from_stcs( - self, stc_string: Union[List[str], str], **overlay_options: any + self, stc_string: Union[Iterable[str], str], **overlay_options: any ) -> None: """Add an overlay layer defined by an STC-S string. Parameters ---------- - stc_string : str, list[str] - The STC-S string or a list of STC-S strings. + stc_string : str, Iterable[str] + The STC-S string or an iterable of STC-S strings. overlay_options : keyword arguments The overlay options for all the STC-S strings. See `Aladin Lite's graphic overlay options @@ -882,7 +882,7 @@ def add_graphic_overlay_from_stcs( object. """ - region_list = [stc_string] if not isinstance(stc_string, list) else stc_string + region_list = [stc_string] if isinstance(stc_string, str) else stc_string regions_infos = [ { @@ -892,6 +892,7 @@ def add_graphic_overlay_from_stcs( } for region_element in region_list ] + self.send( { "event_name": "add_overlay", diff --git a/src/tests/test_aladin.py b/src/tests/test_aladin.py index abb67976..1fb587a4 100644 --- a/src/tests/test_aladin.py +++ b/src/tests/test_aladin.py @@ -1,9 +1,11 @@ -from typing import Callable, Dict +from typing import Callable, Dict, Iterable, Union from astropy.coordinates import Angle, SkyCoord, Longitude, Latitude import astropy.units as u +from astropy.table import Column import numpy as np import pytest +from unittest.mock import Mock from ipyaladin import Aladin from ipyaladin.utils._coordinate_parser import _parse_coordinate_string @@ -130,3 +132,71 @@ def test_aladin_angle_fov_set(angle: float) -> None: angle_fov = Angle(angle, unit="deg") aladin.fov = angle_fov assert aladin.fov.deg == angle_fov.deg + + +test_stcs_iterables = [ + "CIRCLE ICRS 258.93205686 43.13632863 0.625", + [ + "POLYGON ICRS 257 38 261.005016 50.011125 278.305761 46.00127 257 38", + "CIRCLE ICRS 259.29230291 42.63394602 0.625", + ], + "POLYGON ICRS 259.254026 43.196761 259 43 259.202 43.118 259.254026 43.196761", + ( + "POLYGON ICRS 257 38 261.005016 50.011125 278.305761 46.00127 257 38", + "CIRCLE ICRS 259.29230291 42.63394602 0.625", + ), + Column( + name="s_regions", + data=[ + "CIRCLE ICRS 259.29230291 42.63394602 0.625", + "CIRCLE ICRS 259.22668619 42.76082126 0.625", + "CIRCLE ICRS 258.93205686 43.13632863 0.625", + ], + ), +] + + +@pytest.mark.parametrize("stcs_strings", test_stcs_iterables) +def test_add_graphic_overlay_from_stcs_iterables( + monkeypatch: Callable, + stcs_strings: Union[Iterable[str], str], +) -> None: + """Test generating region overlay info from iterable STC-S string(s). + + Parameters + ---------- + stcs_strings : Union[Iterable[str], str] + The stcs strings to create region overlay info from. + + """ + mock_send = Mock() + monkeypatch.setattr(Aladin, "send", mock_send) + aladin.add_graphic_overlay_from_stcs(stcs_strings) + regions_info = mock_send.call_args[0][0]["regions_infos"] + assert isinstance(regions_info, list) + assert regions_info[0]["infos"]["stcs"] in stcs_strings + + +test_stcs_noniterables = [ + 0, + 1000, + -100, + np.nan, +] + + +@pytest.mark.parametrize("stcs_strings", test_stcs_noniterables) +def test_add_graphic_overlay_from_stcs_noniterables( + stcs_strings: Union[Iterable[str], str], +) -> None: + """Test generating region overlay info from iterable STC-S string(s). + + Parameters + ---------- + stcs_strings : non-Iterables + The stcs strings to create region overlay info from. + + """ + with pytest.raises(TypeError) as info: + aladin.add_graphic_overlay_from_stcs(stcs_strings) + assert info.type is TypeError From ff21e552fce59dbca713d72521bcb269e3c0982f Mon Sep 17 00:00:00 2001 From: Fabio Trabucchi Date: Tue, 18 Mar 2025 09:26:59 -0400 Subject: [PATCH 07/22] Addressed issue in ipyaladin when height=-1 is provided to Aladin (#142) * Addressed issue in ipyaladin when height=-1 is provided to Aladin * PR suggestions --- CHANGELOG.md | 2 ++ js/widget.css | 8 ++++++++ js/widget.js | 3 +++ 3 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8459b215..c77dfb1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - footprints will now appear immediately after adding them, without requiring an other event (fixed in https://github.com/cds-astro/aladin-lite/pull/218) +- when Aladin is initialized with `Aladin(height=-1)` it correctly occupy 100% of its + `
` container [#142] ## [0.5.2] diff --git a/js/widget.css b/js/widget.css index bd967b1f..98371f5d 100644 --- a/js/widget.css +++ b/js/widget.css @@ -10,3 +10,11 @@ .aladin-widget .aladin-measurement-div { max-height: 100px; } + +.lm-Widget.aladin-lite-lm-container { + /* Style fix for the aladin widget container. + The aladin widget is not being able to render to 100% height when initialized with + height=-1 in the constructor + see widget.js:13 */ + height: 100%; +} diff --git a/js/widget.js b/js/widget.js index 92a5d29e..f9dd91b3 100644 --- a/js/widget.js +++ b/js/widget.js @@ -9,6 +9,9 @@ import { import A from "./aladin_lite"; function initAladinLite(model, el) { + // Add 'aladin-lite-lm-container' class to the div container to apply the CSS styles in widget.css + el.classList.add("aladin-lite-lm-container"); + setDivNumber(divNumber + 1); let initFromPython = model.get("_init_options"); let initOptions = {}; From ba7b2be34f58827ae79ebe8f9c1bd767cd9fcaa8 Mon Sep 17 00:00:00 2001 From: ManonMarchand Date: Wed, 7 Aug 2024 10:33:40 +0200 Subject: [PATCH 08/22] feat: draw shape errors in tables Co-authored-by: Xen0Xys --- CHANGELOG.md | 8 ++ examples/04_Importing_Tables.ipynb | 94 ++++++++++++++++------ js/models/message_handler.js | 42 +++++++++- src/ipyaladin/__init__.py | 3 +- src/ipyaladin/elements/error_shape.py | 107 ++++++++++++++++++++++++++ src/ipyaladin/widget.py | 73 +++++++++++++++--- src/tests/test_elements.py | 11 +++ 7 files changed, 302 insertions(+), 36 deletions(-) create mode 100644 src/ipyaladin/elements/error_shape.py create mode 100644 src/tests/test_elements.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c77dfb1c..b29eb962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## Added + +- when adding tables to `ipyaladin` with `add_table`, the shape argument now accepts + `CircleError` and `EllipseError` object on top of the usual strings "square", + "circle", "plus", "cross", "rhomb", and "triangle". These new shapes draw ellipses or + circles according to the error column(s) associated with each source coordinates in + the table [#110] + ## Changed - supported python versions are now 3.9 - 3.13 [#141] diff --git a/examples/04_Importing_Tables.ipynb b/examples/04_Importing_Tables.ipynb index 7d526c52..39f24ea2 100644 --- a/examples/04_Importing_Tables.ipynb +++ b/examples/04_Importing_Tables.ipynb @@ -1,15 +1,12 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "# Display tables resulting from an astroquery request\n", + "# Adding tables to the view\n", "\n", - "This example implements the addition of two tables :\n", - "- one resulting from an astroquery request on the [Simbad](https://simbad.cds.unistra.fr/simbad/ \"https://simbad.cds.unistra.fr/simbad/\") database\n", - "- the other is a table created locally" + "In this notebook, we add tables to the `ipyaladin` view." ] }, { @@ -18,7 +15,7 @@ "metadata": {}, "outputs": [], "source": [ - "from ipyaladin import Aladin\n", + "from ipyaladin import Aladin, CircleError, EllipseError\n", "from astropy.table import QTable\n", "import astropy.units as u\n", "from astroquery.simbad import Simbad" @@ -29,7 +26,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## From a query" + "## Table from a database\n", + "\n", + "Let's query the [SIMBAD](https://simbad.cds.unistra.fr/simbad/ \"https://simbad.cds.unistra.fr/simbad/\") database around the Crab nebula." ] }, { @@ -42,6 +41,13 @@ "table" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we instantiate an `ipyaladin` view around the nebula." + ] + }, { "cell_type": "code", "execution_count": null, @@ -52,21 +58,51 @@ "aladin" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In `add_table`, the shape argument can take the values \"square\", \"circle\", \"plus\", \"cross\", \"rhomb\", or \"triangle\" for the simple shapes. \n", + "\n", + "The two specific classes of error shapes `EllipseError` and `CircleError` adapt the shapes drawn to the values of the errors around the coordinates.\n", + "\n", + "SIMBAD gives errors as ellipses, so let's use an `EllipseError` shape:" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "aladin.add_table(table, shape=\"rhomb\", color=\"lightskyblue\", source_size=20)\n", - "# This line also works with camelCase instead of snake_case: sourceSize=20" + "aladin.add_table(\n", + " table,\n", + " shape=EllipseError(\n", + " maj_axis=\"coo_err_maj\",\n", + " min_axis=\"coo_err_min\",\n", + " angle=\"coo_err_angle\",\n", + " default_shape=\"cross\",\n", + " ),\n", + " color=\"lightskyblue\",\n", + " source_size=20, # will only affect the sources which fallback to the default shape\n", + " name=\"SIMBAD query\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you zoom in the view, you'll remark that the sources which had error information appear as ellipses. If the spahe would be smaller than a pixel at maximum zoom or if there is no information in the error columns, then the sources appear with the fallback shape. `default_shape` should be one of the strings allowed in `shape`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Display Astropy table created from scratch" + "## Displaying a QTable\n", + "\n", + "Let's create a table from scratch and add it to the view. We will draw `CircleError` shapes this time." ] }, { @@ -75,29 +111,37 @@ "metadata": {}, "outputs": [], "source": [ - "ra = [83.63451584700, 83.61368056017, 83.58780251600]\n", - "dec = [22.05652591227, 21.97517807639, 21.99277764451]\n", - "name = [\n", - " \"Gaia EDR3 3403818589184411648\",\n", - " \"Gaia EDR3 3403817661471500416\",\n", - " \"Gaia EDR3 3403817936349408000\",\n", - "]\n", - "parallax = [1.7703, 0.5112, 0.3735] * u.mas\n", - "\n", "t = QTable(\n", - " [ra, dec, name, parallax],\n", - " names=(\"ra\", \"dec\", \"name\", \"parallax\"),\n", + " {\n", + " \"error\": [0.005, 0.002, 0.003] * u.deg,\n", + " \"coo1\": [83.63451584700, 83.61368056017, 83.58780251600] * u.deg,\n", + " \"coo2\": [22.05652591227, 21.97517807639, 21.99277764451] * u.deg,\n", + " \"name\": [\"Source 1\", \"Source 2\", \"Source 3\"],\n", + " \"parallax\": [1.7703, 0.5112, 0.3735] * u.mas,\n", + " },\n", " meta={\"name\": \"my_sample_table\"},\n", + ")\n", + "\n", + "aladin.add_table(\n", + " t,\n", + " name=t.meta[\"name\"],\n", + " shape=CircleError(\n", + " radius=\"error\",\n", + " probability_threshold=0.989, # roughly 3 sigma\n", + " ),\n", + " color=\"pink\",\n", + " ra_field=\"coo1\",\n", + " dec_field=\"coo2\",\n", ")" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "aladin.add_table(t)" + "Note that we used unconventional column names for the coordinates fields here. In this case, we can specify the column names where Aladin Lite should read the coordinates via `ra_field` and `dec_field`.\n", + "\n", + "We used a very high probability threshold. This corresponds to roughly 3 sigma in the drawn circle." ] } ], diff --git a/js/models/message_handler.js b/js/models/message_handler.js index 97f30e45..09e1af1e 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -157,13 +157,53 @@ export default class MessageHandler { handleAddTable(msg, buffers) { const options = convertOptionNamesToCamelCase(msg["options"] || {}); + const circleOptions = convertOptionNamesToCamelCase( + options.circleError || {}, + ); + const ellipseOptions = convertOptionNamesToCamelCase( + options.ellipseError || {}, + ); const buffer = buffers[0].buffer; const decoder = new TextDecoder("utf-8"); const blob = new Blob([decoder.decode(buffer)]); const url = URL.createObjectURL(blob); + options.onClick = "showTable"; + if (Object.keys(circleOptions).length != 0) { + options.shape = (source) => { + if (source.data[circleOptions.radius]) { + return A.circle( + source.ra, + source.dec, + source.data[circleOptions.radius] * circleOptions.conversionRadius, + options, + ); + } + // return string shape (remove comment when aladin lite accepts strings as returns) + }; + } + if (Object.keys(ellipseOptions).length != 0) { + options.shape = (source) => { + if ( + source.data[ellipseOptions.majAxis] & + source.data[ellipseOptions.minAxis] + ) { + return A.ellipse( + source.ra, + source.dec, + source.data[ellipseOptions.majAxis] * + ellipseOptions.conversionMajAxis, + source.data[ellipseOptions.minAxis] * + ellipseOptions.conversionMinAxis, + source.data[ellipseOptions.angle] * ellipseOptions.conversionAngle, + options, + ); + } + // return string shape (remove comment when aladin lite accepts strings as returns) + }; + } A.catalogFromURL( url, - Object.assign(options, { onClick: "showTable" }), + options, (catalog) => { this.aladin.addCatalog(catalog); }, diff --git a/src/ipyaladin/__init__.py b/src/ipyaladin/__init__.py index eba7d087..3c9ac234 100644 --- a/src/ipyaladin/__init__.py +++ b/src/ipyaladin/__init__.py @@ -1,5 +1,6 @@ """Top-level package for ipyaladin.""" -from .widget import Aladin # noqa: F401 +from .elements.error_shape import CircleError, EllipseError # noqa: F401 from .elements.marker import Marker # noqa: F401 +from .widget import Aladin # noqa: F401 from .__about__ import __version__, __aladin_lite_version__ # noqa: F401 diff --git a/src/ipyaladin/elements/error_shape.py b/src/ipyaladin/elements/error_shape.py new file mode 100644 index 00000000..ab98c067 --- /dev/null +++ b/src/ipyaladin/elements/error_shape.py @@ -0,0 +1,107 @@ +from dataclasses import dataclass +import math +from typing import Iterable, Optional + +from astropy.coordinates import Angle +import astropy.units as u + + +def _error_radius_conversion_factor( + column_unit: u.Unit, probability: Optional[float] = None +) -> Iterable: + """Return the product of Mahalanobis distance and unit conversion factor. + + Parameters + ---------- + column: `~astropy.units.core.Unit` + The unit of the column containing the standard deviations. Should be an + angle unit. + probability: float, optional + Probability that will be enclosed in the error shape. + + Returns + ------- + float + """ + unit_factor = Angle(1 * column_unit).to("deg").value + if probability: + mahalanobis_distance = math.sqrt(-2 * math.log(1 - probability)) + else: + mahalanobis_distance = 1 + return unit_factor * mahalanobis_distance + + +@dataclass +class CircleError: + r"""Circular error shape, accepted as `~ipyaladin.Aladin.add_table`'s shape. + + Attributes + ---------- + radius: str + Name of the column containing the radius of the error circle. The + column's unit should be an angle-like unit. + default_shape: str, default: "square" + Can be "square", "circle", "plus", "cross", "rhomb", "triangle". This will be + the fallback shape if the radius in None for a source. + probability_threshold: float + The confidence level contained in the drawn circle. Should be in ]0; 1[. + When this is not given, the 1 sigma contour is plotted. + + Notes + ----- + Correspondence table between sigmas and probability threshold: + + ================= ====================== + :math::`n_\sigma` probability + ================= ====================== + 1 :math::`1 - e^{-1/2}` + 2 :math::`1 - e^{-2}` + 3 :math::`1 - e^{-9/2}` + ================= ====================== + """ + + radius: str + default_shape: str = "square" + probability_threshold: float = 0 + + +@dataclass +class EllipseError: + r"""Elliptical error shape, accepted as `~ipyaladin.Aladin.add_table`'s shape. + + Attributes + ---------- + maj_axis: str + Name of the column containing the major axis of the error ellipse. The + column's unit should be an angle-like unit. + min_axis: str + Name of the column containing the minor axis of the error ellipse. The + column's unit should be an angle-like unit. + angle: str + Name of the column containing the angle of the error ellipse. The + column's unit should be an angle-like unit. + default_shape: str + Can be "square", "circle", "plus", "cross", "rhomb", "triangle". This will be + the fallback shape if one of the ellipse's axis in None for a source. + probability_threshold: float + The confidence level contained in the drawn circle. Should be in ]0; 1[. + When this is not given, the 1 sigma contour is plotted. + + Notes + ----- + Correspondence table between sigmas and probability threshold: + + ================= ====================== + :math::`n_\sigma` probability + ================= ====================== + 1 :math::`1 - e^{-1/2}` + 2 :math::`1 - e^{-2}` + 3 :math::`1 - e^{-9/2}` + ================= ====================== + """ + + maj_axis: str + min_axis: str + angle: str + default_shape: str = "square" + probability_threshold: float = 0 diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 5661d361..d930406b 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -6,20 +6,24 @@ """ from collections.abc import Callable, Iterable -import functools from json import JSONDecodeError +import functools import io import pathlib from pathlib import Path import time from typing import ClassVar, Dict, Final, List, Optional, Tuple, Union + +try: # drop this clause when we drop python 3.9 + from typing_extensions import TypeAlias +except ImportError: + from typing import TypeAlias import warnings import anywidget from astropy.coordinates import SkyCoord, Angle, Longitude, Latitude from astropy.coordinates.name_resolve import NameResolveError -from astropy.table.table import QTable -from astropy.table import Table +from astropy.table.table import QTable, Table from astropy.io import fits as astropy_fits from astropy.io.fits import HDUList from astropy.wcs import WCS @@ -28,6 +32,11 @@ from .utils.exceptions import WidgetReducedError, WidgetNotReadyError from .utils._coordinate_parser import _parse_coordinate_string +from .elements.error_shape import ( + CircleError, + EllipseError, + _error_radius_conversion_factor, +) from .elements.marker import Marker try: @@ -56,7 +65,7 @@ Any, ) -SupportedRegion = Union[ +SupportedRegion: TypeAlias = Union[ List[ Union[ CircleSkyRegion, @@ -732,23 +741,69 @@ def add_moc_from_dict( self.add_moc(moc_dict, **moc_options) @widget_should_be_loaded - def add_table(self, table: Union[QTable, Table], **table_options: any) -> None: + def add_table( + self, + table: Union[QTable, Table], + *, + shape: Union[str, CircleError, EllipseError] = "cross", + **table_options: any, + ) -> None: """Load a table into the widget. + The extra parameters allow to draw either circles which radii correspond to the + error estimation, or ellipses which major axis, minor axis, and angles + correspond to the coordinates error. + Parameters ---------- table : `~astropy.table.table.QTable` or `~astropy.table.table.Table` table that must contain coordinates information - table_options - Keyword arguments. The possible values are documented in `Aladin Lite's - table options + shape : str | `~ipyaladin.CircleError` | `~ipyaladin.EllipseError` + The shape to draw for each source. It accepts the strings "square", + "circle", "plus", "cross", "rhomb", and "triangle" as well as the two + specific classes `ipyaladin.CircleError` and `ipyaladin.EllipseError` + that adapt the size of the drawn shapes (circles or ellipses) to error + columns. + See example notebook `04_Importing_Tables`. + **table_options + Keyword arguments. They mostly give control on the visual aspects of the + table. If the coordinates cannot be detected automatically, then you can + give the appropriate column names in the 'ra_field' and 'dec_field' + arguments. + The possible values are documented in `Aladin Lite's table options `_ See Also -------- add_markers: adds markers with a popup window when clicked - """ + shape = table_options.get("shape") + if isinstance(shape, CircleError): + table_options["circle_error"] = { + "radius": shape.radius, + "conversion_radius": _error_radius_conversion_factor( + table[shape.radius].unit, shape.probability_threshold + ), + } + table_options["shape"] = shape.default_shape + elif isinstance(shape, EllipseError): + table_options["ellipse_error"] = { + "maj_axis": shape.maj_axis, + "min_axis": shape.min_axis, + "angle": shape.angle, + "conversion_angle": _error_radius_conversion_factor( + table[shape.angle].unit + ), + "conversion_maj_axis": _error_radius_conversion_factor( + table[shape.maj_axis].unit, shape.probability_threshold + ), + "conversion_min_axis": _error_radius_conversion_factor( + table[shape.min_axis].unit, shape.probability_threshold + ), + } + table_options["shape"] = shape.default_shape + else: + table_options["shape"] = shape table_bytes = io.BytesIO() table.write(table_bytes, format="votable") self.send( diff --git a/src/tests/test_elements.py b/src/tests/test_elements.py new file mode 100644 index 00000000..887213ba --- /dev/null +++ b/src/tests/test_elements.py @@ -0,0 +1,11 @@ +import math + +import astropy.units as u +import numpy as np + +from ipyaladin.elements.error_shape import _error_radius_conversion_factor + + +def test_error_radius_conversion_factor() -> None: + # degrees and 1 sigma should give 1 + assert np.isclose(_error_radius_conversion_factor(u.deg, 1 - math.exp(-1 / 2)), 1) From bf5d17d46a4dbc121c116e262db4a78a6d6f603c Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Fri, 21 Mar 2025 16:46:10 +0100 Subject: [PATCH 09/22] maint: run npm audit fix --- package-lock.json | 276 +++++++++++++++++++++++++++------------------- package.json | 5 +- 2 files changed, 166 insertions(+), 115 deletions(-) diff --git a/package-lock.json b/package-lock.json index 05dc5a8e..d7b1cd27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "esbuild": "^0.25.0", "husky": "^8.0.0", "lint-staged": "^15.2.2", - "prettier": "3.2.5", + "prettier": "^3.2.5", "trailing-whitespaces": "^1.0.8" } }, @@ -2855,22 +2855,27 @@ } }, "node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2883,6 +2888,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2919,10 +2925,11 @@ } }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -2931,15 +2938,16 @@ } }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, + "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2950,6 +2958,7 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" @@ -3079,15 +3088,17 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/compute-gcd": { @@ -3132,10 +3143,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3393,12 +3405,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3483,10 +3496,11 @@ } }, "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" }, "node_modules/entities": { "version": "4.5.0", @@ -3500,6 +3514,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/esbuild": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", @@ -3566,7 +3593,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/execa": { "version": "8.0.1", @@ -3690,10 +3718,11 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3845,6 +3874,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4012,30 +4042,35 @@ } }, "node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lint-staged": { - "version": "15.2.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz", - "integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==", - "dev": true, - "dependencies": { - "chalk": "5.3.0", - "commander": "11.1.0", - "debug": "4.3.4", - "execa": "8.0.1", - "lilconfig": "3.0.0", - "listr2": "8.0.1", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.4" + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.0.tgz", + "integrity": "sha512-WyCzSbfYGhK7cU+UuDDkzUiytbfbi0ZdPy2orwtM75P3WTtQBzmG40cCxIa8Ii2+XjfxzLH6Be46tUfWS85Xfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1", + "commander": "^13.1.0", + "debug": "^4.4.0", + "execa": "^8.0.1", + "lilconfig": "^3.1.3", + "listr2": "^8.2.5", + "micromatch": "^4.0.8", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.7.0" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -4048,16 +4083,17 @@ } }, "node_modules/listr2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz", - "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.0", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, "engines": { @@ -4089,14 +4125,15 @@ "dev": true }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -4112,6 +4149,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", "dev": true, + "license": "MIT", "dependencies": { "get-east-asian-width": "^1.0.0" }, @@ -4127,6 +4165,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -4178,12 +4217,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -4202,6 +4242,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4224,15 +4277,16 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -4240,6 +4294,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -4460,6 +4515,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -4638,51 +4694,38 @@ "dev": true }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4694,10 +4737,11 @@ } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", - "dev": true + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "2.7.1", @@ -4819,6 +4863,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -4858,10 +4903,11 @@ } }, "node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -4879,6 +4925,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5633,6 +5680,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -5702,10 +5750,14 @@ } }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } diff --git a/package.json b/package.json index bf56a204..95cf4c33 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "esbuild": "^0.25.0", "husky": "^8.0.0", "lint-staged": "^15.2.2", - "prettier": "3.2.5", + "prettier": "^3.2.5", "trailing-whitespaces": "^1.0.8" }, "lint-staged": { @@ -25,7 +25,6 @@ "ruff format", "ruff check --fix" ], - "*ipynb": - "python3 -m jupyter nbconvert --clear-output --ClearMetadataPreprocessor.enabled=True --ClearMetadataPreprocessor.preserve_nb_metadata_mask=nbsphinx --inplace" + "*ipynb": "python3 -m jupyter nbconvert --clear-output --ClearMetadataPreprocessor.enabled=True --ClearMetadataPreprocessor.preserve_nb_metadata_mask=nbsphinx --inplace" } } From b09d22ee1363adf7554ad8f540fc1332ed6b7421 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 14 Apr 2025 15:51:23 +0200 Subject: [PATCH 10/22] maint: ruff rule ANN101 does not exist anymore --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 944f5a63..21ae3986 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ extend-select = ["E", "W", "YTT", "ASYNC", "BLE", "B", "A", "PTH", "TD", "ERA", "PL", "PERF", "RUF", "ARG", "ANN", "D" ] -ignore = ["ISC001", "ANN101", "D203", "D213", "D100", "D105"] +ignore = ["ISC001", "D203", "D213", "D100", "D105"] [tool.ruff.lint.pydocstyle] convention = "numpy" From 417df08906eaf7e3a8c687dc090b7f3796fd3f0f Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 14 Apr 2025 17:33:28 +0200 Subject: [PATCH 11/22] maint: bump aladin to 3.6.5 --- CHANGELOG.md | 2 +- README.md | 2 +- js/aladin_lite.js | 2 +- src/ipyaladin/__about__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b29eb962..2addea32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed - supported python versions are now 3.9 - 3.13 [#141] -- aladin-lite version is now 3.6.1-beta [#141] +- aladin-lite version is now 3.6.5 [#110] - `add_graphic_overlay_from_stcs` accepts iterables besides lists [#140] ## Fixed diff --git a/README.md b/README.md index f97dc44e..cd3361f5 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Correspondence table between ipyaladin versions and Aladin Lite versions: | ipyaladin | Aladin-Lite | | ---------- | ----------- | -| Unreleased | 3.6.1-beta | +| Unreleased | 3.6.5 | | 0.5.2 | 3.5.1-beta | | 0.5.1 | 3.5.1-beta | | 0.5.0 | 3.5.1-beta | diff --git a/js/aladin_lite.js b/js/aladin_lite.js index d40545ab..241d4025 100644 --- a/js/aladin_lite.js +++ b/js/aladin_lite.js @@ -1,3 +1,3 @@ -import A from "https://esm.sh/aladin-lite@3.6.1-beta"; +import A from "https://esm.sh/aladin-lite@3.6.5"; export default A; diff --git a/src/ipyaladin/__about__.py b/src/ipyaladin/__about__.py index caadf290..0493963e 100644 --- a/src/ipyaladin/__about__.py +++ b/src/ipyaladin/__about__.py @@ -1,2 +1,2 @@ __version__ = "0.5.2" -__aladin_lite_version__ = "3.6.1-beta" +__aladin_lite_version__ = "3.6.5" From ee2ec990138f7770735e9b93477943d7c122f45d Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 14 Apr 2025 17:33:57 +0200 Subject: [PATCH 12/22] docs: fill is not True by default anymore --- examples/05_Display_a_MOC.ipynb | 44 +++------------------------------ 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/examples/05_Display_a_MOC.ipynb b/examples/05_Display_a_MOC.ipynb index 61058dcc..ce940bb4 100644 --- a/examples/05_Display_a_MOC.ipynb +++ b/examples/05_Display_a_MOC.ipynb @@ -40,6 +40,8 @@ " \"https://alasky.u-strasbg.fr/footprints/tables/vizier/II_337_vvv1/MOC?nside=256\",\n", " color=\"violet\",\n", " opacity=0.3,\n", + " fill=True,\n", + " edge=True,\n", ")" ] }, @@ -284,49 +286,11 @@ " external_radius=20 * u.deg,\n", " max_depth=16,\n", ")\n", - "aladin.add_moc(\n", - " moc, color=\"teal\", edge=True, line_width=3, fill_color=\"teal\", opacity=0.5\n", - ")" + "aladin.add_moc(moc, color=\"teal\", edge=True, line_width=3, fill=True, opacity=0.5)" ] } ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.3" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": false, - "sideBar": false, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": false, - "toc_window_display": false - }, - "vscode": { - "interpreter": { - "hash": "85bb43f988bdbdc027a50b6d744a62eda8a76617af1f4f9b115d38242716dbac" - } - } - }, + "metadata": {}, "nbformat": 4, "nbformat_minor": 4 } From 6c01f759b58f7b950005a35e6d1bda45278598ce Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Tue, 15 Apr 2025 11:45:09 +0200 Subject: [PATCH 13/22] fix: object clicked for error shapes --- js/models/event_handler.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 935cf562..188fd9d7 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -187,12 +187,16 @@ export default class EventHandler { this.aladin.on("objectClicked", (clicked) => { if (clicked) { let clickedContent = { - ra: clicked["ra"], - dec: clicked["dec"], + // the coordinates are in 'source' for footprints + ra: clicked["ra"] || clicked["source"]["ra"], + dec: clicked["dec"] || clicked["source"]["dec"], }; if (clicked["data"] !== undefined) { clickedContent["data"] = clicked["data"]; } + if (clicked["source"] !== undefined) { + clickedContent["data"] = clicked["source"]["data"]; + } this.model.set("clicked_object", clickedContent); // send a custom message in case the user wants to define their own callbacks this.model.send({ From 4d9ab6750102e3caa03f1cf1ec14670395cc5000 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Tue, 15 Apr 2025 11:46:05 +0200 Subject: [PATCH 14/22] fix: default option in error shapes --- examples/04_Importing_Tables.ipynb | 8 ++++++-- js/models/message_handler.js | 9 +++++---- src/ipyaladin/widget.py | 1 - 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/04_Importing_Tables.ipynb b/examples/04_Importing_Tables.ipynb index 39f24ea2..5901f1a4 100644 --- a/examples/04_Importing_Tables.ipynb +++ b/examples/04_Importing_Tables.ipynb @@ -84,7 +84,9 @@ " default_shape=\"cross\",\n", " ),\n", " color=\"lightskyblue\",\n", - " source_size=20, # will only affect the sources which fallback to the default shape\n", + " # source_size will only affect the sources which fallback to the default shape,\n", + " # or the ones too small to be drawn\n", + " source_size=20,\n", " name=\"SIMBAD query\",\n", ")" ] @@ -93,7 +95,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If you zoom in the view, you'll remark that the sources which had error information appear as ellipses. If the spahe would be smaller than a pixel at maximum zoom or if there is no information in the error columns, then the sources appear with the fallback shape. `default_shape` should be one of the strings allowed in `shape`." + "If you zoom in the view, you'll remark that the sources which had error information appear as ellipses. If if there is no information in the error columns, then the sources appear with the fallback shape `default_shape`. `default_shape` should be one of the strings allowed in `shape`.\n", + "\n", + "If the ellipse would be too small to be drawn in the widget, then it appears as a square, see the source `2MASS J05343561+2200372` located in `83.64842925852 +22.01034559457`. If you zoom in close to this square, you'll see the square turning into an ellipse when it is big enough to be drawn." ] }, { diff --git a/js/models/message_handler.js b/js/models/message_handler.js index 09e1af1e..952d5e0a 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -168,6 +168,7 @@ export default class MessageHandler { const blob = new Blob([decoder.decode(buffer)]); const url = URL.createObjectURL(blob); options.onClick = "showTable"; + const shape = options.shape || "cross"; if (Object.keys(circleOptions).length != 0) { options.shape = (source) => { if (source.data[circleOptions.radius]) { @@ -175,10 +176,10 @@ export default class MessageHandler { source.ra, source.dec, source.data[circleOptions.radius] * circleOptions.conversionRadius, - options, ); + } else { + return shape; } - // return string shape (remove comment when aladin lite accepts strings as returns) }; } if (Object.keys(ellipseOptions).length != 0) { @@ -195,10 +196,10 @@ export default class MessageHandler { source.data[ellipseOptions.minAxis] * ellipseOptions.conversionMinAxis, source.data[ellipseOptions.angle] * ellipseOptions.conversionAngle, - options, ); + } else { + return shape; } - // return string shape (remove comment when aladin lite accepts strings as returns) }; } A.catalogFromURL( diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index d930406b..8c711a79 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -777,7 +777,6 @@ def add_table( -------- add_markers: adds markers with a popup window when clicked """ - shape = table_options.get("shape") if isinstance(shape, CircleError): table_options["circle_error"] = { "radius": shape.radius, From ce84742740fe9099605ebbf2584f153405e16254 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Tue, 15 Apr 2025 13:57:23 +0200 Subject: [PATCH 15/22] test: add verification for add table --- src/tests/test_aladin.py | 53 ++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/tests/test_aladin.py b/src/tests/test_aladin.py index 1fb587a4..1f659fb2 100644 --- a/src/tests/test_aladin.py +++ b/src/tests/test_aladin.py @@ -2,12 +2,13 @@ from astropy.coordinates import Angle, SkyCoord, Longitude, Latitude import astropy.units as u -from astropy.table import Column +from astropy.table import Column, Table import numpy as np import pytest from unittest.mock import Mock from ipyaladin import Aladin +from ipyaladin.elements.error_shape import EllipseError, CircleError from ipyaladin.utils._coordinate_parser import _parse_coordinate_string from .test_coordinate_parser import test_is_coordinate_string_values @@ -70,12 +71,6 @@ def test_aladin_string_target_set(target: str, mock_sesame: Callable) -> None: assert np.isclose(aladin.target.icrs.dec.deg, parsed_target[1]) -def test_aladin_planetary_string_target_set() -> None: - aladin._survey_body = "mars" - parsed_target = _parse_coordinate_string("Olympus Mons", body="mars") - print(parsed_target) - - @pytest.mark.parametrize("target", test_aladin_string_target) def test_aladin_sky_coord_target_set(target: str, mock_sesame: Callable) -> None: # noqa: ARG001 """Test setting and getting the target of an Aladin object with a SkyCoord object. @@ -200,3 +195,47 @@ def test_add_graphic_overlay_from_stcs_noniterables( with pytest.raises(TypeError) as info: aladin.add_graphic_overlay_from_stcs(stcs_strings) assert info.type is TypeError + + +def test_add_table(monkeypatch: Callable) -> None: + """Test generating region overlay info from iterable STC-S string(s). + + Parameters + ---------- + stcs_strings : Union[Iterable[str], str] + The stcs strings to create region overlay info from. + + """ + table = Table({"a": [1, 2, 3]}) + table["a"].unit = "deg" + mock_send = Mock() + monkeypatch.setattr(Aladin, "send", mock_send) + + # normal table call + aladin.add_table(table) + table_sent_message = mock_send.call_args[0][0] + assert table_sent_message["event_name"] == "add_table" + + # circle error + aladin.add_table( + table, shape=CircleError(radius="a", default_shape="cross"), color="pink" + ) + table_sent_message = mock_send.call_args[0][0] + assert table_sent_message["options"]["circle_error"] == { + "radius": "a", + "conversion_radius": 1, + } + assert table_sent_message["options"]["shape"] == "cross" + + # ellipse error + aladin.add_table(table, shape=EllipseError(maj_axis="a", min_axis="a", angle="a")) + table_sent_message = mock_send.call_args[0][0] + ellipse_options = { + "maj_axis": "a", + "min_axis": "a", + "angle": "a", + "conversion_angle": 1, + "conversion_min_axis": 1, + "conversion_maj_axis": 1, + } + assert table_sent_message["options"]["ellipse_error"] == ellipse_options From 4259f33250e1be38672d1a0dc0c009bd077ab7bb Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 16 Apr 2025 11:17:23 +0200 Subject: [PATCH 16/22] maint: run npm audit fix --- package-lock.json | 480 +++++++++++++++++++++++++++++----------------- 1 file changed, 299 insertions(+), 181 deletions(-) diff --git a/package-lock.json b/package-lock.json index d7b1cd27..2496c9b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "ipyaladin", "devDependencies": { "@jupyterlab/galata": "^5.2.3", "@playwright/test": "^1.44.0", @@ -2808,7 +2809,8 @@ "version": "7946.0.4", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.4.tgz", "integrity": "sha512-MHmwBtCb7OCv1DSivz2UNJXPGU/1btAWRKlqJ2saEhVJkpkvqHMMaOpKg0v4sAbDWSQekHGvPVMM8nQ+Jen03Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/prop-types": { "version": "15.7.12", @@ -3180,6 +3182,7 @@ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3189,6 +3192,7 @@ "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", "dev": true, + "license": "ISC", "dependencies": { "delaunator": "5" }, @@ -3201,6 +3205,7 @@ "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3210,6 +3215,7 @@ "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", "dev": true, + "license": "ISC", "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -3235,6 +3241,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -3244,6 +3251,7 @@ "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", "dev": true, + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -3258,6 +3266,7 @@ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3267,6 +3276,7 @@ "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "dev": true, + "license": "ISC", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -3279,6 +3289,7 @@ "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-4.0.0.tgz", "integrity": "sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==", "dev": true, + "license": "ISC", "dependencies": { "commander": "7", "d3-array": "1 - 3", @@ -3300,6 +3311,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -3309,6 +3321,7 @@ "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3318,6 +3331,7 @@ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dev": true, + "license": "ISC", "dependencies": { "d3-color": "1 - 3" }, @@ -3330,6 +3344,7 @@ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3339,6 +3354,7 @@ "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3348,6 +3364,7 @@ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dev": true, + "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -3359,11 +3376,26 @@ "node": ">=12" } }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-shape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", "dev": true, + "license": "ISC", "dependencies": { "d3-path": "^3.1.0" }, @@ -3376,6 +3408,7 @@ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "dev": true, + "license": "ISC", "dependencies": { "d3-array": "2 - 3" }, @@ -3388,6 +3421,7 @@ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dev": true, + "license": "ISC", "dependencies": { "d3-time": "1 - 3" }, @@ -3400,6 +3434,7 @@ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3436,6 +3471,7 @@ "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", "dev": true, + "license": "ISC", "dependencies": { "robust-predicates": "^3.0.2" } @@ -3828,6 +3864,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -4307,6 +4344,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -4759,7 +4797,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", - "dev": true + "dev": true, + "license": "Unlicense" }, "node_modules/run-parallel": { "version": "1.2.0", @@ -4788,7 +4827,8 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -4800,7 +4840,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sanitize-html": { "version": "2.12.1", @@ -5015,6 +5056,7 @@ "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", "dev": true, + "license": "ISC", "dependencies": { "commander": "2" }, @@ -5028,13 +5070,15 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/trailing-whitespaces": { "version": "1.0.8", @@ -5182,79 +5226,84 @@ "dev": true }, "node_modules/vega": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/vega/-/vega-5.28.0.tgz", - "integrity": "sha512-5EDVhjBUgcVdrA6LZDBLah/nuk4FRUwZqTgP/Yi32qeRCoiN0xkptQ5Sbmj6XfH7wu1SdbAbsCm1Zls+9NC/8Q==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/vega/-/vega-5.33.0.tgz", + "integrity": "sha512-jNAGa7TxLojOpMMMrKMXXBos4K6AaLJbCgGDOw1YEkLRjUkh12pcf65J2lMSdEHjcEK47XXjKiOUVZ8L+MniBA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-crossfilter": "~4.1.1", - "vega-dataflow": "~5.7.5", - "vega-encode": "~4.9.2", + "vega-crossfilter": "~4.1.3", + "vega-dataflow": "~5.7.7", + "vega-encode": "~4.10.2", "vega-event-selector": "~3.0.1", - "vega-expression": "~5.1.0", - "vega-force": "~4.2.0", - "vega-format": "~1.1.1", - "vega-functions": "~5.14.0", - "vega-geo": "~4.4.1", - "vega-hierarchy": "~4.1.1", - "vega-label": "~1.2.1", - "vega-loader": "~4.5.1", - "vega-parser": "~6.3.0", - "vega-projection": "~1.6.0", - "vega-regression": "~1.2.0", - "vega-runtime": "~6.1.4", - "vega-scale": "~7.3.1", - "vega-scenegraph": "~4.11.2", + "vega-expression": "~5.2.0", + "vega-force": "~4.2.2", + "vega-format": "~1.1.3", + "vega-functions": "~5.18.0", + "vega-geo": "~4.4.3", + "vega-hierarchy": "~4.1.3", + "vega-label": "~1.3.1", + "vega-loader": "~4.5.3", + "vega-parser": "~6.6.0", + "vega-projection": "~1.6.2", + "vega-regression": "~1.3.1", + "vega-runtime": "~6.2.1", + "vega-scale": "~7.4.2", + "vega-scenegraph": "~4.13.1", "vega-statistics": "~1.9.0", - "vega-time": "~2.1.1", - "vega-transforms": "~4.11.1", - "vega-typings": "~1.1.0", + "vega-time": "~2.1.3", + "vega-transforms": "~4.12.1", + "vega-typings": "~1.5.0", "vega-util": "~1.17.2", - "vega-view": "~5.12.0", - "vega-view-transforms": "~4.5.9", - "vega-voronoi": "~4.2.2", - "vega-wordcloud": "~4.1.4" + "vega-view": "~5.16.0", + "vega-view-transforms": "~4.6.1", + "vega-voronoi": "~4.2.4", + "vega-wordcloud": "~4.1.6" } }, "node_modules/vega-canvas": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/vega-canvas/-/vega-canvas-1.2.7.tgz", "integrity": "sha512-OkJ9CACVcN9R5Pi9uF6MZBF06pO6qFpDYHWSKBJsdHP5o724KrsgR6UvbnXFH82FdsiTOff/HqjuaG8C7FL+9Q==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/vega-crossfilter": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vega-crossfilter/-/vega-crossfilter-4.1.1.tgz", - "integrity": "sha512-yesvlMcwRwxrtAd9IYjuxWJJuAMI0sl7JvAFfYtuDkkGDtqfLXUcCzHIATqW6igVIE7tWwGxnbfvQLhLNgK44Q==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vega-crossfilter/-/vega-crossfilter-4.1.3.tgz", + "integrity": "sha512-nyPJAXAUABc3EocUXvAL1J/IWotZVsApIcvOeZaUdEQEtZ7bt8VtP2nj3CLbHBA8FZZVV+K6SmdwvCOaAD4wFQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", - "vega-dataflow": "^5.7.5", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-util": "^1.17.3" } }, "node_modules/vega-dataflow": { - "version": "5.7.5", - "resolved": "https://registry.npmjs.org/vega-dataflow/-/vega-dataflow-5.7.5.tgz", - "integrity": "sha512-EdsIl6gouH67+8B0f22Owr2tKDiMPNNR8lEvJDcxmFw02nXd8juimclpLvjPQriqn6ta+3Dn5txqfD117H04YA==", + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/vega-dataflow/-/vega-dataflow-5.7.7.tgz", + "integrity": "sha512-R2NX2HvgXL+u4E6u+L5lKvvRiCtnE6N6l+umgojfi53suhhkFP+zB+2UAQo4syxuZ4763H1csfkKc4xpqLzKnw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-format": "^1.1.1", - "vega-loader": "^4.5.1", - "vega-util": "^1.17.1" + "vega-format": "^1.1.3", + "vega-loader": "^4.5.3", + "vega-util": "^1.17.3" } }, "node_modules/vega-encode": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.9.2.tgz", - "integrity": "sha512-c3J0LYkgYeXQxwnYkEzL15cCFBYPRaYUon8O2SZ6O4PhH4dfFTXBzSyT8+gh8AhBd572l2yGDfxpEYA6pOqdjg==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.10.2.tgz", + "integrity": "sha512-fsjEY1VaBAmqwt7Jlpz0dpPtfQFiBdP9igEefvumSpy7XUxOJmDQcRDnT3Qh9ctkv3itfPfI9g8FSnGcv2b4jQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-interpolate": "^3.0.1", - "vega-dataflow": "^5.7.5", - "vega-scale": "^7.3.0", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-scale": "^7.4.2", + "vega-util": "^1.17.3" } }, "node_modules/vega-event-selector": { @@ -5274,85 +5323,102 @@ } }, "node_modules/vega-force": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vega-force/-/vega-force-4.2.0.tgz", - "integrity": "sha512-aE2TlP264HXM1r3fl58AvZdKUWBNOGkIvn4EWyqeJdgO2vz46zSU7x7TzPG4ZLuo44cDRU5Ng3I1eQk23Asz6A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/vega-force/-/vega-force-4.2.2.tgz", + "integrity": "sha512-cHZVaY2VNNIG2RyihhSiWniPd2W9R9kJq0znxzV602CgUVgxEfTKtx/lxnVCn8nNrdKAYrGiqIsBzIeKG1GWHw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-force": "^3.0.0", - "vega-dataflow": "^5.7.5", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-util": "^1.17.3" } }, "node_modules/vega-format": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vega-format/-/vega-format-1.1.1.tgz", - "integrity": "sha512-Rll7YgpYbsgaAa54AmtEWrxaJqgOh5fXlvM2wewO4trb9vwM53KBv4Q/uBWCLK3LLGeBXIF6gjDt2LFuJAUtkQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vega-format/-/vega-format-1.1.3.tgz", + "integrity": "sha512-wQhw7KR46wKJAip28FF/CicW+oiJaPAwMKdrxlnTA0Nv8Bf7bloRlc+O3kON4b4H1iALLr9KgRcYTOeXNs2MOA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-format": "^3.1.0", "d3-time-format": "^4.1.0", - "vega-time": "^2.1.1", - "vega-util": "^1.17.1" + "vega-time": "^2.1.3", + "vega-util": "^1.17.3" } }, "node_modules/vega-functions": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/vega-functions/-/vega-functions-5.14.0.tgz", - "integrity": "sha512-Q0rocHmJDfQ0tS91kdN8WcEosq1e3HPK1Yf5z36SPYPmTzKw3uxUGE52tLxC832acAYqPmi8R41wAoI/yFQTPg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/vega-functions/-/vega-functions-5.18.0.tgz", + "integrity": "sha512-+D+ey4bDAhZA2CChh7bRZrcqRUDevv05kd2z8xH+il7PbYQLrhi6g1zwvf8z3KpgGInFf5O13WuFK5DQGkz5lQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-color": "^3.1.0", "d3-geo": "^3.1.0", - "vega-dataflow": "^5.7.5", - "vega-expression": "^5.1.0", - "vega-scale": "^7.3.0", - "vega-scenegraph": "^4.10.2", - "vega-selections": "^5.4.2", - "vega-statistics": "^1.8.1", - "vega-time": "^2.1.1", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-expression": "^5.2.0", + "vega-scale": "^7.4.2", + "vega-scenegraph": "^4.13.1", + "vega-selections": "^5.6.0", + "vega-statistics": "^1.9.0", + "vega-time": "^2.1.3", + "vega-util": "^1.17.3" + } + }, + "node_modules/vega-functions/node_modules/vega-expression": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-5.2.0.tgz", + "integrity": "sha512-WRMa4ny3iZIVAzDlBh3ipY2QUuLk2hnJJbfbncPgvTF7BUgbIbKq947z+JicWksYbokl8n1JHXJoqi3XvpG0Zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/estree": "^1.0.0", + "vega-util": "^1.17.3" } }, "node_modules/vega-geo": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-4.4.1.tgz", - "integrity": "sha512-s4WeZAL5M3ZUV27/eqSD3v0FyJz3PlP31XNSLFy4AJXHxHUeXT3qLiDHoVQnW5Om+uBCPDtTT1ROx1smGIf2aA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-4.4.3.tgz", + "integrity": "sha512-+WnnzEPKIU1/xTFUK3EMu2htN35gp9usNZcC0ZFg2up1/Vqu6JyZsX0PIO51oXSIeXn9bwk6VgzlOmJUcx92tA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-color": "^3.1.0", "d3-geo": "^3.1.0", "vega-canvas": "^1.2.7", - "vega-dataflow": "^5.7.5", - "vega-projection": "^1.6.0", - "vega-statistics": "^1.8.1", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-projection": "^1.6.2", + "vega-statistics": "^1.9.0", + "vega-util": "^1.17.3" } }, "node_modules/vega-hierarchy": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vega-hierarchy/-/vega-hierarchy-4.1.1.tgz", - "integrity": "sha512-h5mbrDtPKHBBQ9TYbvEb/bCqmGTlUX97+4CENkyH21tJs7naza319B15KRK0NWOHuhbGhFmF8T0696tg+2c8XQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vega-hierarchy/-/vega-hierarchy-4.1.3.tgz", + "integrity": "sha512-0Z+TYKRgOEo8XYXnJc2HWg1EGpcbNAhJ9Wpi9ubIbEyEHqIgjCIyFVN8d4nSfsJOcWDzsSmRqohBztxAhOCSaw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-hierarchy": "^3.1.2", - "vega-dataflow": "^5.7.5", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-util": "^1.17.3" } }, "node_modules/vega-label": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/vega-label/-/vega-label-1.2.1.tgz", - "integrity": "sha512-n/ackJ5lc0Xs9PInCaGumYn2awomPjJ87EMVT47xNgk2bHmJoZV1Ve/1PUM6Eh/KauY211wPMrNp/9Im+7Ripg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/vega-label/-/vega-label-1.3.1.tgz", + "integrity": "sha512-Emx4b5s7pvuRj3fBkAJ/E2snCoZACfKAwxVId7f/4kYVlAYLb5Swq6W8KZHrH4M9Qds1XJRUYW9/Y3cceqzEFA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-canvas": "^1.2.6", - "vega-dataflow": "^5.7.3", - "vega-scenegraph": "^4.9.2", - "vega-util": "^1.15.2" + "vega-canvas": "^1.2.7", + "vega-dataflow": "^5.7.7", + "vega-scenegraph": "^4.13.1", + "vega-util": "^1.17.3" } }, "node_modules/vega-lite": { @@ -5388,100 +5454,120 @@ "dev": true }, "node_modules/vega-loader": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/vega-loader/-/vega-loader-4.5.1.tgz", - "integrity": "sha512-qy5x32SaT0YkEujQM2yKqvLGV9XWQ2aEDSugBFTdYzu/1u4bxdUSRDREOlrJ9Km3RWIOgFiCkobPmFxo47SKuA==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vega-loader/-/vega-loader-4.5.3.tgz", + "integrity": "sha512-dUfIpxTLF2magoMaur+jXGvwMxjtdlDZaIS8lFj6N7IhUST6nIvBzuUlRM+zLYepI5GHtCLOnqdKU4XV0NggCA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-dsv": "^3.0.1", "node-fetch": "^2.6.7", "topojson-client": "^3.1.0", - "vega-format": "^1.1.1", - "vega-util": "^1.17.1" + "vega-format": "^1.1.3", + "vega-util": "^1.17.3" } }, "node_modules/vega-parser": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-6.3.0.tgz", - "integrity": "sha512-swS5RuP2imRarMpGWaAZusoKkXc4Z5WxWx349pkqxIAf4F7H8Ya9nThEkSWsFozd75O9nWh0QLifds8Xb7KjUg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-6.6.0.tgz", + "integrity": "sha512-jltyrwCTtWeidi/6VotLCybhIl+ehwnzvFWYOdWNUP0z/EskdB64YmawNwjCjzTBMemeiQtY6sJPPbewYqe3Vg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-dataflow": "^5.7.5", + "vega-dataflow": "^5.7.7", "vega-event-selector": "^3.0.1", - "vega-functions": "^5.14.0", - "vega-scale": "^7.3.1", - "vega-util": "^1.17.2" + "vega-functions": "^5.18.0", + "vega-scale": "^7.4.2", + "vega-util": "^1.17.3" } }, "node_modules/vega-projection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vega-projection/-/vega-projection-1.6.0.tgz", - "integrity": "sha512-LGUaO/kpOEYuTlul+x+lBzyuL9qmMwP1yShdUWYLW+zXoeyGbs5OZW+NbPPwLYqJr5lpXDr/vGztFuA/6g2xvQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vega-projection/-/vega-projection-1.6.2.tgz", + "integrity": "sha512-3pcVaQL9R3Zfk6PzopLX6awzrQUeYOXJzlfLGP2Xd93mqUepBa6m/reVrTUoSFXA3v9lfK4W/PS2AcVzD/MIcQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-geo": "^3.1.0", "d3-geo-projection": "^4.0.0", - "vega-scale": "^7.3.0" + "vega-scale": "^7.4.2" } }, "node_modules/vega-regression": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vega-regression/-/vega-regression-1.2.0.tgz", - "integrity": "sha512-6TZoPlhV/280VbxACjRKqlE0Nv48z5g4CSNf1FmGGTWS1rQtElPTranSoVW4d7ET5eVQ6f9QLxNAiALptvEq+g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/vega-regression/-/vega-regression-1.3.1.tgz", + "integrity": "sha512-AmccF++Z9uw4HNZC/gmkQGe6JsRxTG/R4QpbcSepyMvQN1Rj5KtVqMcmVFP1r3ivM4dYGFuPlzMWvuqp0iKMkQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", - "vega-dataflow": "^5.7.3", + "vega-dataflow": "^5.7.7", "vega-statistics": "^1.9.0", - "vega-util": "^1.15.2" + "vega-util": "^1.17.3" } }, "node_modules/vega-runtime": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/vega-runtime/-/vega-runtime-6.1.4.tgz", - "integrity": "sha512-0dDYXyFLQcxPQ2OQU0WuBVYLRZnm+/CwVu6i6N4idS7R9VXIX5581EkCh3pZ20pQ/+oaA7oJ0pR9rJgJ6rukRQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/vega-runtime/-/vega-runtime-6.2.1.tgz", + "integrity": "sha512-b4eot3tWKCk++INWqot+6sLn3wDTj/HE+tRSbiaf8aecuniPMlwJEK7wWuhVGeW2Ae5n8fI/8TeTViaC94bNHA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-dataflow": "^5.7.5", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-util": "^1.17.3" } }, "node_modules/vega-scale": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vega-scale/-/vega-scale-7.3.1.tgz", - "integrity": "sha512-tyTlaaCpHN2Ik/PPKl/j9ThadBDjPtypqW1D7IsUSkzfoZ7RPlI2jwAaoj2C/YW5jFRbEOx3njmjogp48I5CvA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/vega-scale/-/vega-scale-7.4.2.tgz", + "integrity": "sha512-o6Hl76aU1jlCK7Q8DPYZ8OGsp4PtzLdzI6nGpLt8rxoE78QuB3GBGEwGAQJitp4IF7Lb2rL5oAXEl3ZP6xf9jg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", - "vega-time": "^2.1.1", - "vega-util": "^1.17.1" + "d3-scale-chromatic": "^3.1.0", + "vega-time": "^2.1.3", + "vega-util": "^1.17.3" } }, "node_modules/vega-scenegraph": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.11.2.tgz", - "integrity": "sha512-PXSvv/L7Ek+9mwOTPLpzgkXdfGCR+AcWV5aquPGrqCWoiIF49VJkKFNT1HWxj3RZJX0XKo2r7SuXvRBb9EJ1aA==", + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.13.1.tgz", + "integrity": "sha512-LFY9+sLIxRfdDI9ZTKjLoijMkIAzPLBWHpPkwv4NPYgdyx+0qFmv+puBpAUGUY9VZqAZ736Uj5NJY9zw+/M3yQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-path": "^3.1.0", "d3-shape": "^3.2.0", "vega-canvas": "^1.2.7", - "vega-loader": "^4.5.1", - "vega-scale": "^7.3.0", - "vega-util": "^1.17.1" + "vega-loader": "^4.5.3", + "vega-scale": "^7.4.2", + "vega-util": "^1.17.3" } }, "node_modules/vega-selections": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/vega-selections/-/vega-selections-5.4.2.tgz", - "integrity": "sha512-99FUhYmg0jOJr2/K4TcEURmJRkuibrCDc8KBUX7qcQEITzrZ5R6a4QE+sarCvbb3hi8aA9GV2oyST6MQeA9mgQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/vega-selections/-/vega-selections-5.6.0.tgz", + "integrity": "sha512-UE2w78rUUbaV3Ph+vQbQDwh8eywIJYRxBiZdxEG/Tr/KtFMLdy2BDgNZuuDO1Nv8jImPJwONmqjNhNDYwM0VJQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "3.2.4", - "vega-expression": "^5.0.1", - "vega-util": "^1.17.1" + "vega-expression": "^5.2.0", + "vega-util": "^1.17.3" + } + }, + "node_modules/vega-selections/node_modules/vega-expression": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-5.2.0.tgz", + "integrity": "sha512-WRMa4ny3iZIVAzDlBh3ipY2QUuLk2hnJJbfbncPgvTF7BUgbIbKq947z+JicWksYbokl8n1JHXJoqi3XvpG0Zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/estree": "^1.0.0", + "vega-util": "^1.17.3" } }, "node_modules/vega-statistics": { @@ -5494,96 +5580,126 @@ } }, "node_modules/vega-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/vega-time/-/vega-time-2.1.1.tgz", - "integrity": "sha512-z1qbgyX0Af2kQSGFbApwBbX2meenGvsoX8Nga8uyWN8VIbiySo/xqizz1KrP6NbB6R+x5egKmkjdnyNThPeEWA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/vega-time/-/vega-time-2.1.3.tgz", + "integrity": "sha512-hFcWPdTV844IiY0m97+WUoMLADCp+8yUQR1NStWhzBzwDDA7QEGGwYGxALhdMOaDTwkyoNj3V/nox2rQAJD/vQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-time": "^3.1.0", - "vega-util": "^1.17.1" + "vega-util": "^1.17.3" } }, "node_modules/vega-transforms": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-4.11.1.tgz", - "integrity": "sha512-DDbqEQnvy9/qEvv0bAKPqAuzgaNb7Lh2xKJFom2Yzx4tZHCl8dnKxC1lH9JnJlAMdtZuiNLPARUkf3pCNQ/olw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-4.12.1.tgz", + "integrity": "sha512-Qxo+xeEEftY1jYyKgzOGc9NuW4/MqGm1YPZ5WrL9eXg2G0410Ne+xL/MFIjHF4hRX+3mgFF4Io2hPpfy/thjLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", - "vega-dataflow": "^5.7.5", - "vega-statistics": "^1.8.1", - "vega-time": "^2.1.1", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-statistics": "^1.9.0", + "vega-time": "^2.1.3", + "vega-util": "^1.17.3" } }, "node_modules/vega-typings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-1.1.0.tgz", - "integrity": "sha512-uI6RWlMiGRhsgmw/LzJtjCc0kwhw2f0JpyNMTAnOy90kE4e4CiaZN5nJp8S9CcfcBoPEZHc166AOn2SSNrKn3A==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-1.5.0.tgz", + "integrity": "sha512-tcZ2HwmiQEOXIGyBMP8sdCnoFoVqHn4KQ4H0MQiHwzFU1hb1EXURhfc+Uamthewk4h/9BICtAM3AFQMjBGpjQA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@types/geojson": "7946.0.4", "vega-event-selector": "^3.0.1", - "vega-expression": "^5.1.0", - "vega-util": "^1.17.2" + "vega-expression": "^5.2.0", + "vega-util": "^1.17.3" + } + }, + "node_modules/vega-typings/node_modules/vega-expression": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-5.2.0.tgz", + "integrity": "sha512-WRMa4ny3iZIVAzDlBh3ipY2QUuLk2hnJJbfbncPgvTF7BUgbIbKq947z+JicWksYbokl8n1JHXJoqi3XvpG0Zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/estree": "^1.0.0", + "vega-util": "^1.17.3" } }, "node_modules/vega-util": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/vega-util/-/vega-util-1.17.2.tgz", - "integrity": "sha512-omNmGiZBdjm/jnHjZlywyYqafscDdHaELHx1q96n5UOz/FlO9JO99P4B3jZg391EFG8dqhWjQilSf2JH6F1mIw==", - "dev": true + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/vega-util/-/vega-util-1.17.3.tgz", + "integrity": "sha512-nSNpZLUrRvFo46M5OK4O6x6f08WD1yOcEzHNlqivF+sDLSsVpstaF6fdJYwrbf/debFi2L9Tkp4gZQtssup9iQ==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/vega-view": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/vega-view/-/vega-view-5.12.0.tgz", - "integrity": "sha512-T3GY7UJNVZGrCUrAmE/OCrkoJQyOT/2dCgXgy9EvDMVv/sdrn7o1TMKhSV18nIr0m5A7m4mgKwrmguAfROY85g==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/vega-view/-/vega-view-5.16.0.tgz", + "integrity": "sha512-Nxp1MEAY+8bphIm+7BeGFzWPoJnX9+hgvze6wqCAPoM69YiyVR0o0VK8M2EESIL+22+Owr0Fdy94hWHnmon5tQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-array": "^3.2.2", "d3-timer": "^3.0.1", - "vega-dataflow": "^5.7.5", - "vega-format": "^1.1.1", - "vega-functions": "^5.13.1", - "vega-runtime": "^6.1.4", - "vega-scenegraph": "^4.10.2", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-format": "^1.1.3", + "vega-functions": "^5.18.0", + "vega-runtime": "^6.2.1", + "vega-scenegraph": "^4.13.1", + "vega-util": "^1.17.3" } }, "node_modules/vega-view-transforms": { - "version": "4.5.9", - "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-4.5.9.tgz", - "integrity": "sha512-NxEq4ZD4QwWGRrl2yDLnBRXM9FgCI+vvYb3ZC2+nVDtkUxOlEIKZsMMw31op5GZpfClWLbjCT3mVvzO2xaTF+g==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-4.6.1.tgz", + "integrity": "sha512-RYlyMJu5kZV4XXjmyTQKADJWDB25SMHsiF+B1rbE1p+pmdQPlp5tGdPl9r5dUJOp3p8mSt/NGI8GPGucmPMxtw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "vega-dataflow": "^5.7.5", - "vega-scenegraph": "^4.10.2", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-scenegraph": "^4.13.1", + "vega-util": "^1.17.3" } }, "node_modules/vega-voronoi": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/vega-voronoi/-/vega-voronoi-4.2.2.tgz", - "integrity": "sha512-Bq2YOp2MGphhQnUuLwl3dsyBs6MuEU86muTjDbBJg33+HkZtE1kIoQZr+EUHa46NBsY1NzSKddOTu8wcaFrWiQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/vega-voronoi/-/vega-voronoi-4.2.4.tgz", + "integrity": "sha512-lWNimgJAXGeRFu2Pz8axOUqVf1moYhD+5yhBzDSmckE9I5jLOyZc/XvgFTXwFnsVkMd1QW1vxJa+y9yfUblzYw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "d3-delaunay": "^6.0.2", - "vega-dataflow": "^5.7.5", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-util": "^1.17.3" } }, "node_modules/vega-wordcloud": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/vega-wordcloud/-/vega-wordcloud-4.1.4.tgz", - "integrity": "sha512-oeZLlnjiusLAU5vhk0IIdT5QEiJE0x6cYoGNq1th+EbwgQp153t4r026fcib9oq15glHFOzf81a8hHXHSJm1Jw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/vega-wordcloud/-/vega-wordcloud-4.1.6.tgz", + "integrity": "sha512-lFmF3u9/ozU0P+WqPjeThQfZm0PigdbXDwpIUCxczrCXKYJLYFmZuZLZR7cxtmpZ0/yuvRvAJ4g123LXbSZF8A==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "vega-canvas": "^1.2.7", - "vega-dataflow": "^5.7.5", - "vega-scale": "^7.3.0", - "vega-statistics": "^1.8.1", - "vega-util": "^1.17.1" + "vega-dataflow": "^5.7.7", + "vega-scale": "^7.4.2", + "vega-statistics": "^1.9.0", + "vega-util": "^1.17.3" + } + }, + "node_modules/vega/node_modules/vega-expression": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-5.2.0.tgz", + "integrity": "sha512-WRMa4ny3iZIVAzDlBh3ipY2QUuLk2hnJJbfbncPgvTF7BUgbIbKq947z+JicWksYbokl8n1JHXJoqi3XvpG0Zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@types/estree": "^1.0.0", + "vega-util": "^1.17.3" } }, "node_modules/vscode-jsonrpc": { @@ -5648,13 +5764,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" From 68a538be2ea562c44b5aefeef406c100873429f1 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Wed, 16 Apr 2025 11:19:33 +0200 Subject: [PATCH 17/22] maint: prepare 0.6.0 --- CHANGELOG.md | 2 ++ README.md | 1 + src/ipyaladin/__about__.py | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2addea32..59f24cba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.6.0] + ## Added - when adding tables to `ipyaladin` with `add_table`, the shape argument now accepts diff --git a/README.md b/README.md index cd3361f5..edb9cbfe 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ Correspondence table between ipyaladin versions and Aladin Lite versions: | ipyaladin | Aladin-Lite | | ---------- | ----------- | | Unreleased | 3.6.5 | +| 0.6.0 | 3.6.5 | | 0.5.2 | 3.5.1-beta | | 0.5.1 | 3.5.1-beta | | 0.5.0 | 3.5.1-beta | diff --git a/src/ipyaladin/__about__.py b/src/ipyaladin/__about__.py index 0493963e..74d43c91 100644 --- a/src/ipyaladin/__about__.py +++ b/src/ipyaladin/__about__.py @@ -1,2 +1,2 @@ -__version__ = "0.5.2" +__version__ = "0.6.0" __aladin_lite_version__ = "3.6.5" From 882795cd0503b9ea5c995f1ab58d53e098a965a3 Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Wed, 16 Jul 2025 12:59:11 -0400 Subject: [PATCH 18/22] initial changes to be able to remove overlays programatically --- js/models/event_handler.js | 1 + js/models/message_handler.js | 8 ++++++++ src/ipyaladin/widget.py | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 188fd9d7..fddccf04 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -280,6 +280,7 @@ export default class EventHandler { add_MOC_from_URL: this.messageHandler.handleAddMOCFromURL, add_MOC_from_dict: this.messageHandler.handleAddMOCFromDict, add_overlay: this.messageHandler.handleAddOverlay, + remove_overlay: this.messageHandler.handleRemoveOverlay, change_colormap: this.messageHandler.handleChangeColormap, get_JPG_thumbnail: this.messageHandler.handleGetJPGThumbnail, trigger_selection: this.messageHandler.handleTriggerSelection, diff --git a/js/models/message_handler.js b/js/models/message_handler.js index 952d5e0a..ac9272e7 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -140,6 +140,14 @@ export default class MessageHandler { } } + handleRemoveOverlay(msg) { + const overlay_names = msg["name"]; + for (const overlay_name of overlay_names) { + console.info(`Sending removeOverlay for ${overlay_name}`); + this.aladin.removeOverlay(overlay_name); + } + } + handleChangeColormap(msg) { this.aladin.getBaseImageLayer().setColormap(msg["colormap"]); } diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 8c711a79..b735f9b5 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -955,6 +955,25 @@ def add_graphic_overlay_from_stcs( } ) + @widget_should_be_loaded + def remove_overlay(self, overlay_name: Union[Iterable[str], str]) -> None: + """Remove an overlay layer defined by an STC-S string. + + Parameters + ---------- + overlay_name : str, Iterable[str] + The STC-S string //or an iterable of STC-S strings. + + """ + overlay_name = [overlay_name] if isinstance(overlay_name, str) else overlay_name + + self.send( + { + "event_name": "remove_overlay", + "name": overlay_name, + } + ) + @widget_should_be_loaded def set_color_map(self, color_map_name: str) -> None: """Change the color map of the Aladin Lite widget. From 70e9a7837d89e2ca96d44f7eafa3a8d76fcfa7ea Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Fri, 18 Jul 2025 14:49:47 -0400 Subject: [PATCH 19/22] adding overlay traitletto list current overlays, must be updated using get_overlay to keep up to date --- js/models/event_handler.js | 1 + js/models/message_handler.js | 21 +++++++++++++++++++-- src/ipyaladin/widget.py | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index fddccf04..60a4afdc 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -281,6 +281,7 @@ export default class EventHandler { add_MOC_from_dict: this.messageHandler.handleAddMOCFromDict, add_overlay: this.messageHandler.handleAddOverlay, remove_overlay: this.messageHandler.handleRemoveOverlay, + get_overlays: this.messageHandler.handleGetOverlays, change_colormap: this.messageHandler.handleChangeColormap, get_JPG_thumbnail: this.messageHandler.handleGetJPGThumbnail, trigger_selection: this.messageHandler.handleTriggerSelection, diff --git a/js/models/message_handler.js b/js/models/message_handler.js index ac9272e7..2d1660e6 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -140,13 +140,30 @@ export default class MessageHandler { } } - handleRemoveOverlay(msg) { + handleRemoveOverlay = (msg) => { const overlay_names = msg["name"]; for (const overlay_name of overlay_names) { console.info(`Sending removeOverlay for ${overlay_name}`); this.aladin.removeOverlay(overlay_name); } - } + this.handleGetOverlays(); + }; + + handleGetOverlays = () => { + const overlay_names = []; + const overlays = this.aladin.getOverlays(); + for (const overlay of overlays) { + const overlay_name = overlay["name"]; + overlay_names.push(overlay_name); + } + console.info(`Current overlays are ${overlay_names}`); + this.model.send({ + event_type: "current_overlays", + content: { + overlays: overlay_names, + }, + }); + }; handleChangeColormap(msg) { this.aladin.getBaseImageLayer().setColormap(msg["colormap"]); diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index b735f9b5..b1d42afa 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -177,6 +177,11 @@ class Aladin(anywidget.AnyWidget): ).tag(sync=True) _wcs = traitlets.Dict().tag(sync=True) _fov_xy = traitlets.Dict().tag(sync=True) + # Overlays + _overlays = traitlets.List( + [], + help="A list of overlays on the widget.", + ).tag(sync=True) # content of the last click clicked_object = traitlets.Dict().tag(sync=True) @@ -254,6 +259,9 @@ def _handle_custom_message(self, _: any, message: dict, buffers: any) -> None: self.listener_callback["select"](message["content"]) elif event_type == "save_view_as_image": self._save_file(message["path"], buffers[0]) + elif event_type == "current_overlays": + self.listener_callback["current_overlays"](message["content"]) + self._overlays = message["content"]["overlays"] @property def selected_objects(self) -> List[Table]: @@ -271,6 +279,18 @@ def selected_objects(self) -> List[Table]: catalogs.append(Table(objects_data)) return catalogs + @property + def overlays(self) -> List: + """The list of overlays on the widget. + + Returns + ------- + list + A list of strings representing the widget overlays. + + """ + return self._overlays + @property def height(self) -> int: """The height of the widget. @@ -957,12 +977,12 @@ def add_graphic_overlay_from_stcs( @widget_should_be_loaded def remove_overlay(self, overlay_name: Union[Iterable[str], str]) -> None: - """Remove an overlay layer defined by an STC-S string. + """Remove an overlay layer defined by a string. Parameters ---------- overlay_name : str, Iterable[str] - The STC-S string //or an iterable of STC-S strings. + The string or an iterable of strings. """ overlay_name = [overlay_name] if isinstance(overlay_name, str) else overlay_name @@ -974,6 +994,15 @@ def remove_overlay(self, overlay_name: Union[Iterable[str], str]) -> None: } ) + @widget_should_be_loaded + def get_overlays(self) -> List: + """Update the current overlays defined by their names.""" + self.send( + { + "event_name": "get_overlays", + } + ) + @widget_should_be_loaded def set_color_map(self, color_map_name: str) -> None: """Change the color map of the Aladin Lite widget. @@ -1039,6 +1068,8 @@ def set_listener(self, listener_type: str, callback: Callable) -> None: self.listener_callback["click"] = callback elif listener_type == "select": self.listener_callback["select"] = callback + elif listener_type == "current_overlays": + self.listener_callback["current_overlays"] = callback else: raise ValueError( "listener_type must be 'object_hovered', " From e61afb056250cd1d99014015be49e980f23c3b38 Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Fri, 18 Jul 2025 15:19:23 -0400 Subject: [PATCH 20/22] basic testing to assess if messages are sent for get/remove functionality --- src/tests/test_aladin.py | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/tests/test_aladin.py b/src/tests/test_aladin.py index 1f659fb2..9ac5c538 100644 --- a/src/tests/test_aladin.py +++ b/src/tests/test_aladin.py @@ -239,3 +239,47 @@ def test_add_table(monkeypatch: Callable) -> None: "conversion_maj_axis": 1, } assert table_sent_message["options"]["ellipse_error"] == ellipse_options + + +test_overlay_names = [ + "overlay", + ["overlay", "overlay_1", "2MASS"], + "catalog", + ["overlay_1", "2MASS"], +] + + +@pytest.mark.parametrize("overlay_names", test_overlay_names) +def test_remove_overlay( + monkeypatch: Callable, + overlay_names: Union[Iterable[str], str], +) -> None: + """Test proper messages sent for removing overlays using their name string(s). + + Parameters + ---------- + overlay_names : Union[Iterable[str], str] + The name strings of overlays. + + """ + mock_send = Mock() + monkeypatch.setattr(Aladin, "send", mock_send) + aladin.remove_overlay(overlay_names) + name_info = mock_send.call_args[0][0]["name"] + assert isinstance(name_info, list) + assert name_info[0] in overlay_names + + if isinstance(overlay_names, list): + assert name_info == overlay_names + + +def test_get_overlays( + monkeypatch: Callable, +) -> None: + """Test proper message sent for getting current overlays.""" + mock_send = Mock() + monkeypatch.setattr(Aladin, "send", mock_send) + aladin.get_overlays() + event_name = mock_send.call_args[0][0]["event_name"] + assert isinstance(event_name, str) + assert event_name == "get_overlays" From fbeda98db0110d36f1fbd1a507de733a639de24f Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Fri, 18 Jul 2025 15:49:56 -0400 Subject: [PATCH 21/22] updating the order --- src/ipyaladin/widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index b1d42afa..23e88b77 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -260,8 +260,8 @@ def _handle_custom_message(self, _: any, message: dict, buffers: any) -> None: elif event_type == "save_view_as_image": self._save_file(message["path"], buffers[0]) elif event_type == "current_overlays": - self.listener_callback["current_overlays"](message["content"]) self._overlays = message["content"]["overlays"] + self.listener_callback["current_overlays"](message["content"]) @property def selected_objects(self) -> List[Table]: From fefe2bbfeaa1b3cc64ec1ba5f8aa415d1d7241e0 Mon Sep 17 00:00:00 2001 From: Celia Parts Date: Mon, 21 Jul 2025 15:57:46 -0400 Subject: [PATCH 22/22] implementing suggestions from Patrick --- js/models/message_handler.js | 2 +- src/ipyaladin/widget.py | 12 ++++++++---- src/tests/test_aladin.py | 7 ++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/js/models/message_handler.js b/js/models/message_handler.js index 2d1660e6..28c9e266 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -141,7 +141,7 @@ export default class MessageHandler { } handleRemoveOverlay = (msg) => { - const overlay_names = msg["name"]; + const overlay_names = msg["overlay_names"]; for (const overlay_name of overlay_names) { console.info(`Sending removeOverlay for ${overlay_name}`); this.aladin.removeOverlay(overlay_name); diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 23e88b77..d5240821 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -985,12 +985,14 @@ def remove_overlay(self, overlay_name: Union[Iterable[str], str]) -> None: The string or an iterable of strings. """ - overlay_name = [overlay_name] if isinstance(overlay_name, str) else overlay_name + overlay_names = ( + [overlay_name] if isinstance(overlay_name, str) else overlay_name + ) self.send( { "event_name": "remove_overlay", - "name": overlay_name, + "overlay_names": overlay_names, } ) @@ -1054,7 +1056,8 @@ def set_listener(self, listener_type: str, callback: Callable) -> None: Parameters ---------- listener_type : str - Can either be 'object_hovered', 'object_clicked', 'click' or 'select' + Can either be 'object_hovered', 'object_clicked', 'click', 'select', + or 'current_overlays' callback : Callable A python function to be called when the event corresponding to the listener_type is detected @@ -1073,7 +1076,8 @@ def set_listener(self, listener_type: str, callback: Callable) -> None: else: raise ValueError( "listener_type must be 'object_hovered', " - "'object_clicked', 'click' or 'select'" + "'object_clicked', 'click', 'select', " + "or 'current_overlays'" ) @widget_should_be_loaded diff --git a/src/tests/test_aladin.py b/src/tests/test_aladin.py index 9ac5c538..df3b4129 100644 --- a/src/tests/test_aladin.py +++ b/src/tests/test_aladin.py @@ -265,7 +265,12 @@ def test_remove_overlay( mock_send = Mock() monkeypatch.setattr(Aladin, "send", mock_send) aladin.remove_overlay(overlay_names) - name_info = mock_send.call_args[0][0]["name"] + + event_name = mock_send.call_args[0][0]["event_name"] + assert isinstance(event_name, str) + assert event_name == "remove_overlay" + + name_info = mock_send.call_args[0][0]["overlay_names"] assert isinstance(name_info, list) assert name_info[0] in overlay_names