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
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Changelog

## Unreleased — next minor
## 0.7.0 — 2026-10-14

- **Breaking:** group grid/circle styles and appearance overrides by visual element (`line`, `text`, `point`, `focus`, and scale subgroups). Replace flat style keys, preserve nested partial updates, and allow independent Q/VSWR theme widths. See the [migration guide](docs/migration-next.md).
- **Breaking:** group trace style options and snapshots into `line: { width, tolerancePx }` and `point: { radius }`. Add `TraceStyleOptions` for nested partial patches, reject unknown keys, and return detached readonly style snapshots.
- Allow `new SmithScales(target, appearance?)` to configure and mount independent parameter scales in one call, while preserving deferred mounting.
- Refresh the demo and example styling, add syntax highlighting and formatted example source, and streamline CI with shared build artifacts and parallel checks.

- **Breaking:** group grid/circle styles and appearance overrides by visual element (`line`, `text`, `point`, `focus`, and scale subgroups). Replace flat style keys, preserve nested partial updates, and allow independent Q/VSWR theme widths. See the [migration guide](docs/migration-0.7.md).
- Allow `new Smith(target, options?)` to configure and mount a chart with one call, accepting the same CSS selector or HTMLElement as `draw()`. Keep deferred mounting with `new Smith(options)`.

## 0.6.0 — 2026-10-14
Expand Down
16 changes: 8 additions & 8 deletions demo/measurements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,24 +174,24 @@ export class Measurements {
});
modeLabel.append(mode);
appearance.append(modeLabel);
for (const [key, caption] of [
['lineWidth', 'Line width (px)'],
['pointRadius', 'Point radius (px)'],
['lineTolerancePx', 'Line tolerance (px, 0 = full)'],
for (const [group, key, caption, current] of [
['line', 'width', 'Line width (px)', trace.line.width],
['point', 'radius', 'Point radius (px)', trace.point.radius],
['line', 'tolerancePx', 'Line tolerance (px, 0 = full)', trace.line.tolerancePx],
] as const) {
const label = document.createElement('label');
label.textContent = caption + ' ';
const input = document.createElement('input');
input.type = 'number';
input.min = key === 'lineTolerancePx' ? '0' : '0.1';
input.min = key === 'tolerancePx' ? '0' : '0.1';
input.step = 'any';
input.value = String(trace[key]);
input.value = String(current);
input.addEventListener('change', () => {
if (!input.value || !input.checkValidity() || !Number.isFinite(Number(input.value))) {
input.value = String(trace[key]);
input.value = String(current);
return;
}
this.smith.setTraceOptions(trace.id, { [key]: Number(input.value) });
this.smith.setTraceOptions(trace.id, { [group]: { [key]: Number(input.value) } });
this.changed();
});
label.append(input);
Expand Down
9 changes: 5 additions & 4 deletions docs/api-review.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Public API review and compatibility policy

Reviewed against **0.6.0 and the next minor API changes**, including grouped visual styles, optional constructor mounting, compact trace input, line simplification, and Touchstone reflection I/O,
Reviewed against **0.7.0**, including grouped visual styles, optional constructor mounting, compact trace input, line simplification, and Touchstone reflection I/O,
including the installed integration examples and the subsequent React/Angular
lifecycle verification. Version 0.3.0 used positional constructor arguments,
interactive defaults, and an automatic marker. See [migration to 0.4](migration-0.4.md).
Expand Down Expand Up @@ -112,8 +112,9 @@ arbitrary side effects from application callbacks.
hides geometry, cancels queued readings, and clears the readout. Enabling waits
for a new pointer movement. `cursorReading` retains the last position.

`SmithScales` is a separate component whose constructor takes only
`SmithAppearance`. It does not inherit chart options or listen to chart events
`SmithScales` is a separate component configured with `SmithAppearance`.
Like `Smith`, it optionally accepts a CSS selector or `HTMLElement` first for
immediate mounting. It does not inherit chart options or listen to chart events
implicitly. Consumers select the source reading with `update(Complex | null)`.
Keeping this constructor focused avoids grid/interaction options that do not apply.

Expand Down Expand Up @@ -310,7 +311,7 @@ block 1.0; future additions must respect the public boundary above.

## Trace display accuracy

`TraceOptions.lineTolerancePx` is a per-trace display setting, shared by `addTrace()`
`TraceOptions.line.tolerancePx` is a per-trace display setting, shared by `addTrace()`
and `setTraceOptions()`, and reported in `TraceInfo`. Its default is zero, retaining
full line geometry. Finite non-negative CSS pixel values bound additional geometric
deviation; invalid values throw `RangeError` before mutation. It never changes
Expand Down
29 changes: 25 additions & 4 deletions docs/api/smithkit.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ export interface SmithReading {
// @public
export class SmithScales {
constructor(appearance?: SmithAppearance);
constructor(target: string | HTMLElement, appearance?: SmithAppearance);
// (undocumented)
destroy(): void;
// (undocumented)
Expand Down Expand Up @@ -764,10 +765,14 @@ export interface TraceInfo extends Readonly<TraceStyle> {
// (undocumented)
readonly id: string;
// (undocumented)
readonly line: Readonly<TraceStyle['line']>;
// (undocumented)
readonly markers: readonly MarkerInfo[];
// (undocumented)
readonly name: string;
// (undocumented)
readonly point: Readonly<TraceStyle['point']>;
// (undocumented)
readonly sampleCount: number;
// (undocumented)
readonly visible: boolean;
Expand All @@ -777,7 +782,7 @@ export interface TraceInfo extends Readonly<TraceStyle> {
export type TraceInput = TraceSamples | readonly TraceTuple[] | Float64Array;

// @public (undocumented)
export interface TraceOptions extends Partial<TraceStyle> {
export interface TraceOptions extends TraceStyleOptions {
color?: string;
// (undocumented)
name?: string;
Expand All @@ -801,11 +806,27 @@ export type TraceSamples = readonly TraceSample[];

// @public (undocumented)
export interface TraceStyle {
lineTolerancePx: number;
lineWidth: number;
// (undocumented)
line: {
width: number;
tolerancePx: number;
};
// (undocumented)
mode: TraceRenderMode;
pointRadius: number;
// (undocumented)
point: {
radius: number;
};
}

// @public
export interface TraceStyleOptions {
// (undocumented)
line?: Partial<TraceStyle['line']>;
// (undocumented)
mode?: TraceRenderMode;
// (undocumented)
point?: Partial<TraceStyle['point']>;
}

// @public
Expand Down
8 changes: 5 additions & 3 deletions docs/guide/scales.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ Mount `SmithScales` independently so its twelve axes stay outside chart zoom:
```ts
import { SmithScales, SmithEventType } from 'smithkit';

const scales = new SmithScales();
scales.draw('#smith-scales'); // Provide a separate mounted container.
const scales = new SmithScales('#smith-scales', { theme: 'dark' });
const stopScales = chart.onEvent((event) => {
if (event.type === SmithEventType.Cursor || event.type === SmithEventType.Marker) {
const gamma = event.data?.reflectionCoefficient ?? null;
Expand All @@ -28,7 +27,10 @@ const stopScales = chart.onEvent((event) => {
```

`update(Complex | null)` synchronizes indicators, values, tooltips, and accessible
labels. Null, non-finite, or active-load inputs hide indicators. `draw` accepts a
labels. Null, non-finite, or active-load inputs hide indicators.
The constructor optionally accepts a CSS selector or `HTMLElement`, followed by
`SmithAppearance`. For deferred mounting, use `new SmithScales(appearance)` then
`draw(target)`. `draw` accepts a
selector or `HTMLElement`; `destroy` is idempotent. Scales adapt to container width.

Labels follow the complete Smith chart terminology: **Reflection loss**,
Expand Down
20 changes: 15 additions & 5 deletions docs/guide/traces.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Invalid replacements leave data, markers, and rendering unchanged.
For more than 5,000 samples, point rendering groups overlapping points into screen
cells and skips offscreen points; markers still select from the full data. Lines
retain every sample by default; opt into pixel-based simplification with
`lineTolerancePx` as described under [trace appearance](#trace-appearance).
`line.tolerancePx` as described under [trace appearance](#trace-appearance).
Sorted ascending frequencies accelerate frequency selection; unsorted inputs remain
supported without reordering. There is no interpolation or reduction of the stored measurements.

Expand Down Expand Up @@ -145,10 +145,20 @@ after destruction throw; trace/marker lookups return empty or missing results.

## Trace appearance

Pass `mode: 'points' | 'line' | 'both'`, `lineWidth`, `pointRadius`, and `lineTolerancePx` to
Pass `mode: 'points' | 'line' | 'both'`, `line.width`, `point.radius`, and `line.tolerancePx` to
`addTrace` or `setTraceOptions`. Defaults are points, 2 px line width, and 2 px point radius. Both sizes are
CSS pixels and remain constant under chart zoom and container resize. Widths and radii must be positive and finite.
`getTraces()` includes the current style.
`getTraces()` includes the current style in detached, readonly nested objects.
Updates merge individual properties, preserving omitted line and point settings.

```ts
chart.setTraceOptions(traceId, {
mode: 'both',
line: { width: 3, tolerancePx: 0.5 },
point: { radius: 4 },
});
chart.setTraceOptions(traceId, { line: { width: 2 } }); // Keeps tolerance and radius.
```

By default, lines connect all samples in input order, without smoothing or frequency sorting.
A line-only trace creates one SVG path and no sample circles, suitable for dense
Expand All @@ -160,11 +170,11 @@ snapping, readouts, and comparisons.
Styles do not change marker identity or layer ordering. Hidden traces retain their style after sample replacement.
The demo exposes the same controls per trace.

For dense lines, opt into `lineTolerancePx` (finite, non-negative; default `0` disables
For dense lines, opt into `line.tolerancePx` (finite, non-negative; default `0` disables
simplification):

```ts
chart.setTraceOptions(traceId, { mode: 'line', lineTolerancePx: 0.5 });
chart.setTraceOptions(traceId, { mode: 'line', line: { tolerancePx: 0.5 } });
```

The tolerance bounds additional geometric deviation in **CSS pixels**, accounting for
Expand Down
40 changes: 38 additions & 2 deletions docs/migration-next.md → docs/migration-0.7.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Migration from 0.6.x to the next minor
# Migration from 0.6.x to 0.7.0

These changes are unreleased and require a minor version during 0.x development.
Version 0.7.0 changes the visual configuration schema.
The old flat visual style keys are removed; they are not compatibility aliases.
Default appearance, interaction, grid detail, and trace behavior remain unchanged.

Expand Down Expand Up @@ -30,6 +30,32 @@ Use `GridStyleOptions` / `CircleStyleOptions` for partial patches instead of
properties; for example, changing `text.color` preserves the font and line style.
Unknown keys and invalid nested values are rejected before changing the chart.

## Trace styles

| Previous trace key | New trace key |
| ------------------ | ------------------ |
| `lineWidth` | `line.width` |
| `lineTolerancePx` | `line.tolerancePx` |
| `pointRadius` | `point.radius` |

The new shape applies to `addTrace()`, `setTraceOptions()`, and `getTraces()`:

```ts
const traceId = chart.addTrace(samples, {
mode: 'both',
line: { width: 2, tolerancePx: 0.5 },
point: { radius: 3 },
});
chart.setTraceOptions(traceId, { line: { width: 4 } });
// The tolerance and point radius are preserved.
console.log(chart.getTraces()[0].line.width);
```

Use `TraceStyleOptions` for partial style patches rather than `Partial<TraceStyle>`.
Snapshots have readonly, detached `line` and `point` objects. Unknown keys and
invalid nested values throw before changing the trace. Defaults remain points,
2 px line width, 2 px point radius, and no line simplification.

## Theme overrides

The `appearance: { theme, overrides }` wrapper and replacement semantics stay the
Expand Down Expand Up @@ -70,3 +96,13 @@ The first argument is a CSS selector or an `HTMLElement`. It is optional: existi
`new Smith(options)` followed by `draw(target)` still works. Data and markers are
added through the existing methods. The target is separate from configuration so
`setOptions()` keeps the chart in its current container.

`SmithScales` supports the same optional mounting argument, followed by its
independent appearance configuration:

```ts
const scales = new SmithScales('#scales', { theme: 'dark' });
```

`new SmithScales(appearance)` followed by `draw(target)` remains available.
Scales do not inherit chart settings or subscribe to chart events automatically.
4 changes: 2 additions & 2 deletions docs/migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ new integration, start with the [README](../README.md) and the
[API documentation](https://rosek86.github.io/smithkit/api/).
When skipping versions, apply the relevant migrations in version order.

## 0.6.x to the next minor (unreleased)
## 0.6.x to 0.7.0

Visual styles are grouped by element and chart construction can mount directly
into a container. Follow the [next minor migration guide](migration-next.md).
into a container. Follow the [0.7 migration guide](migration-0.7.md).

## 0.4.x to 0.5.0

Expand Down
2 changes: 1 addition & 1 deletion docs/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ the zoom handler. Input shape alone is not a reliable predictor of rendering cos

## Optional line simplification — 2026-10-09

`lineTolerancePx` defaults to 0 (full geometry). With a positive tolerance, nested
`line.tolerancePx` defaults to 0 (full geometry). With a positive tolerance, nested
radial-distance levels cache ordered sample indices. Each level accounts for the
accumulated error of earlier levels; selection uses the chart's CSS scale and zoom.
Panning and zooming within a level do not rewrite the path. Crossing a level rewrites
Expand Down
43 changes: 43 additions & 0 deletions docs/releases/0.7.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Smithkit 0.7.0

This release groups visual configuration by element and adds optional constructor
mounting for charts and independent parameter scales.

## Configuration changes

- Trace styles use `line: { width, tolerancePx }` and `point: { radius }`.
`setTraceOptions()` merges individual nested properties. `getTraces()` returns
detached, readonly nested style snapshots.
- Grid and constant-circle styles use `line` and `text` groups. Appearance overrides
group grid, scales, cursor, marker, and trace settings by visual element.
- Invalid or unknown style options are rejected before changing the chart.
- Chart defaults remain unchanged: standard impedance grid, labels visible,
peripheral scales, zoom and cursor disabled, and no implicit markers.

These are breaking changes from 0.6.x. Update flat style keys using the
[migration guide](https://github.com/rosek86/smithkit/blob/v0.7.0/docs/migration-0.7.md).
No compatibility aliases are retained.

## Mounting and examples

```ts
const chart = new Smith('#chart', { appearance: { theme: 'dark' } });
const scales = new SmithScales('#scales', { theme: 'dark' });
const traceId = chart.addTrace(samples, {
mode: 'both',
line: { width: 2, tolerancePx: 0.5 },
point: { radius: 3 },
});
```

Both constructors accept an `HTMLElement` instead of a selector. Deferred mounting
with `draw()` remains available. Scales stay independent of chart configuration
and events.

The demo and integration examples share updated styling, formatted source, and
syntax highlighting. The [API reference](https://rosek86.github.io/smithkit/api/)
and installed-package checks cover the new option shapes and constructor overloads.

```sh
npm install smithkit@0.7.0
```
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ npm run dev
```

To test local library changes, run `npm pack` from the repository root, then
`npm install --no-save --package-lock=false ../smithkit-0.6.0.tgz` in `examples`.
`npm install --no-save --package-lock=false ../smithkit-0.7.0.tgz` in `examples`.
Use the archive's absolute path when running a copied gallery.

`npm run build` creates the complete standalone gallery in `dist/`. It imports the
Expand Down
4 changes: 2 additions & 2 deletions examples/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ A standalone application importing only the installed `smithkit` package. It has
no source aliases, relative imports into the library, or dependency on demo code.
Use Node.js 24 and npm.

Install the declared `smithkit@^0.5.0` dependency and start the example:
Install the declared `smithkit@^0.7.0` dependency and start the example:

```sh
npm install
npm run dev
```

To test local library changes, run `npm pack` from the repository root, then
`npm install --no-save --package-lock=false ../../smithkit-0.5.0.tgz` here.
`npm install --no-save --package-lock=false ../../smithkit-0.7.0.tgz` here.
The example can be copied into a separate project; use the archive's absolute path
when testing a copied example against the local checkout.

Expand Down
2 changes: 1 addition & 1 deletion examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"preview": "vite preview --host 127.0.0.1"
},
"dependencies": {
"smithkit": "^0.6.0"
"smithkit": "^0.7.0"
},
"devDependencies": {
"shiki": "4.5.0",
Expand Down
4 changes: 2 additions & 2 deletions examples/large-trace/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ chart.draw('#chart');
const traceId = chart.addTrace(createSamples(count), {
name: 'Synthetic sweep',
mode: 'line',
lineTolerancePx: 0.5,
line: { tolerancePx: 0.5 },
});
const markerId = chart.addMarker(traceId)!;
const slider = document.querySelector<HTMLInputElement>('#sample')!;
Expand All @@ -47,7 +47,7 @@ renderReading();

const detail = document.querySelector<HTMLSelectElement>('#line-detail')!;
detail.addEventListener('change', () => {
chart.setTraceOptions(traceId, { lineTolerancePx: Number(detail.value) });
chart.setTraceOptions(traceId, { line: { tolerancePx: Number(detail.value) } });
});

const sampleCount = document.querySelector<HTMLSelectElement>('#sample-count')!;
Expand Down
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"preview": "vite preview --host 127.0.0.1"
},
"dependencies": {
"smithkit": "^0.6.0",
"smithkit": "^0.7.0",
"react": "19.3.0",
"react-dom": "19.3.0",
"@angular/core": "22.2.2",
Expand Down
Loading
Loading