anywidget-vector 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/CHANGELOG.md +18 -2
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/PKG-INFO +1 -1
- anywidget_vector-0.3.2/assets/demo.png +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/examples/fashion-mnist-parallel-coords-6d.py +8 -11
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/pyproject.toml +2 -1
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/__init__.py +26 -14
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/styles.css +1 -4
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/uv.lock +1 -1
- anywidget_vector-0.3.1/assets/demo.png +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/.github/workflows/ci.yml +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/.github/workflows/pypi.yml +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/.gitignore +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/.python-version +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/LICENSE +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/README.md +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/examples/demo.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/examples/test_add_numpy.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/examples/test_projection.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/client.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/browser.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/client.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/embed.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/client.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/pinecone/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/pinecone/client.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/pinecone/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/client.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/weaviate/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/weaviate/client.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/weaviate/converter.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/demo.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/py.typed +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/static/icons.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/canvas.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/constants.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/properties.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/settings.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/sidebar.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/ui/toolbar.js +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/widget.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/tests/__init__.py +0 -0
- {anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/tests/test_widget.py +0 -0
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.2 (2026-03-16)
|
|
4
|
+
|
|
5
|
+
### Improvements
|
|
6
|
+
|
|
7
|
+
- **Marimo reactivity fix**: Removed camera and hover JS-to-Python sync to prevent continuous cell re-execution. Only user-initiated actions (selection, mode change) now trigger marimo reactive updates
|
|
8
|
+
- **Custom scroll zoom**: Replaced OrbitControls zoom with a custom wheel handler for much finer granularity
|
|
9
|
+
- **Selection hides completely**: Lasso/box selection now fully hides non-selected points (scale-to-zero for instanced meshes) instead of dimming
|
|
10
|
+
- **Auto zoom-to-fit on selection**: Camera automatically frames the selected points after lasso/box selection
|
|
11
|
+
- **Search filter modes**: Typing in the search bar dims non-matching points as a preview, pressing Run/Enter hides them completely
|
|
12
|
+
- **Hover via callback**: Properties panel hover now uses a direct JS callback instead of model sync, eliminating unnecessary Python round-trips
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- **setSelection scoping**: Moved `setSelection` helper to `createCanvas` scope so lasso/box/click handlers can access it
|
|
17
|
+
- **Camera debounce variable**: Fixed `_cameraDebounce` lexical declaration error by moving it to the correct scope
|
|
18
|
+
|
|
3
19
|
## 0.3.1 (2026-03-16)
|
|
4
20
|
|
|
5
21
|
### New Features
|
|
@@ -24,7 +40,7 @@
|
|
|
24
40
|
|
|
25
41
|
### New Features
|
|
26
42
|
|
|
27
|
-
- **Distance metrics sidebar**: Distance section with metric selector (euclidean, cosine, manhattan, dot product), configurable k-neighbors (0-50)
|
|
43
|
+
- **Distance metrics sidebar**: Distance section with metric selector (euclidean, cosine, manhattan, dot product), configurable k-neighbors (0-50) and live nearest-neighbor display for the selected point
|
|
28
44
|
- **Dimension mapping display**: Sidebar now shows active visual mapping fields: color field, size range, shape field and unique shape count
|
|
29
45
|
|
|
30
46
|
### Improvements
|
|
@@ -35,7 +51,7 @@
|
|
|
35
51
|
|
|
36
52
|
### New Features
|
|
37
53
|
|
|
38
|
-
- **6D parallel coordinates example**: Fashion-MNIST demo with PCA across 6+ dimensions, interactive axis mapping
|
|
54
|
+
- **6D parallel coordinates example**: Fashion-MNIST demo with PCA across 6+ dimensions, interactive axis mapping and shape mapping to categorical labels
|
|
39
55
|
|
|
40
56
|
## 0.2.7 (2026-03-15)
|
|
41
57
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anywidget-vector
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Interactive 3D vector visualization with query UI for vector databases
|
|
5
5
|
Project-URL: Homepage, https://grafeo.dev/
|
|
6
6
|
Project-URL: Repository, https://github.com/GrafeoDB/anywidget-vector
|
|
Binary file
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/examples/fashion-mnist-parallel-coords-6d.py
RENAMED
|
@@ -34,6 +34,7 @@ def _():
|
|
|
34
34
|
from wigglystuff import ParallelCoordinates
|
|
35
35
|
|
|
36
36
|
from anywidget_vector import VectorSpace
|
|
37
|
+
|
|
37
38
|
return PCA, ParallelCoordinates, VectorSpace, fetch_openml, mo, np, pl, plt
|
|
38
39
|
|
|
39
40
|
|
|
@@ -244,10 +245,12 @@ def _(LABEL_COLORS, ParallelCoordinates, df, mo, vs):
|
|
|
244
245
|
_indices = sorted(int(sid.split("_")[1]) for sid in _selected)
|
|
245
246
|
_filtered_df = df[_indices]
|
|
246
247
|
_par = ParallelCoordinates(_filtered_df, color_by="label", color_map=LABEL_COLORS)
|
|
247
|
-
mo.vstack(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
mo.vstack(
|
|
249
|
+
[
|
|
250
|
+
mo.md(f"**{len(_indices)}** points selected in 3D view"),
|
|
251
|
+
mo.ui.anywidget(_par),
|
|
252
|
+
]
|
|
253
|
+
)
|
|
251
254
|
else:
|
|
252
255
|
mo.md("*Lasso or box-select points in the 3D view to filter*")
|
|
253
256
|
return
|
|
@@ -258,13 +261,7 @@ def _(LABEL_COLORS, idx, images, label_names, labels, np, plt, vs, widget):
|
|
|
258
261
|
_selected_ids = set(vs.widget.selected_points or [])
|
|
259
262
|
_filtered = widget.widget.filtered_indices
|
|
260
263
|
|
|
261
|
-
if _selected_ids:
|
|
262
|
-
_show = [
|
|
263
|
-
_i for _i in range(len(idx))
|
|
264
|
-
if f"p_{_i}" in _selected_ids
|
|
265
|
-
][:10]
|
|
266
|
-
else:
|
|
267
|
-
_show = list(_filtered[:10])
|
|
264
|
+
_show = [_i for _i in range(len(idx)) if f"p_{_i}" in _selected_ids][:10] if _selected_ids else list(_filtered[:10])
|
|
268
265
|
|
|
269
266
|
_sample_idx = np.array(_show) if len(_show) > 0 else np.array([0])
|
|
270
267
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "anywidget-vector"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.2"
|
|
4
4
|
description = "Interactive 3D vector visualization with query UI for vector databases"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -73,6 +73,7 @@ select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF"]
|
|
|
73
73
|
|
|
74
74
|
[tool.ruff.lint.per-file-ignores]
|
|
75
75
|
"src/anywidget_vector/widget.py" = ["E501"] # Long lines in embedded JS
|
|
76
|
+
"src/anywidget_vector/ui/__init__.py" = ["E501"] # Long lines in embedded JS
|
|
76
77
|
"examples/**" = ["B007", "B018"] # Marimo cells use bare expressions for output
|
|
77
78
|
|
|
78
79
|
[tool.ty.environment]
|
|
@@ -134,11 +134,13 @@ function render({{ model, el }}) {{
|
|
|
134
134
|
|
|
135
135
|
el.appendChild(wrapper);
|
|
136
136
|
|
|
137
|
-
// Auto-detect host theme (
|
|
137
|
+
// Auto-detect host theme (Tailwind dark/dark-theme class, data-theme, or prefers-color-scheme)
|
|
138
138
|
function detectHostDark() {{
|
|
139
139
|
const html = document.documentElement;
|
|
140
|
-
if (html.classList.contains("dark")) return true;
|
|
140
|
+
if (html.classList.contains("dark") || html.classList.contains("dark-theme")) return true;
|
|
141
141
|
if (html.dataset.theme === "dark") return true;
|
|
142
|
+
if (document.body?.classList.contains("dark") || document.body?.classList.contains("dark-theme")) return true;
|
|
143
|
+
if (document.body?.dataset.theme === "dark") return true;
|
|
142
144
|
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) return true;
|
|
143
145
|
return false;
|
|
144
146
|
}}
|
|
@@ -149,27 +151,37 @@ function render({{ model, el }}) {{
|
|
|
149
151
|
model.save_changes();
|
|
150
152
|
}}
|
|
151
153
|
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
154
|
+
// Always auto-detect and observe theme changes
|
|
155
|
+
let autoTheme = true;
|
|
156
|
+
model.set("dark_mode", detectHostDark());
|
|
157
|
+
applyTheme(detectHostDark());
|
|
158
|
+
|
|
159
|
+
const themeObserver = new MutationObserver(() => {{
|
|
160
|
+
if (!autoTheme) return;
|
|
161
|
+
const dark = detectHostDark();
|
|
162
|
+
if (model.get("dark_mode") !== dark) {{
|
|
163
|
+
model.set("dark_mode", dark);
|
|
164
|
+
applyTheme(dark);
|
|
165
|
+
}}
|
|
166
|
+
}});
|
|
167
|
+
themeObserver.observe(document.documentElement, {{ attributes: true, attributeFilter: ["class", "data-theme", "style"] }});
|
|
168
|
+
if (document.body) {{
|
|
169
|
+
themeObserver.observe(document.body, {{ attributes: true, attributeFilter: ["class", "data-theme", "style"] }});
|
|
170
|
+
}}
|
|
171
|
+
if (window.matchMedia) {{
|
|
172
|
+
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {{
|
|
173
|
+
if (!autoTheme) return;
|
|
160
174
|
const dark = detectHostDark();
|
|
161
175
|
if (model.get("dark_mode") !== dark) {{
|
|
162
176
|
model.set("dark_mode", dark);
|
|
163
177
|
applyTheme(dark);
|
|
164
178
|
}}
|
|
165
179
|
}});
|
|
166
|
-
themeObserver.observe(document.documentElement, {{ attributes: true, attributeFilter: ["class", "data-theme"] }});
|
|
167
|
-
}} else {{
|
|
168
|
-
applyTheme(model.get("dark_mode"));
|
|
169
180
|
}}
|
|
170
181
|
|
|
171
|
-
// Manual toggle from settings panel
|
|
182
|
+
// Manual toggle from settings panel disables auto-theme
|
|
172
183
|
model.on("change:dark_mode", () => {{
|
|
184
|
+
autoTheme = false;
|
|
173
185
|
applyTheme(model.get("dark_mode"));
|
|
174
186
|
}});
|
|
175
187
|
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/client.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/chroma/converter.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/browser.js
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/client.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/converter.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/grafeo/embed.js
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/client.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/lancedb/converter.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/pinecone/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/pinecone/client.js
RENAMED
|
File without changes
|
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/client.js
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/qdrant/converter.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/weaviate/__init__.py
RENAMED
|
File without changes
|
{anywidget_vector-0.3.1 → anywidget_vector-0.3.2}/src/anywidget_vector/backends/weaviate/client.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|