@quantumwake/terminal-ux-dashboard-components 0.1.20 → 0.1.22

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.cjs CHANGED
@@ -281,6 +281,9 @@ var DEFAULT_CHART_STYLE = {
281
281
  height: 0,
282
282
  margin: null,
283
283
  maxXTicks: 0,
284
+ maxYTicks: 0,
285
+ areaOpacity: 0.15,
286
+ barLabels: true,
284
287
  seriesColors: []
285
288
  };
286
289
  var DEFAULT_SERIES_COLORS = [
@@ -573,9 +576,11 @@ function makeAxis(style, axis, columnName, opts2 = {}) {
573
576
  out.tickRotation = rotate;
574
577
  out.format = (v) => formatVal(v, s, numeric);
575
578
  }
579
+ const maxTicks = isX ? s.maxXTicks : s.maxYTicks;
580
+ if (numeric && maxTicks > 0) out.tickValues = maxTicks;
576
581
  return out;
577
582
  }
578
- function BarView({ records, groupColumn, valueColumn, aggFn = "count", data: presetData, style }) {
583
+ function BarView({ records, groupColumn, valueColumn, aggFn = "count", data: presetData, layout = "vertical", style }) {
579
584
  const computed = react.useMemo(() => {
580
585
  if (presetData || !records) return [];
581
586
  const groups = groupBy(records, groupColumn);
@@ -584,18 +589,24 @@ function BarView({ records, groupColumn, valueColumn, aggFn = "count", data: pre
584
589
  const data = presetData || computed;
585
590
  const s = withStyleDefaults(style);
586
591
  const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 20, bottom: 60, left: 60 });
592
+ const horizontal = layout === "horizontal";
593
+ const plotted = horizontal ? [...data].reverse() : data;
594
+ const axisBottom = horizontal ? makeAxis(style, "x", valueColumn, { numeric: true }) : makeAxis(style, "x", groupColumn);
595
+ const axisLeft = horizontal ? makeAxis(style, "y", groupColumn) : makeAxis(style, "y", valueColumn, { numeric: true });
587
596
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
588
597
  bar.ResponsiveBar,
589
598
  {
590
- data,
599
+ data: plotted,
591
600
  keys: ["value"],
592
601
  indexBy: "group",
602
+ layout,
593
603
  margin,
594
604
  padding: 0.3,
595
605
  colors: [s.seriesColors[0] || "rgba(74, 222, 128, 0.8)"],
596
606
  borderColor: { from: "color", modifiers: [["darker", 1.6]] },
597
- axisBottom: makeAxis(style, "x", groupColumn),
598
- axisLeft: makeAxis(style, "y", valueColumn, { numeric: true }),
607
+ axisBottom,
608
+ axisLeft,
609
+ enableLabel: s.barLabels,
599
610
  labelSkipWidth: 12,
600
611
  labelSkipHeight: 12,
601
612
  labelTextColor: { from: "color", modifiers: [["darker", 3]] },
@@ -641,7 +652,7 @@ function PieView({ records, groupColumn, data: presetData, style }) {
641
652
  }
642
653
  ) });
643
654
  }
644
- function LineView({ records, xColumn, yColumn, data: presetData, style }) {
655
+ function LineView({ records, xColumn, yColumn, data: presetData, dashedIds, style }) {
645
656
  const computed = react.useMemo(() => {
646
657
  if (presetData || !records) return [];
647
658
  const sorted = [...records].filter((r) => r[xColumn] != null && r[yColumn] != null).sort((a, b) => {
@@ -661,7 +672,21 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
661
672
  serie.id,
662
673
  s.seriesColors.length || data.length > 1 ? seriesColor(i, s) : "rgba(96, 165, 250, 0.9)"
663
674
  ]));
664
- const tickValues = thinTicks(data[0]?.data.map((d) => d.x) ?? [], s.maxXTicks);
675
+ const longest = data.reduce((a, b) => b.data.length > a.data.length ? b : a, { id: "", data: [] });
676
+ const tickValues = thinTicks(longest.data.map((d) => d.x), s.maxXTicks);
677
+ const dashed = new Set(dashedIds || []);
678
+ const linesLayer = ({ series, lineGenerator }) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: series.map((serie) => /* @__PURE__ */ jsxRuntime.jsx(
679
+ "path",
680
+ {
681
+ d: lineGenerator(serie.data.map((d) => d.position)),
682
+ fill: "none",
683
+ stroke: serie.color,
684
+ strokeWidth: 2,
685
+ strokeLinecap: "round",
686
+ strokeDasharray: dashed.has(String(serie.id)) ? "1 5" : void 0
687
+ },
688
+ serie.id
689
+ )) });
665
690
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
666
691
  line.ResponsiveLine,
667
692
  {
@@ -670,10 +695,10 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
670
695
  xScale: { type: "point" },
671
696
  yScale: { type: "linear", min: "auto", max: "auto" },
672
697
  curve: "monotoneX",
673
- enableArea: true,
674
- areaOpacity: 0.15,
698
+ enableArea: s.areaOpacity > 0,
699
+ areaOpacity: s.areaOpacity,
675
700
  colors: ((serie) => colorById.get(serie.id)),
676
- pointSize: (data[0]?.data.length ?? 0) > 50 ? 0 : 6,
701
+ pointSize: 0,
677
702
  pointColor: { theme: "background" },
678
703
  pointBorderWidth: 2,
679
704
  pointBorderColor: { from: "serieColor" },
@@ -681,11 +706,12 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
681
706
  axisBottom: { ...makeAxis(style, "x", xColumn), ...tickValues ? { tickValues } : {} },
682
707
  axisLeft: makeAxis(style, "y", yColumn, { numeric: true }),
683
708
  useMesh: true,
709
+ layers: ["grid", "markers", "axes", "areas", linesLayer, "crosshair", "slices", "mesh", "legends"],
684
710
  theme: buildNivoTheme(style)
685
711
  }
686
712
  ) });
687
713
  }
688
- function SparklineView({ data, height = 56, color = "#3987e5" }) {
714
+ function SparklineView({ data, height = 56, color = "#3987e5", showValue = false, format }) {
689
715
  const gradientId = react.useId();
690
716
  const width = 260;
691
717
  const pts = data && data.length ? data : [0];
@@ -694,13 +720,18 @@ function SparklineView({ data, height = 56, color = "#3987e5" }) {
694
720
  const xy = (v, i) => [i * dx, height - v / max * (height - 4) - 2];
695
721
  const line = pts.map((v, i) => `${i === 0 ? "M" : "L"} ${xy(v, i)[0].toFixed(1)} ${xy(v, i)[1].toFixed(1)}`).join(" ");
696
722
  const area = `${line} L ${width} ${height} L 0 ${height} Z`;
697
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: `0 0 ${width} ${height}`, height, className: "w-full", preserveAspectRatio: "none", children: [
698
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
699
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: "0.25" }),
700
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
701
- ] }) }),
702
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: area, fill: `url(#${gradientId})` }),
703
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: line, fill: "none", stroke: color, strokeWidth: "2", vectorEffect: "non-scaling-stroke" })
723
+ const current = pts[pts.length - 1];
724
+ const readout = format ? format(current) : current.toLocaleString(void 0, { maximumFractionDigits: 1 });
725
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
726
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: `0 0 ${width} ${height}`, height, className: "w-full", preserveAspectRatio: "none", children: [
727
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
728
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: "0.25" }),
729
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
730
+ ] }) }),
731
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: area, fill: `url(#${gradientId})` }),
732
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: line, fill: "none", stroke: color, strokeWidth: "2", vectorEffect: "non-scaling-stroke" })
733
+ ] }),
734
+ showValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-1 top-0 font-mono text-lg text-midnight-text-primary", children: readout })
704
735
  ] });
705
736
  }
706
737
  function ScatterView({ records, xColumn, yColumn, data: presetData, style }) {