Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [0.2.40] - 2026-03-24

### Added
- `PlaySlider` now has a `values` property that returns all discrete values in the range, useful for pre-caching downstream results before hitting play.
- `ParallelCoordinates` now exposes a `selections` property that returns the full filtering state: completed Keep/Exclude steps plus the active brush, enabling decision-tree-style filtering audit trails.
- `ParallelCoordinates` now has `keep()`, `exclude()`, and `restore()` methods for programmatic control from Python.

### Fixed
- `PlaySlider` no longer produces floating-point rounding artifacts (e.g., `0.30000000000000004`) when using fractional step values. Both the displayed label and the synced Python value are now rounded to the step's precision.
- `ParallelCoordinates` axis tick labels no longer get highlighted during brush/drag interactions.

## [0.2.39] - 2026-03-17
Expand Down
2 changes: 1 addition & 1 deletion demos/play_slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# "marimo",
# "matplotlib",
# "numpy",
# "wigglystuff==0.2.37",
# "wigglystuff==0.2.40",
# ]
# ///
import marimo
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "wigglystuff"
version = "0.2.39"
version = "0.2.40"
description = "Collection of Anywidget Widgets"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions wigglystuff/play_slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,15 @@ def __init__(
width=width,
**kwargs,
)

@property
def values(self):
"""All discrete values from min_value to max_value (inclusive) at the current step."""
step_str = str(self.step)
precision = len(step_str.rstrip("0").split(".")[-1]) if "." in step_str else 0
result = []
v = self.min_value
while v <= self.max_value:
result.append(round(v, precision))
v += self.step
return result
14 changes: 11 additions & 3 deletions wigglystuff/static/play-slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,26 @@ function render({ model, el }) {
function renderValue() {
const val = model.get("value");
slider.value = val;
label.textContent = val;
label.textContent = val.toFixed(getPrecision());
updateTrackFill();
}

function renderBtn() {
btn.innerHTML = model.get("playing") ? PAUSE_ICON : PLAY_ICON;
}

function getPrecision() {
const s = String(model.get("step"));
const dot = s.indexOf(".");
return dot === -1 ? 0 : s.length - dot - 1;
}

function snap(val) {
const step = model.get("step");
const min = model.get("min_value");
return Math.round((val - min) / step) * step + min;
const prec = getPrecision();
const raw = Math.round((val - min) / step) * step + min;
return parseFloat(raw.toFixed(prec));
}

function tick() {
Expand Down Expand Up @@ -117,7 +125,7 @@ function render({ model, el }) {
// Manual slider input
slider.addEventListener("input", () => {
localUpdate = true;
model.set("value", parseFloat(slider.value));
model.set("value", snap(parseFloat(slider.value)));
model.save_changes();
updateTrackFill();
});
Expand Down
Loading