@tangle-network/charts 0.9.0 → 0.10.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as IntervalMethod, C as BreakdownInput, D as Exclusion, E as Estimate, F as Tier, I as TierCounts, L as isRefusal, M as RateRow, N as Refusal, O as Figure, P as Setup, S as YTick, T as CostBasis, _ as MarkVerdict, a as timeline, b as YScale, c as OUTCOME_ORDER, d as PointFields, f as PointGlyph, g as MarkKind, h as ChartMark, i as TimelineTick, j as MatrixCell, k as Interval, l as TickOutcome, m as ChartBand, n as TimelineOptions, o as CHECKER_HUES, p as BandKind, r as TimelineSpan, s as OUTCOME_COLORS, t as TimelineLane, u as checkerColor, v as MarkerShape, w as ComparisonRow, x as YTarget, y as XCategory } from "./timeline-CNHABOS1.js";
1
+ import { A as IntervalMethod, C as BreakdownInput, D as Exclusion, E as Estimate, F as Tier, I as TierCounts, L as isRefusal, M as RateRow, N as Refusal, O as Figure, P as Setup, S as YTick, T as CostBasis, _ as MarkVerdict, a as timeline, b as YScale, c as OUTCOME_ORDER, d as PointFields, f as PointGlyph, g as MarkKind, h as ChartMark, i as TimelineTick, j as MatrixCell, k as Interval, l as TickOutcome, m as ChartBand, n as TimelineOptions, o as CHECKER_HUES, p as BandKind, r as TimelineSpan, s as OUTCOME_COLORS, t as TimelineLane, u as checkerColor, v as MarkerShape, w as ComparisonRow, x as YTarget, y as XCategory } from "./timeline-irTei5Fl.js";
2
2
  //#region src/block.d.ts
3
3
  interface RenderFigureOptions {
4
4
  /** Chart uses a closed data disclosure; plot keeps only the SVG and accessible data. */
@@ -232,6 +232,10 @@ interface TimeSeriesOptions {
232
232
  bands?: ChartBand[];
233
233
  /** What each point `marker` stands for, such as `{ circle: "check", diamond: "gate" }`, named in the figure's key. */
234
234
  markers?: Partial<Record<MarkerShape, string>>;
235
+ /** The wide render's width in pixels, such as the measured container (at least 720, the default). */
236
+ width?: number;
237
+ /** false leaves out the series legend under the plot, for a caller that names its series itself. The verdict key stays. */
238
+ legend?: boolean;
235
239
  id?: string;
236
240
  }
237
241
  export declare function timeSeries(rows: TimeSeriesRow[], o: TimeSeriesOptions): Figure | Refusal;
@@ -291,6 +295,8 @@ interface SmallMultiplesOptions {
291
295
  markers?: Partial<Record<MarkerShape, string>>;
292
296
  formatX?: (value: number) => string;
293
297
  formatY?: (value: number) => string;
298
+ /** The wide render's width in pixels, such as the measured container (at least 720, the default). */
299
+ width?: number;
294
300
  id?: string;
295
301
  }
296
302
  export declare function smallMultiples(panels: MultiplePanel[], o: SmallMultiplesOptions): Figure | Refusal;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as esc, A as pts, B as MARKER_SHAPES, C as duration, D as kn, E as intervalName, F as tierSummary, G as line, H as hatch, I as tierTotal, J as rect, K as markerPath, L as usd, M as rateIntervalGap, N as rateOrder, O as pct, P as tierAtLeast, Q as capitalize, R as usdTick, S as drawable, T as intervalGap, V as circle, W as hbar, X as text, Y as svgRoot, Z as titled, a as checkerClass, at as wrap, b as TIERS_BEST_FIRST, d as drawGroups, et as fitLines, f as drawMarks, g as markLabelRows, h as groupRowHeight, i as OUTCOME_ORDER, it as textWidth, j as rateDataGap, k as perPass, l as MARK_VERDICTS, m as eventsTable, n as CHECKER_HUES, nt as plural, o as checkerColor, p as eventsGap, q as polyline, r as OUTCOME_COLORS, rt as textBlock, s as EVENTS_READ, t as timeline, tt as listJoin, u as drawBands, v as isRefusal, w as estimateNote, x as costText, y as METHOD_NAME, z as table } from "./timeline-BAwebuqb.js";
1
+ import { $ as capitalize, A as pts, B as MARKER_SHAPES, C as duration, D as kn, E as intervalName, F as tierSummary, G as line, H as hatch, I as tierTotal, J as rect, K as markerPath, L as usd, M as rateIntervalGap, N as rateOrder, O as pct, P as tierAtLeast, Q as wideWidth, R as usdTick, S as drawable, T as intervalGap, V as circle, W as hbar, X as text, Y as svgRoot, Z as titled, a as checkerClass, at as textWidth, b as TIERS_BEST_FIRST, d as drawGroups, et as esc, f as drawMarks, g as markLabelRows, h as groupRowHeight, i as OUTCOME_ORDER, it as textBlock, j as rateDataGap, k as perPass, l as MARK_VERDICTS, m as eventsTable, n as CHECKER_HUES, nt as listJoin, o as checkerColor, ot as wrap, p as eventsGap, q as polyline, r as OUTCOME_COLORS, rt as plural, s as EVENTS_READ, t as timeline, tt as fitLines, u as drawBands, v as isRefusal, w as estimateNote, x as costText, y as METHOD_NAME, z as table } from "./timeline-ApeJgFac.js";
2
2
  //#region src/block.ts
3
3
  /**
4
4
  * The figure block: one markup for every figure on every surface.
@@ -2641,10 +2641,6 @@ function timeSeries(rows, o) {
2641
2641
  const xLabel = (x) => o.formatX ? o.formatX(x) : category.get(x) ?? String(x);
2642
2642
  const yLabel = (y) => scalarLabel(y, o.y.unit, o.formatY);
2643
2643
  const grid = yGridlines(o.y, yLabel);
2644
- if (axisGutter(grid) >= 270) return {
2645
- id,
2646
- refused: "Formatted y-axis labels leave no room for the phone chart. Use a shorter formatter or unit."
2647
- };
2648
2644
  const flat = rows.flatMap((row) => row.points.map((point) => ({
2649
2645
  row,
2650
2646
  point
@@ -2656,6 +2652,14 @@ function timeSeries(rows, o) {
2656
2652
  const hasEvents = marks.length + bands.length > 0;
2657
2653
  const groups = bands.some((band) => band.kind === "group");
2658
2654
  const stripName = o.y.strip?.trim() || "no value";
2655
+ if (axisGutter(grid) >= 270) return {
2656
+ id,
2657
+ refused: "Formatted y-axis labels leave no room for the phone chart. Use a shorter formatter or unit."
2658
+ };
2659
+ if (stripped.length && axisGutter(grid, stripName) >= 270) return {
2660
+ id,
2661
+ refused: "The strip name leaves no room for the phone chart. Use a shorter y.strip."
2662
+ };
2659
2663
  const valueText = (point) => point.y !== null ? yLabel(point.y) : point.verdict !== void 0 ? `${stripName} (${VERDICT_WORD[point.verdict]})` : "not measured";
2660
2664
  const facts = (row, point) => [
2661
2665
  row.label,
@@ -2697,7 +2701,7 @@ function timeSeries(rows, o) {
2697
2701
  lede: `${measured.length} of ${flat.length} positions have a recorded value.${stripped.length ? ` ${stripped.length} recorded ${plural(stripped.length, "verdict")} without a value ${stripped.length === 1 ? "sits" : "sit"} in the strip under the plot.` : ""}`,
2698
2702
  read: `Points show recorded values. Lines connect adjacent measured positions; missing positions break the line. Whiskers show recorded intervals.${recorded ? " A filled mark is a pass, an outline a fail, a dashed outline undecided; * is not comparable with the goal and ? of unknown comparability; ×n counts the recorded rows a mark stands for." : ""}${stripped.length ? ` Hatched squares under the plot are verdicts recorded without a value (${stripName}).` : ""}${o.y.targets?.length ? " Shaded bands are recorded targets; dashed bands are stretch targets." : ""}${groups ? " Brackets above the plot group positions, such as one run's releases." : ""}${hasEvents ? ` ${EVENTS_READ}` : ""}`,
2699
2703
  svg: {
2700
- wide: plot(rows, o, 720, xLabel, yLabel, grid, facts, stripName),
2704
+ wide: plot(rows, o, wideWidth(o.width), xLabel, yLabel, grid, facts, stripName),
2701
2705
  narrow: plot(rows, o, 358, xLabel, yLabel, grid, facts, stripName),
2702
2706
  interactive: true
2703
2707
  },
@@ -2710,14 +2714,14 @@ function timeSeries(rows, o) {
2710
2714
  };
2711
2715
  }
2712
2716
  function plot(rows, o, width, xLabel, yLabel, grid, facts, stripName) {
2713
- const left = axisGutter(grid);
2717
+ const strip = rows.some((row) => row.points.some((point) => point.y === null && point.verdict !== void 0)) ? 24 : 0;
2718
+ const left = axisGutter(grid, strip ? stripName : void 0);
2714
2719
  const right = width - 24;
2715
2720
  const axis = xAxis(o.x.domain, o.x.categories, left, right);
2716
2721
  const px = axis.px;
2717
2722
  const labelRows = markLabelRows(o.marks ?? [], px, left, right);
2718
2723
  const top = 36 + (labelRows ? labelRows * 14 + 2 : 0) + groupRowHeight(o.bands), bottom = top + 224;
2719
2724
  const py = yScale(o.y.domain, o.y.scale, top, bottom);
2720
- const strip = rows.some((row) => row.points.some((point) => point.y === null && point.verdict !== void 0)) ? 24 : 0;
2721
2725
  let marks = text(left, 18, o.y.label, { cls: "tgc-ink-muted" });
2722
2726
  for (const [i, tick] of grid.entries()) marks += line(left, py(tick.at), right, py(tick.at), i === 0 && !o.y.ticks?.length ? "tgc-axis" : "tgc-gridline") + text(left - 8, py(tick.at) + 4, tick.label, {
2723
2727
  anchor: "end",
@@ -2831,7 +2835,7 @@ function plot(rows, o, width, xLabel, yLabel, grid, facts, stripName) {
2831
2835
  marks += wrapSeries(lines);
2832
2836
  points += wrapSeries(own);
2833
2837
  const legendKey = `${row.label}\u0000${row.colorIndex ?? `s${seriesIndex}`}`;
2834
- if (legend.has(legendKey)) continue;
2838
+ if (o.legend === false || legend.has(legendKey)) continue;
2835
2839
  legend.add(legendKey);
2836
2840
  const label = wrap(row.label, right - left - 32, 12, "sans", 8);
2837
2841
  marks += wrapSeries(`<g style="stroke-dasharray:${dash}">${line(left, legendY - 4, left + 24, legendY - 4, "tgc-series-line")}</g>` + (rows.length > 1 ? `<path class="tgc-series-key" d="${markerPath(row.colorIndex !== void 0 ? "circle" : MARKER_SHAPES[ord % MARKER_SHAPES.length], left + 12, legendY - 4, 3.5)}"/>` : "")) + textBlock(label.lines, left + 32, legendY, 16, "class=\"tgc-ink\" font-size=\"12\"");
@@ -2844,8 +2848,8 @@ function plot(rows, o, width, xLabel, yLabel, grid, facts, stripName) {
2844
2848
  const events = drawMarks(o.marks ?? [], px, top - groupRowHeight(o.bands), bottom, left, right, xLabel, 22);
2845
2849
  return `<svg class="tgc-svg tgc-trajectories" xmlns="http://www.w3.org/2000/svg" width="${width}" height="${legendY + 12}" viewBox="0 0 ${width} ${legendY + 12}" role="group" aria-label="${esc(o.y.label)} by ${esc(o.x.label)}"><style>${rules}</style>${marks}${events}${points}${badges}${tips}</svg>`;
2846
2850
  }
2847
- function axisGutter(ticks) {
2848
- return Math.max(64, ...ticks.map((tick) => Math.ceil(textWidth(tick.label, 12, "mono")) + 20));
2851
+ function axisGutter(ticks, stripName) {
2852
+ return Math.max(64, ...ticks.map((tick) => Math.ceil(textWidth(tick.label, 12, "mono")) + 20), stripName ? Math.ceil(textWidth(stripName, 11)) + 14 : 0);
2849
2853
  }
2850
2854
  //#endregion
2851
2855
  //#region src/small-multiples.ts
@@ -3011,7 +3015,7 @@ function smallMultiples(panels, o) {
3011
3015
  lede: `${withData.length} of ${panels.length} ${plural(panels.length, noun)} have data${ended.length ? `; ${ended.length} ended before the window closed` : ""}.`,
3012
3016
  read: `Each panel is one ${noun} on ${o.shared === "both" ? "the same x and y axes" : "the same x axis; y axes differ per panel"}. Hatched panels have no data and name the reason. A vertical rule with a cross marks where a line ended.${recorded ? " A filled mark is a pass, an outline a fail; * is not comparable with the goal and ? of unknown comparability; ✓ marks a solve and ✕ a failing candidate." : ""}${targets.length ? " Shaded bands are recorded targets; dashed bands are stretch targets." : ""}${panels.some((p) => p.scale === "log") ? " Log-scale panels say so in their y labels." : ""}`,
3013
3017
  svg: {
3014
- wide: draw(panels, o, 720, xLabel, yLabelOf, marksOf),
3018
+ wide: draw(panels, o, wideWidth(o.width), xLabel, yLabelOf, marksOf),
3015
3019
  narrow: draw(panels, o, 358, xLabel, yLabelOf, marksOf)
3016
3020
  },
3017
3021
  table: table(`${capitalize(o.y.label)} by ${o.x.label} and ${noun}`, [
@@ -1,4 +1,4 @@
1
- import { N as Refusal, O as Figure, S as YTick, _ as MarkVerdict, b as YScale, d as PointFields, f as PointGlyph, g as MarkKind, h as ChartMark, i as TimelineTick, l as TickOutcome, m as ChartBand, n as TimelineOptions, p as BandKind, r as TimelineSpan, t as TimelineLane, v as MarkerShape, x as YTarget, y as XCategory } from "../timeline-CNHABOS1.js";
1
+ import { N as Refusal, O as Figure, S as YTick, _ as MarkVerdict, b as YScale, d as PointFields, f as PointGlyph, g as MarkKind, h as ChartMark, i as TimelineTick, l as TickOutcome, m as ChartBand, n as TimelineOptions, p as BandKind, r as TimelineSpan, t as TimelineLane, v as MarkerShape, x as YTarget, y as XCategory } from "../timeline-irTei5Fl.js";
2
2
  import { ReactElement, ReactNode } from "react";
3
3
  //#region src/react/sparkline.d.ts
4
4
  type SparklineDirection = "rising" | "falling" | "flat";
@@ -248,12 +248,19 @@ export declare function Gantt({ rows, lanes: laneInput, colors, axis, span, mark
248
248
  }): import("react").JSX.Element;
249
249
  //#endregion
250
250
  //#region src/react/figure-view.d.ts
251
+ /** A figure drawn for a width: FigureView calls it with its container's measured width (at least 720 px). */
252
+ type FigureAtWidth = (width: number) => Figure | Refusal;
251
253
  interface FigureViewProps {
252
- figure: Figure | Refusal;
254
+ /**
255
+ * A figure, or a function that draws one for a width. With a function the wide render is drawn at the container's
256
+ * width, in 32 px steps, so its text and marks keep their set size on a wide page instead of being scaled up from 720.
257
+ * Memoize the function: a new function redraws the figure.
258
+ */
259
+ figure: Figure | Refusal | FigureAtWidth;
253
260
  /** `chart` (default) keeps the lede, reading and method in the disclosure; `report` also shows the finding and lede. */
254
261
  presentation?: 'chart' | 'report';
255
262
  }
256
- export declare function FigureView({ figure, presentation }: FigureViewProps): import("react").JSX.Element;
263
+ export declare function FigureView({ figure: given, presentation }: FigureViewProps): import("react").JSX.Element;
257
264
  //#endregion
258
265
  //#region src/react/timeline-view.d.ts
259
266
  interface TimelineViewProps {
@@ -265,4 +272,4 @@ interface TimelineViewProps {
265
272
  }
266
273
  export declare function TimelineView({ lanes, options, defaultCollapsed, presentation }: TimelineViewProps): import("react").JSX.Element;
267
274
  //#endregion
268
- export type { BandKind, ChartBand, ChartMark, Figure, FigureViewProps, 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 };
275
+ export type { BandKind, ChartBand, ChartMark, Figure, FigureAtWidth, FigureViewProps, 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 };
@@ -1,4 +1,4 @@
1
- import { K as markerPath, U as hatchPath, _ as markName, c as MARK_HEADS, p as eventsGap, t as timeline, v as isRefusal } from "../timeline-BAwebuqb.js";
1
+ import { K as markerPath, U as hatchPath, _ as markName, c as MARK_HEADS, p as eventsGap, t as timeline, v as isRefusal } from "../timeline-ApeJgFac.js";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Fragment as Fragment$1, useEffect, useId, useMemo, useRef, useState } from "react";
4
4
  //#region src/react/sparkline.tsx
@@ -1626,8 +1626,10 @@ function Gantt({ rows, lanes: laneInput, colors, axis, span, marks = [], now, ha
1626
1626
  //#region src/react/figure-view.tsx
1627
1627
  /** Embeds a static Figure or Refusal in React: the wide or phone render chosen by the container's width, the data
1628
1628
  * table in a disclosure. The SVG and table strings come from this library's figure functions, which escape input. */
1629
- function FigureView({ figure, presentation = "chart" }) {
1629
+ function FigureView({ figure: given, presentation = "chart" }) {
1630
1630
  const [ref, width] = useWidth();
1631
+ const drawn = width >= 720 ? Math.floor(width / 32) * 32 : 720;
1632
+ const figure = useMemo(() => typeof given === "function" ? given(drawn) : given, [given, drawn]);
1631
1633
  if (isRefusal(figure)) return /* @__PURE__ */ jsx("p", {
1632
1634
  className: "ov-refusal",
1633
1635
  role: "note",
@@ -1698,9 +1700,10 @@ function TimelineView({ lanes, options, defaultCollapsed = [], presentation }) {
1698
1700
  const [collapsed, setCollapsed] = useState(defaultCollapsed);
1699
1701
  const box = useRef(null);
1700
1702
  const refocus = useRef(null);
1701
- const figure = useMemo(() => timeline(lanes, {
1703
+ const figure = useMemo(() => (width) => timeline(lanes, {
1702
1704
  ...options,
1703
- collapsed
1705
+ collapsed,
1706
+ width
1704
1707
  }), [
1705
1708
  lanes,
1706
1709
  options,
@@ -300,14 +300,13 @@ function listJoin(items) {
300
300
  function capitalize(text) {
301
301
  return text.charAt(0).toUpperCase() + text.slice(1);
302
302
  }
303
- //#endregion
304
- //#region src/svg.ts
305
303
  /**
306
- * SVG marks. Every mark carries a class and `figure.css` maps classes to the
307
- * `--chart-*` tokens, so a render holds no colour and follows the page theme.
308
- * Geometry stays in attributes, so an SVG shown without the stylesheet keeps
309
- * its layout.
304
+ * The wide render's width for a caller-measured `width` (a figure's container): at least `WIDE`, whole pixels. A figure
305
+ * drawn at its container's width keeps text and marks at their set size instead of being scaled up from 720 px.
310
306
  */
307
+ function wideWidth(width) {
308
+ return width !== void 0 && Number.isFinite(width) && width > 720 ? Math.floor(width) : 720;
309
+ }
311
310
  const r2 = (n) => Math.round(n * 100) / 100;
312
311
  function svgRoot(width, height, inner) {
313
312
  const h = Math.ceil(height);
@@ -1112,7 +1111,7 @@ function timeline(lanes, o) {
1112
1111
  ...marks.length + bands.length ? [EVENTS_READ] : []
1113
1112
  ].join(" "),
1114
1113
  svg: {
1115
- wide: draw(720),
1114
+ wide: draw(wideWidth(o.width)),
1116
1115
  narrow: draw(358),
1117
1116
  ...folds ? { interactive: true } : {}
1118
1117
  },
@@ -1182,4 +1181,4 @@ function axisTicks(t0, t1, px, left, right, label) {
1182
1181
  return fit([t0, t1]) ? [t0, t1] : [t0];
1183
1182
  }
1184
1183
  //#endregion
1185
- export { esc as $, pts as A, MARKER_SHAPES as B, duration as C, kn as D, intervalName as E, tierSummary as F, line as G, hatch as H, tierTotal as I, rect as J, markerPath as K, usd as L, rateIntervalGap as M, rateOrder as N, pct as O, tierAtLeast as P, capitalize as Q, usdTick as R, drawable as S, intervalGap as T, hatchPath as U, circle as V, hbar as W, text as X, svgRoot as Y, titled as Z, markName as _, checkerClass as a, wrap as at, TIERS_BEST_FIRST as b, MARK_HEADS as c, drawGroups as d, fitLines as et, drawMarks as f, markLabelRows as g, groupRowHeight as h, OUTCOME_ORDER as i, textWidth as it, rateDataGap as j, perPass as k, MARK_VERDICTS as l, eventsTable as m, CHECKER_HUES as n, plural as nt, checkerColor as o, eventsGap as p, polyline as q, OUTCOME_COLORS as r, textBlock as rt, EVENTS_READ as s, timeline as t, listJoin as tt, drawBands as u, isRefusal as v, estimateNote as w, costText as x, METHOD_NAME as y, table as z };
1184
+ export { capitalize as $, pts as A, MARKER_SHAPES as B, duration as C, kn as D, intervalName as E, tierSummary as F, line as G, hatch as H, tierTotal as I, rect as J, markerPath as K, usd as L, rateIntervalGap as M, rateOrder as N, pct as O, tierAtLeast as P, wideWidth as Q, usdTick as R, drawable as S, intervalGap as T, hatchPath as U, circle as V, hbar as W, text as X, svgRoot as Y, titled as Z, markName as _, checkerClass as a, textWidth as at, TIERS_BEST_FIRST as b, MARK_HEADS as c, drawGroups as d, esc as et, drawMarks as f, markLabelRows as g, groupRowHeight as h, OUTCOME_ORDER as i, textBlock as it, rateDataGap as j, perPass as k, MARK_VERDICTS as l, eventsTable as m, CHECKER_HUES as n, listJoin as nt, checkerColor as o, wrap as ot, eventsGap as p, polyline as q, OUTCOME_COLORS as r, plural as rt, EVENTS_READ as s, timeline as t, fitLines as tt, drawBands as u, isRefusal as v, estimateNote as w, costText as x, METHOD_NAME as y, table as z };
@@ -286,6 +286,8 @@ interface TimelineOptions {
286
286
  */
287
287
  collapsed?: string[];
288
288
  formatTime?: (ms: number) => string;
289
+ /** The wide render's width in pixels, such as the measured container (at least 720, the default). */
290
+ width?: number;
289
291
  id?: string;
290
292
  }
291
293
  declare function timeline(lanes: TimelineLane[], o: TimelineOptions): Figure | Refusal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/charts",
3
- "version": "0.9.0",
3
+ "version": "0.10.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",