@quantumwake/terminal-ux-dashboard-components 0.1.19 → 0.1.21

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.cts CHANGED
@@ -104,6 +104,12 @@ declare const shapeChartData: (chartType: ChartType, rows: Row[], { yFields }?:
104
104
  type LegendAnchor = 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';
105
105
  type LegendPosition = 'start' | 'middle' | 'end';
106
106
  type TitleAlign = 'left' | 'center' | 'right';
107
+ interface ChartMargin {
108
+ top: number;
109
+ right: number;
110
+ bottom: number;
111
+ left: number;
112
+ }
107
113
  interface ChartStyle {
108
114
  background: string;
109
115
  textColor: string;
@@ -135,8 +141,26 @@ interface ChartStyle {
135
141
  titleBold: boolean;
136
142
  titleBackground: string;
137
143
  titleColor: string;
144
+ height: number;
145
+ margin: Partial<ChartMargin> | null;
146
+ maxXTicks: number;
147
+ maxYTicks: number;
148
+ areaOpacity: number;
149
+ barLabels: boolean;
150
+ seriesColors: string[];
138
151
  }
139
152
  declare const DEFAULT_CHART_STYLE: ChartStyle;
153
+ declare const DEFAULT_SERIES_COLORS: string[];
154
+ declare const SERIES_OVERFLOW_COLOR = "#707078";
155
+ declare const seriesColor: (i: number, style?: Partial<ChartStyle> | null) => string;
156
+ declare const chartSizing: (style: Partial<ChartStyle> | null | undefined, defaultMargin: ChartMargin) => {
157
+ frameClass: string;
158
+ frameStyle: {
159
+ height?: number;
160
+ };
161
+ margin: ChartMargin;
162
+ };
163
+ declare function thinTicks<T>(values: T[], max: number): T[] | undefined;
140
164
  declare const LEGEND_ANCHORS: LegendAnchor[];
141
165
  declare const withStyleDefaults: (style?: Partial<ChartStyle> | null) => ChartStyle;
142
166
  declare const buildNivoTheme: (style?: Partial<ChartStyle> | null) => {
@@ -276,9 +300,12 @@ interface BarViewProps {
276
300
  aggFn?: string;
277
301
  /** Pre-aggregated [{group, value}] bypasses client-side aggregation. */
278
302
  data?: BarDatum[];
303
+ /** 'horizontal' lays categories on the y axis — the readable form for
304
+ * many bars with long names (labels never collide). Default vertical. */
305
+ layout?: 'vertical' | 'horizontal';
279
306
  style?: Partial<ChartStyle>;
280
307
  }
281
- declare function BarView({ records, groupColumn, valueColumn, aggFn, data: presetData, style }: BarViewProps): react.JSX.Element;
308
+ declare function BarView({ records, groupColumn, valueColumn, aggFn, data: presetData, layout, style }: BarViewProps): react.JSX.Element;
282
309
 
283
310
  interface PieDatum {
284
311
  id: string;
@@ -307,9 +334,22 @@ interface LineViewProps {
307
334
  yColumn: string;
308
335
  /** Pre-shaped Nivo line series bypasses client-side processing. */
309
336
  data?: LineSerie[];
337
+ /** Serie ids to draw dotted — the aggregate-vs-individual distinction
338
+ * (an average line reads as derived, a member line as observed). */
339
+ dashedIds?: string[];
310
340
  style?: Partial<ChartStyle>;
311
341
  }
312
- declare function LineView({ records, xColumn, yColumn, data: presetData, style }: LineViewProps): react.JSX.Element;
342
+ declare function LineView({ records, xColumn, yColumn, data: presetData, dashedIds, style }: LineViewProps): react.JSX.Element;
343
+
344
+ interface SparklineViewProps {
345
+ /** The series, oldest first. */
346
+ data: number[];
347
+ /** Viewbox height in px (the svg scales to its container's width). */
348
+ height?: number;
349
+ /** Line + area hue. */
350
+ color?: string;
351
+ }
352
+ declare function SparklineView({ data, height, color }: SparklineViewProps): react.JSX.Element;
313
353
 
314
354
  interface ScatterSerie {
315
355
  id: string;
@@ -606,4 +646,4 @@ interface DataExplorerProps {
606
646
  }
607
647
  declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, defaultMode, tabs, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
608
648
 
609
- export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, type ColorMethod, type ColorOptions, type ColorScope, DEFAULT_CHART_STYLE, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, HEAT_STATS, type HeatCell, type HeatPlusDatum, type HeatStat, HeatmapPlusView, type HeatmapPlusViewProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, PanelChart, type PanelChartProps, type PanelInput, type PanelLayout, type PanelRef, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, shapeChartData, useCapabilities, useDashboard, withStyleDefaults };
649
+ export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartMargin, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, type ColorMethod, type ColorOptions, type ColorScope, DEFAULT_CHART_STYLE, DEFAULT_SERIES_COLORS, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, HEAT_STATS, type HeatCell, type HeatPlusDatum, type HeatStat, HeatmapPlusView, type HeatmapPlusViewProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, PanelChart, type PanelChartProps, type PanelInput, type PanelLayout, type PanelRef, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, SERIES_OVERFLOW_COLOR, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SparklineView, type SparklineViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, chartSizing, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, seriesColor, shapeChartData, thinTicks, useCapabilities, useDashboard, withStyleDefaults };
package/dist/index.d.ts CHANGED
@@ -104,6 +104,12 @@ declare const shapeChartData: (chartType: ChartType, rows: Row[], { yFields }?:
104
104
  type LegendAnchor = 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';
105
105
  type LegendPosition = 'start' | 'middle' | 'end';
106
106
  type TitleAlign = 'left' | 'center' | 'right';
107
+ interface ChartMargin {
108
+ top: number;
109
+ right: number;
110
+ bottom: number;
111
+ left: number;
112
+ }
107
113
  interface ChartStyle {
108
114
  background: string;
109
115
  textColor: string;
@@ -135,8 +141,26 @@ interface ChartStyle {
135
141
  titleBold: boolean;
136
142
  titleBackground: string;
137
143
  titleColor: string;
144
+ height: number;
145
+ margin: Partial<ChartMargin> | null;
146
+ maxXTicks: number;
147
+ maxYTicks: number;
148
+ areaOpacity: number;
149
+ barLabels: boolean;
150
+ seriesColors: string[];
138
151
  }
139
152
  declare const DEFAULT_CHART_STYLE: ChartStyle;
153
+ declare const DEFAULT_SERIES_COLORS: string[];
154
+ declare const SERIES_OVERFLOW_COLOR = "#707078";
155
+ declare const seriesColor: (i: number, style?: Partial<ChartStyle> | null) => string;
156
+ declare const chartSizing: (style: Partial<ChartStyle> | null | undefined, defaultMargin: ChartMargin) => {
157
+ frameClass: string;
158
+ frameStyle: {
159
+ height?: number;
160
+ };
161
+ margin: ChartMargin;
162
+ };
163
+ declare function thinTicks<T>(values: T[], max: number): T[] | undefined;
140
164
  declare const LEGEND_ANCHORS: LegendAnchor[];
141
165
  declare const withStyleDefaults: (style?: Partial<ChartStyle> | null) => ChartStyle;
142
166
  declare const buildNivoTheme: (style?: Partial<ChartStyle> | null) => {
@@ -276,9 +300,12 @@ interface BarViewProps {
276
300
  aggFn?: string;
277
301
  /** Pre-aggregated [{group, value}] bypasses client-side aggregation. */
278
302
  data?: BarDatum[];
303
+ /** 'horizontal' lays categories on the y axis — the readable form for
304
+ * many bars with long names (labels never collide). Default vertical. */
305
+ layout?: 'vertical' | 'horizontal';
279
306
  style?: Partial<ChartStyle>;
280
307
  }
281
- declare function BarView({ records, groupColumn, valueColumn, aggFn, data: presetData, style }: BarViewProps): react.JSX.Element;
308
+ declare function BarView({ records, groupColumn, valueColumn, aggFn, data: presetData, layout, style }: BarViewProps): react.JSX.Element;
282
309
 
283
310
  interface PieDatum {
284
311
  id: string;
@@ -307,9 +334,22 @@ interface LineViewProps {
307
334
  yColumn: string;
308
335
  /** Pre-shaped Nivo line series bypasses client-side processing. */
309
336
  data?: LineSerie[];
337
+ /** Serie ids to draw dotted — the aggregate-vs-individual distinction
338
+ * (an average line reads as derived, a member line as observed). */
339
+ dashedIds?: string[];
310
340
  style?: Partial<ChartStyle>;
311
341
  }
312
- declare function LineView({ records, xColumn, yColumn, data: presetData, style }: LineViewProps): react.JSX.Element;
342
+ declare function LineView({ records, xColumn, yColumn, data: presetData, dashedIds, style }: LineViewProps): react.JSX.Element;
343
+
344
+ interface SparklineViewProps {
345
+ /** The series, oldest first. */
346
+ data: number[];
347
+ /** Viewbox height in px (the svg scales to its container's width). */
348
+ height?: number;
349
+ /** Line + area hue. */
350
+ color?: string;
351
+ }
352
+ declare function SparklineView({ data, height, color }: SparklineViewProps): react.JSX.Element;
313
353
 
314
354
  interface ScatterSerie {
315
355
  id: string;
@@ -606,4 +646,4 @@ interface DataExplorerProps {
606
646
  }
607
647
  declare function DataExplorer({ records, columns, states, activeStateId, profile, dashboard, dashboardId, savedDashboards, loading, analyzing, defaultMode, tabs, onSelectState, onRefreshStates, }: DataExplorerProps): react.JSX.Element;
608
648
 
609
- export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, type ColorMethod, type ColorOptions, type ColorScope, DEFAULT_CHART_STYLE, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, HEAT_STATS, type HeatCell, type HeatPlusDatum, type HeatStat, HeatmapPlusView, type HeatmapPlusViewProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, PanelChart, type PanelChartProps, type PanelInput, type PanelLayout, type PanelRef, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, shapeChartData, useCapabilities, useDashboard, withStyleDefaults };
649
+ export { type AggFn, type BarDatum, BarView, type BarViewProps, ChartBuilder, type ChartBuilderColumn, type ChartBuilderProps, type ChartConfig, type ChartField, type ChartFilter, type ChartMargin, type ChartPanel, type ChartStyle, ChartStyleControls, type ChartStyleControlsProps, type ChartType, type ColorMethod, type ColorOptions, type ColorScope, DEFAULT_CHART_STYLE, DEFAULT_SERIES_COLORS, type Dashboard$1 as Dashboard, type DashboardCapabilities, type DashboardContextValue, type DashboardPanel$1 as DashboardPanel, DashboardProvider, type DashboardProviderProps, DashboardRenderer, type DashboardRendererProps, type DashboardTheme, DataExplorer, type DataExplorerProps, HEAT_STATS, type HeatCell, type HeatPlusDatum, type HeatStat, HeatmapPlusView, type HeatmapPlusViewProps, type HeatmapSerie, HeatmapView, type HeatmapViewProps, type InsightConfig, InsightView, type InsightViewProps, LEGEND_ANCHORS, type LegendAnchor, type LegendPosition, type LineSerie, LineView, type LineViewProps, type MetricConfig, MetricView, type MetricViewProps, PanelChart, type PanelChartProps, type PanelInput, type PanelLayout, type PanelRef, type PieDatum, PieView, type PieViewProps, PivotView, type PivotViewProps, type QueryResult, type Row, SERIES_OVERFLOW_COLOR, type SavedDashboard, type ScatterSerie, ScatterView, type ScatterViewProps, SparklineView, type SparklineViewProps, SqlConsole, type SqlConsoleColumn, type SqlConsoleProps, type TitleAlign, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, chartSizing, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, seriesColor, shapeChartData, thinTicks, useCapabilities, useDashboard, withStyleDefaults };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useContext, useMemo, useState, useEffect, useRef, useCallback, Suspense } from 'react';
1
+ import { createContext, useContext, useMemo, useId, useState, useEffect, useRef, useCallback, Suspense } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { interpolateRdYlGn } from 'd3-scale-chromatic';
4
4
  import { ResponsiveBar } from '@nivo/bar';
@@ -268,8 +268,57 @@ var DEFAULT_CHART_STYLE = {
268
268
  titleAlign: "left",
269
269
  titleBold: false,
270
270
  titleBackground: "",
271
- titleColor: ""
271
+ titleColor: "",
272
+ // Chart frame + series color model.
273
+ height: 0,
274
+ margin: null,
275
+ maxXTicks: 0,
276
+ maxYTicks: 0,
277
+ areaOpacity: 0.15,
278
+ barLabels: true,
279
+ seriesColors: []
272
280
  };
281
+ var DEFAULT_SERIES_COLORS = [
282
+ "#3987e5",
283
+ // blue
284
+ "#d95926",
285
+ // orange
286
+ "#199e70",
287
+ // aqua
288
+ "#c98500",
289
+ // yellow
290
+ "#d55181",
291
+ // magenta
292
+ "#008300",
293
+ // green
294
+ "#9085e9",
295
+ // violet
296
+ "#e66767"
297
+ // red
298
+ ];
299
+ var SERIES_OVERFLOW_COLOR = "#707078";
300
+ var seriesColor = (i, style) => {
301
+ const s = withStyleDefaults(style);
302
+ const palette = s.seriesColors.length ? s.seriesColors : DEFAULT_SERIES_COLORS;
303
+ return i < palette.length ? palette[i] : SERIES_OVERFLOW_COLOR;
304
+ };
305
+ var chartSizing = (style, defaultMargin) => {
306
+ const s = withStyleDefaults(style);
307
+ return {
308
+ frameClass: s.height > 0 ? "w-full" : "h-full w-full min-h-[160px]",
309
+ frameStyle: s.height > 0 ? { height: s.height } : {},
310
+ margin: { ...defaultMargin, ...s.margin || {} }
311
+ };
312
+ };
313
+ function thinTicks(values, max) {
314
+ if (max <= 0 || values.length <= max) return void 0;
315
+ if (max === 1) return [values[values.length - 1]];
316
+ const picked = [];
317
+ for (let i = 0; i < max; i++) {
318
+ picked.push(values[Math.round(i * (values.length - 1) / (max - 1))]);
319
+ }
320
+ return [...new Set(picked)];
321
+ }
273
322
  var LEGEND_ANCHORS = ["right", "top-left", "top-right", "bottom-left", "bottom-right", "none"];
274
323
  var withStyleDefaults = (style) => ({
275
324
  ...DEFAULT_CHART_STYLE,
@@ -519,27 +568,37 @@ function makeAxis(style, axis, columnName, opts2 = {}) {
519
568
  out.tickRotation = rotate;
520
569
  out.format = (v) => formatVal(v, s, numeric);
521
570
  }
571
+ const maxTicks = isX ? s.maxXTicks : s.maxYTicks;
572
+ if (numeric && maxTicks > 0) out.tickValues = maxTicks;
522
573
  return out;
523
574
  }
524
- function BarView({ records, groupColumn, valueColumn, aggFn = "count", data: presetData, style }) {
575
+ function BarView({ records, groupColumn, valueColumn, aggFn = "count", data: presetData, layout = "vertical", style }) {
525
576
  const computed = useMemo(() => {
526
577
  if (presetData || !records) return [];
527
578
  const groups = groupBy(records, groupColumn);
528
579
  return Object.entries(groups).map(([key, recs]) => ({ group: key, value: aggregate(recs, valueColumn, aggFn) })).sort((a, b) => b.value - a.value).slice(0, 50);
529
580
  }, [records, groupColumn, valueColumn, aggFn, presetData]);
530
581
  const data = presetData || computed;
531
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
582
+ const s = withStyleDefaults(style);
583
+ const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 20, bottom: 60, left: 60 });
584
+ const horizontal = layout === "horizontal";
585
+ const plotted = horizontal ? [...data].reverse() : data;
586
+ const axisBottom = horizontal ? makeAxis(style, "x", valueColumn, { numeric: true }) : makeAxis(style, "x", groupColumn);
587
+ const axisLeft = horizontal ? makeAxis(style, "y", groupColumn) : makeAxis(style, "y", valueColumn, { numeric: true });
588
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
532
589
  ResponsiveBar,
533
590
  {
534
- data,
591
+ data: plotted,
535
592
  keys: ["value"],
536
593
  indexBy: "group",
537
- margin: { top: 20, right: 20, bottom: 60, left: 60 },
594
+ layout,
595
+ margin,
538
596
  padding: 0.3,
539
- colors: ["rgba(74, 222, 128, 0.8)"],
597
+ colors: [s.seriesColors[0] || "rgba(74, 222, 128, 0.8)"],
540
598
  borderColor: { from: "color", modifiers: [["darker", 1.6]] },
541
- axisBottom: makeAxis(style, "x", groupColumn),
542
- axisLeft: makeAxis(style, "y", valueColumn, { numeric: true }),
599
+ axisBottom,
600
+ axisLeft,
601
+ enableLabel: s.barLabels,
543
602
  labelSkipWidth: 12,
544
603
  labelSkipHeight: 12,
545
604
  labelTextColor: { from: "color", modifiers: [["darker", 3]] },
@@ -560,16 +619,19 @@ function PieView({ records, groupColumn, data: presetData, style }) {
560
619
  }, [records, groupColumn, presetData]);
561
620
  const data = presetData || computed;
562
621
  const legend = legendConfig(style);
563
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
622
+ const s = withStyleDefaults(style);
623
+ const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 120, bottom: 20, left: 20 });
624
+ const colorById = new Map(data.map((d, i) => [d.id, seriesColor(i, s)]));
625
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
564
626
  ResponsivePie,
565
627
  {
566
628
  data,
567
- margin: { top: 20, right: 120, bottom: 20, left: 20 },
629
+ margin,
568
630
  innerRadius: 0.4,
569
631
  padAngle: 1,
570
632
  cornerRadius: 3,
571
633
  activeOuterRadiusOffset: 8,
572
- colors: { scheme: "set2" },
634
+ colors: ((d) => colorById.get(d.id)),
573
635
  borderWidth: 1,
574
636
  borderColor: { from: "color", modifiers: [["darker", 0.2]] },
575
637
  arcLinkLabelsSkipAngle: 10,
@@ -582,7 +644,7 @@ function PieView({ records, groupColumn, data: presetData, style }) {
582
644
  }
583
645
  ) });
584
646
  }
585
- function LineView({ records, xColumn, yColumn, data: presetData, style }) {
647
+ function LineView({ records, xColumn, yColumn, data: presetData, dashedIds, style }) {
586
648
  const computed = useMemo(() => {
587
649
  if (presetData || !records) return [];
588
650
  const sorted = [...records].filter((r) => r[xColumn] != null && r[yColumn] != null).sort((a, b) => {
@@ -596,29 +658,69 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
596
658
  }];
597
659
  }, [records, xColumn, yColumn, presetData]);
598
660
  const data = presetData || computed;
599
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
661
+ const s = withStyleDefaults(style);
662
+ const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 20, bottom: 60, left: 60 });
663
+ const colorById = new Map(data.map((serie, i) => [
664
+ serie.id,
665
+ s.seriesColors.length || data.length > 1 ? seriesColor(i, s) : "rgba(96, 165, 250, 0.9)"
666
+ ]));
667
+ const longest = data.reduce((a, b) => b.data.length > a.data.length ? b : a, { id: "", data: [] });
668
+ const tickValues = thinTicks(longest.data.map((d) => d.x), s.maxXTicks);
669
+ const dashed = new Set(dashedIds || []);
670
+ const linesLayer = ({ series, lineGenerator }) => /* @__PURE__ */ jsx(Fragment, { children: series.map((serie) => /* @__PURE__ */ jsx(
671
+ "path",
672
+ {
673
+ d: lineGenerator(serie.data.map((d) => d.position)),
674
+ fill: "none",
675
+ stroke: serie.color,
676
+ strokeWidth: 2,
677
+ strokeLinecap: "round",
678
+ strokeDasharray: dashed.has(String(serie.id)) ? "1 5" : void 0
679
+ },
680
+ serie.id
681
+ )) });
682
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
600
683
  ResponsiveLine,
601
684
  {
602
685
  data,
603
- margin: { top: 20, right: 20, bottom: 60, left: 60 },
686
+ margin,
604
687
  xScale: { type: "point" },
605
688
  yScale: { type: "linear", min: "auto", max: "auto" },
606
689
  curve: "monotoneX",
607
- enableArea: true,
608
- areaOpacity: 0.15,
609
- colors: ["rgba(96, 165, 250, 0.9)"],
610
- pointSize: (data[0]?.data.length ?? 0) > 50 ? 0 : 6,
690
+ enableArea: s.areaOpacity > 0,
691
+ areaOpacity: s.areaOpacity,
692
+ colors: ((serie) => colorById.get(serie.id)),
693
+ pointSize: 0,
611
694
  pointColor: { theme: "background" },
612
695
  pointBorderWidth: 2,
613
696
  pointBorderColor: { from: "serieColor" },
614
697
  enableGridX: false,
615
- axisBottom: makeAxis(style, "x", xColumn),
698
+ axisBottom: { ...makeAxis(style, "x", xColumn), ...tickValues ? { tickValues } : {} },
616
699
  axisLeft: makeAxis(style, "y", yColumn, { numeric: true }),
617
700
  useMesh: true,
701
+ layers: ["grid", "markers", "axes", "areas", linesLayer, "crosshair", "slices", "mesh", "legends"],
618
702
  theme: buildNivoTheme(style)
619
703
  }
620
704
  ) });
621
705
  }
706
+ function SparklineView({ data, height = 56, color = "#3987e5" }) {
707
+ const gradientId = useId();
708
+ const width = 260;
709
+ const pts = data && data.length ? data : [0];
710
+ const max = Math.max(...pts, 1);
711
+ const dx = pts.length > 1 ? width / (pts.length - 1) : width;
712
+ const xy = (v, i) => [i * dx, height - v / max * (height - 4) - 2];
713
+ const line = pts.map((v, i) => `${i === 0 ? "M" : "L"} ${xy(v, i)[0].toFixed(1)} ${xy(v, i)[1].toFixed(1)}`).join(" ");
714
+ const area = `${line} L ${width} ${height} L 0 ${height} Z`;
715
+ return /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${width} ${height}`, height, className: "w-full", preserveAspectRatio: "none", children: [
716
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
717
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: "0.25" }),
718
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
719
+ ] }) }),
720
+ /* @__PURE__ */ jsx("path", { d: area, fill: `url(#${gradientId})` }),
721
+ /* @__PURE__ */ jsx("path", { d: line, fill: "none", stroke: color, strokeWidth: "2", vectorEffect: "non-scaling-stroke" })
722
+ ] });
723
+ }
622
724
  function ScatterView({ records, xColumn, yColumn, data: presetData, style }) {
623
725
  const computed = useMemo(() => {
624
726
  if (presetData || !records) return [];
@@ -626,14 +728,20 @@ function ScatterView({ records, xColumn, yColumn, data: presetData, style }) {
626
728
  return [{ id: `${xColumn} vs ${yColumn}`, data: points }];
627
729
  }, [records, xColumn, yColumn, presetData]);
628
730
  const data = presetData || computed;
629
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
731
+ const s = withStyleDefaults(style);
732
+ const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 20, bottom: 60, left: 60 });
733
+ const colorById = new Map(data.map((serie, i) => [
734
+ serie.id,
735
+ s.seriesColors.length || data.length > 1 ? seriesColor(i, s) : "rgba(167, 139, 250, 0.7)"
736
+ ]));
737
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
630
738
  ResponsiveScatterPlot,
631
739
  {
632
740
  data,
633
- margin: { top: 20, right: 20, bottom: 60, left: 60 },
741
+ margin,
634
742
  xScale: { type: "linear", min: "auto", max: "auto" },
635
743
  yScale: { type: "linear", min: "auto", max: "auto" },
636
- colors: ["rgba(167, 139, 250, 0.7)"],
744
+ colors: ((serie) => colorById.get(serie.serieId ?? serie.id ?? "")),
637
745
  nodeSize: 6,
638
746
  axisBottom: makeAxis(style, "x", xColumn, { numeric: true }),
639
747
  axisLeft: makeAxis(style, "y", yColumn, { numeric: true }),
@@ -729,8 +837,8 @@ function HeatmapView({
729
837
  if (!data.length || !data[0].data.length) {
730
838
  return /* @__PURE__ */ jsx("div", { className: "p-8 text-center text-midnight-text-muted", children: "Not enough distinct values for a heatmap" });
731
839
  }
732
- const margin = showTotals ? { top: 60, right: 70, bottom: 60, left: 100 } : { top: 60, right: 20, bottom: 20, left: 100 };
733
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
840
+ const { frameClass, frameStyle, margin } = chartSizing(style, showTotals ? { top: 60, right: 70, bottom: 60, left: 100 } : { top: 60, right: 20, bottom: 20, left: 100 });
841
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
734
842
  ResponsiveHeatMap,
735
843
  {
736
844
  data,
@@ -884,11 +992,12 @@ function HeatmapPlusView({
884
992
  }
885
993
  const { nivoData, t } = built;
886
994
  const tAt = (serieId, x) => t.get(cellKey(serieId, x)) ?? 0;
887
- return /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-[160px]", children: /* @__PURE__ */ jsx(
995
+ const { frameClass, frameStyle, margin } = chartSizing(style, { top: 60, right: 20, bottom: showMargins ? 60 : 20, left: 100 });
996
+ return /* @__PURE__ */ jsx("div", { className: frameClass, style: frameStyle, children: /* @__PURE__ */ jsx(
888
997
  ResponsiveHeatMap,
889
998
  {
890
999
  data: nivoData,
891
- margin: { top: 60, right: 20, bottom: showMargins ? 60 : 20, left: 100 },
1000
+ margin,
892
1001
  valueFormat: ((v) => fmtNum2(v)),
893
1002
  axisTop: { tickSize: 5, tickPadding: 5, tickRotation: s.xTickRotation, legend: s.showXLegend ? s.xAxisLabel || colColumn : "", legendPosition: s.xLegendPosition, legendOffset: -50 },
894
1003
  axisLeft: { tickSize: 5, tickPadding: 5, legend: s.showYLegend ? s.yAxisLabel || rowColumn : "", legendPosition: s.yLegendPosition, legendOffset: -80 },
@@ -2900,6 +3009,6 @@ function DataExplorer({
2900
3009
  ] });
2901
3010
  }
2902
3011
 
2903
- export { BarView, ChartBuilder, ChartStyleControls, DEFAULT_CHART_STYLE, DashboardProvider, DashboardRenderer, DataExplorer, HEAT_STATS, HeatmapPlusView, HeatmapView, InsightView, LEGEND_ANCHORS, LineView, MetricView, PanelChart, PieView, PivotView, ScatterView, SqlConsole, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, shapeChartData, useCapabilities, useDashboard, withStyleDefaults };
3012
+ export { BarView, ChartBuilder, ChartStyleControls, DEFAULT_CHART_STYLE, DEFAULT_SERIES_COLORS, DashboardProvider, DashboardRenderer, DataExplorer, HEAT_STATS, HeatmapPlusView, HeatmapView, InsightView, LEGEND_ANCHORS, LineView, MetricView, PanelChart, PieView, PivotView, SERIES_OVERFLOW_COLOR, ScatterView, SparklineView, SqlConsole, aggExpr, aggregate, axisLegend, buildChartSQL, buildNivoTheme, chartSizing, compileWhere, groupBy, heatColor, heatLabelColor, legendConfig, normalizeCells, qIdent, qLit, seriesColor, shapeChartData, thinTicks, useCapabilities, useDashboard, withStyleDefaults };
2904
3013
  //# sourceMappingURL=index.js.map
2905
3014
  //# sourceMappingURL=index.js.map