@tangle-network/charts 0.20.3 → 0.21.0

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.
@@ -277,6 +277,31 @@ export declare function Gantt({ rows, lanes: laneInput, colors, axis, span, mark
277
277
  hatch?: string[];
278
278
  }): import("react").JSX.Element;
279
279
  //#endregion
280
+ //#region src/react/gap.d.ts
281
+ interface GapBand {
282
+ min: number;
283
+ max: number;
284
+ }
285
+ interface GapProps {
286
+ value: number;
287
+ /** A bound, not a measurement: the true value is at most (upper) or at least (lower) `value`; drawn as an open arrow. */
288
+ bound?: 'upper' | 'lower' | null;
289
+ target: GapBand;
290
+ stretch?: GapBand | null;
291
+ scale?: 'log' | 'linear';
292
+ format?: (value: number) => string;
293
+ /** The value mark's color; the caller's state color. */
294
+ tone?: string;
295
+ /** Hover text for each mark; defaults name the numbers. */
296
+ titles?: {
297
+ value?: string;
298
+ target?: string;
299
+ stretch?: string;
300
+ };
301
+ label?: string;
302
+ }
303
+ export declare function Gap({ value, bound, target, stretch, scale, format, tone, titles, label }: GapProps): import("react").JSX.Element;
304
+ //#endregion
280
305
  //#region src/react/figure-view.d.ts
281
306
  /** A figure drawn for a width: FigureView calls it with its container's measured width (at least 720 px). */
282
307
  type FigureAtWidth = (width: number) => Figure | Refusal;
@@ -391,4 +416,4 @@ interface FlowWaterfallProps {
391
416
  * Data remains producer-owned; playback, zoom and folding change presentation only. */
392
417
  export declare function FlowWaterfall({ trace, live, startedAt, label, defaultCollapsed, defaultView, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill, selectedId, onDeselect, description, summary: showSummary }: FlowWaterfallProps): import("react").JSX.Element;
393
418
  //#endregion
394
- export type { BandKind, ChartBand, ChartMark, DotMapLabel, DotMapProps, DotMapRect, Figure, FigureAtWidth, FigureViewProps, FlowWaterfallProps, LineSeries, MarkKind, MarkVerdict, MarkerShape, MeterSegment, PointFields, PointGlyph, Refusal, SparklineDirection, SparklineGeometry, SparklineGeometryOptions, SparklineLabelOptions, SparklinePoint, SparklineProps, SparklineValues, StackedBarBucket, StackedBarChartProps, StackedBarSegment, StackedBarSeries, TickOutcome, TimelineLane, TimelineOptions, TimelineSpan, TimelineTick, TimelineViewProps, WaterfallBarProps, WaterfallHeaderProps, WaterfallRowProps, WaterfallSpanGeometry, WaterfallTimeAxisProps, WaterfallWindow, XCategory, YScale, YTarget, YTick };
419
+ export type { BandKind, ChartBand, ChartMark, DotMapLabel, DotMapProps, DotMapRect, Figure, FigureAtWidth, FigureViewProps, FlowWaterfallProps, GapBand, GapProps, LineSeries, MarkKind, MarkVerdict, MarkerShape, MeterSegment, PointFields, PointGlyph, Refusal, SparklineDirection, SparklineGeometry, SparklineGeometryOptions, SparklineLabelOptions, SparklinePoint, SparklineProps, SparklineValues, StackedBarBucket, StackedBarChartProps, StackedBarSegment, StackedBarSeries, TickOutcome, TimelineLane, TimelineOptions, TimelineSpan, TimelineTick, TimelineViewProps, WaterfallBarProps, WaterfallHeaderProps, WaterfallRowProps, WaterfallSpanGeometry, WaterfallTimeAxisProps, WaterfallWindow, XCategory, YScale, YTarget, YTick };
@@ -1765,6 +1765,118 @@ function Gantt({ rows, lanes: laneInput, colors, axis, span, marks = [], now, ha
1765
1765
  });
1766
1766
  }
1767
1767
  //#endregion
1768
+ //#region src/react/gap.tsx
1769
+ /** One reading against its target band on one scale: how far a value sits from where it should be. Values, words and
1770
+ * colors belong to callers; the chart only places them. */
1771
+ const HEIGHT = 24;
1772
+ const MID = HEIGHT / 2;
1773
+ function Gap({ value, bound = null, target, stretch = null, scale = "log", format = formatCompact, tone = "var(--chart-live-accent, #8b7cf6)", titles = {}, label }) {
1774
+ const [ref, width] = useWidth();
1775
+ const log = scale === "log" && value > 0 && target.min > 0;
1776
+ const f = (v) => log ? Math.log10(v) : v;
1777
+ const ends = [
1778
+ value,
1779
+ target.min,
1780
+ target.max,
1781
+ ...stretch ? [stretch.min, stretch.max] : []
1782
+ ].map(f);
1783
+ const lo = Math.min(...ends);
1784
+ const hi = Math.max(...ends);
1785
+ const pad = Math.max((hi - lo) * .08, log ? .15 : Math.abs(hi) * .05 || 1);
1786
+ const x = (v) => width ? (f(v) - (lo - pad)) / (hi - lo + 2 * pad) * width : 0;
1787
+ const band = (b) => ({
1788
+ x: x(b.min),
1789
+ w: Math.max(4, x(b.max) - x(b.min))
1790
+ });
1791
+ const t = band(target);
1792
+ const s = stretch ? band(stretch) : null;
1793
+ const near = value < target.min ? x(target.min) : value > target.max ? x(target.max) : x(value);
1794
+ const vx = x(value);
1795
+ const range = (b) => b.min === b.max ? `≈${format(b.min)}` : `${format(b.min)}–${format(b.max)}`;
1796
+ const decades = log && width ? Array.from({ length: Math.floor(hi + pad) - Math.ceil(lo - pad) + 1 }, (_, i) => Math.ceil(lo - pad) + i) : [];
1797
+ const arrow = bound === "upper" ? `M${vx + 4},6 L${vx - 4},${MID} L${vx + 4},18` : `M${vx - 4},6 L${vx + 4},${MID} L${vx - 4},18`;
1798
+ return /* @__PURE__ */ jsx("div", {
1799
+ ref,
1800
+ className: "ov-gap",
1801
+ role: "img",
1802
+ "aria-label": label ?? `${bound === "upper" ? "≤" : bound === "lower" ? "≥" : ""}${format(value)} against ${range(target)}`,
1803
+ children: width > 0 && /* @__PURE__ */ jsxs("svg", {
1804
+ width,
1805
+ height: HEIGHT,
1806
+ viewBox: `0 0 ${width} ${HEIGHT}`,
1807
+ "aria-hidden": true,
1808
+ children: [
1809
+ /* @__PURE__ */ jsx("line", {
1810
+ className: "ov-gap-track",
1811
+ x1: 0,
1812
+ x2: width,
1813
+ y1: MID,
1814
+ y2: MID
1815
+ }),
1816
+ decades.map((d) => /* @__PURE__ */ jsx("line", {
1817
+ className: "ov-gap-tick",
1818
+ x1: x(10 ** d),
1819
+ x2: x(10 ** d),
1820
+ y1: 8,
1821
+ y2: 16
1822
+ }, d)),
1823
+ s && /* @__PURE__ */ jsx("rect", {
1824
+ className: "ov-gap-stretch",
1825
+ x: s.x,
1826
+ y: 4,
1827
+ width: s.w,
1828
+ height: 16,
1829
+ rx: 4,
1830
+ children: /* @__PURE__ */ jsx("title", { children: titles.stretch ?? `stretch ${range(stretch)}` })
1831
+ }),
1832
+ /* @__PURE__ */ jsx("rect", {
1833
+ className: "ov-gap-target",
1834
+ x: t.x,
1835
+ y: 4,
1836
+ width: t.w,
1837
+ height: 16,
1838
+ rx: 4,
1839
+ children: /* @__PURE__ */ jsx("title", { children: titles.target ?? `target ${range(target)}` })
1840
+ }),
1841
+ Math.abs(near - vx) > 1 && /* @__PURE__ */ jsx("line", {
1842
+ className: "ov-gap-span",
1843
+ x1: vx,
1844
+ x2: near,
1845
+ y1: MID,
1846
+ y2: MID,
1847
+ style: { stroke: tone }
1848
+ }),
1849
+ /* @__PURE__ */ jsxs("g", {
1850
+ className: "ov-gap-value",
1851
+ children: [
1852
+ /* @__PURE__ */ jsx("title", { children: titles.value ?? `${bound === "upper" ? "≤" : bound === "lower" ? "≥" : ""}${format(value)}` }),
1853
+ bound ? /* @__PURE__ */ jsx("path", {
1854
+ d: arrow,
1855
+ fill: "none",
1856
+ stroke: tone,
1857
+ strokeWidth: 2,
1858
+ strokeLinecap: "round",
1859
+ strokeLinejoin: "round"
1860
+ }) : /* @__PURE__ */ jsx("circle", {
1861
+ cx: vx,
1862
+ cy: MID,
1863
+ r: 5,
1864
+ fill: tone
1865
+ }),
1866
+ /* @__PURE__ */ jsx("rect", {
1867
+ x: vx - 8,
1868
+ y: 0,
1869
+ width: 16,
1870
+ height: HEIGHT,
1871
+ fill: "transparent"
1872
+ })
1873
+ ]
1874
+ })
1875
+ ]
1876
+ })
1877
+ });
1878
+ }
1879
+ //#endregion
1768
1880
  //#region src/react/figure-view.tsx
1769
1881
  /** Embeds a static Figure or Refusal in React: the wide or phone render chosen by the container's width, the data
1770
1882
  * table in a disclosure. The SVG and table strings come from this library's figure functions, which escape input. */
@@ -4792,4 +4904,4 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
4792
4904
  });
4793
4905
  }
4794
4906
  //#endregion
4795
- export { DEFAULT_SPARKLINE_EMPTY_LABEL, DEFAULT_SPARKLINE_HEIGHT, DEFAULT_SPARKLINE_LABEL, DEFAULT_SPARKLINE_UNAVAILABLE_LABEL, DEFAULT_SPARKLINE_WIDTH, DOT_MAP_CATEGORIES, DayBars, DotMap, Events, FigureView, FlowWaterfall, Gantt, HBars, Histogram, LIVE_SERIES, Lines, Meter, Spark, Sparkline, StackedBarChart, TimelineView, WaterfallBar, WaterfallHeader, WaterfallRow, WaterfallTimeAxis, formatCompact, formatSparklineValue, formatWaterfallDuration, sparklineGeometry, sparklineLabel, sparklinePointsAttribute, sparklineReadings, waterfallSpanGeometry, waterfallTicks };
4907
+ export { DEFAULT_SPARKLINE_EMPTY_LABEL, DEFAULT_SPARKLINE_HEIGHT, DEFAULT_SPARKLINE_LABEL, DEFAULT_SPARKLINE_UNAVAILABLE_LABEL, DEFAULT_SPARKLINE_WIDTH, DOT_MAP_CATEGORIES, DayBars, DotMap, Events, FigureView, FlowWaterfall, Gantt, Gap, HBars, Histogram, LIVE_SERIES, Lines, Meter, Spark, Sparkline, StackedBarChart, TimelineView, WaterfallBar, WaterfallHeader, WaterfallRow, WaterfallTimeAxis, formatCompact, formatSparklineValue, formatWaterfallDuration, sparklineGeometry, sparklineLabel, sparklinePointsAttribute, sparklineReadings, waterfallSpanGeometry, waterfallTicks };
@@ -89,3 +89,11 @@ line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%,
89
89
  .tgc-dot-map { color: var(--chart-live-muted, #8a8a8a); }
90
90
  .tgc-dot-map canvas:focus-visible { outline: 2px solid var(--chart-accent, #7760bd); outline-offset: 2px; }
91
91
  .tgc-dot-map-tip { z-index: 2; max-width: 300px; padding: 6px 9px; border-radius: 6px; background: var(--chart-tip-bg, #262626); color: var(--chart-tip-ink, #eee); font: 12px/1.4 ui-sans-serif, system-ui, sans-serif; white-space: pre-line; box-shadow: 0 4px 14px rgb(0 0 0 / .3); }
92
+ .ov-gap { width: 100%; min-width: 96px; height: 24px; }
93
+ .ov-gap svg { display: block; overflow: visible; }
94
+ .ov-gap-track { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 40%, transparent); stroke-width: 1; }
95
+ .ov-gap-tick { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 60%, transparent); stroke-width: 1; }
96
+ .ov-gap-target { fill: color-mix(in srgb, var(--chart-live-pass, #2f9e6e) 28%, transparent); stroke: var(--chart-live-pass, #2f9e6e); stroke-width: 1; }
97
+ .ov-gap-stretch { fill: none; stroke: var(--chart-live-pass, #2f9e6e); stroke-width: 1; stroke-dasharray: 3 3; }
98
+ .ov-gap-span { stroke-width: 2; stroke-dasharray: 2 4; stroke-linecap: round; }
99
+ .ov-gap-value { cursor: default; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/charts",
3
- "version": "0.20.3",
3
+ "version": "0.21.0",
4
4
  "description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
5
5
  "type": "module",
6
6
  "license": "MIT",