UNPKG

@fusedashlabs/ui9000-workspace

Version:

UI9000 workspace MCP. One tool, show_workspace, draws a chart from your table. Set TYPESAFE_API_KEY to let Jev choose the chart.

436 lines (435 loc) • 21.5 kB
/** * Visual families for the widgets charts. * * `show_workspace` asks Jev for a class, then a drawing inside that class. * A named chart in that class is drawn. A named chart in another class waits * for the user. When Jev does not answer, `decide()` still picks the chart. * Many widgets draw the same columns with a different mark. This file records * that: bar is the comparison main, and the same category + metric can also * be a lollipop, a line, or an area when the `when` holds. * * It does not add charts to the frozen 20-id engine catalog. */ export type ChartRole = { /** widgets component id (`metadata.json` `id`). */ id: string; /** FuseDash `chartType` keys this component already renders. */ chartTypeKeys: readonly string[]; /** What this drawing is for. */ role: string; /** Columns or payload this drawing needs. */ data: string; /** What the mark encodes. */ visual: string; }; export type ChartAlternative = { id: string; /** When this drawing is a faithful reading of the family's data. */ when: string; }; export type ChartFamily = { id: string; /** The question the family answers. */ question: string; /** Shared data shape. */ data: string; /** The chart the engine should select for this question. */ main: string; /** Other drawings of the same data. Closest substitutes first. */ alternatives: readonly ChartAlternative[]; }; export declare const CHART_ROLES: { readonly 'bar-chart': { readonly id: "bar-chart"; readonly chartTypeKeys: readonly ["barChart", "barGrouped", "barStacked", "cumulativeBar", "barHorizontal", "barHorizontalGrouped", "barHorizontalStacked"]; readonly role: "Compare discrete groups on one metric."; readonly data: "Category, one number, optional second category as a series."; readonly visual: "Bar length. Vertical or horizontal; plain, grouped, stacked, or with a cumulative line."; }; readonly lollipop: { readonly id: "lollipop"; readonly chartTypeKeys: readonly ["lollipopChart", "lollipopGroupedChart", "lollipopStackedChart"]; readonly role: "Same comparison as a bar, drawn as a stem and a dot."; readonly data: "Category, one number, optional series."; readonly visual: "Stem length plus a head. Vertical or horizontal; plain, grouped, or stacked."; }; readonly 'line-chart': { readonly id: "line-chart"; readonly chartTypeKeys: readonly ["lineChart", "lineGroupedChart"]; readonly role: "Show how a metric moves along an ordered axis."; readonly data: "Ordered x (time or sequence) and a number, optional series."; readonly visual: "Connected points. One line, or one line per series."; }; readonly 'area-chart': { readonly id: "area-chart"; readonly chartTypeKeys: readonly ["areaChart", "areaStackedChart"]; readonly role: "Same ordered series as a line, with the region under the line filled."; readonly data: "Ordered x and a number, optional series."; readonly visual: "Filled area. Grouped or stacked."; }; readonly 'area-grouped-bar-chart': { readonly id: "area-grouped-bar-chart"; readonly chartTypeKeys: readonly ["areaGroupedBarChart"]; readonly role: "Compare groups with bars and overlay an area or line on the same categories."; readonly data: "Category, a bar metric, and a second series for the overlay."; readonly visual: "Grouped bars plus an area or line. Vertical only."; }; readonly 'radial-bar-chart': { readonly id: "radial-bar-chart"; readonly chartTypeKeys: readonly ["radialBarChart"]; readonly role: "Compare a few categories by ring length instead of a bar."; readonly data: "Category and one number. Few categories."; readonly visual: "One ring per category over a 270° sweep."; }; readonly 'polar-area-chart': { readonly id: "polar-area-chart"; readonly chartTypeKeys: readonly ["polarAreaChart"]; readonly role: "Compare a few categories by wedge radius."; readonly data: "Category and one number, optional group."; readonly visual: "Coxcomb slices. Radius is the metric, not the share of a whole."; }; readonly 'pie-chart': { readonly id: "pie-chart"; readonly chartTypeKeys: readonly ["pieChart"]; readonly role: "Show each category as a share of a total."; readonly data: "Categories whose metric sums to a whole. Low cardinality."; readonly visual: "Full disc. Angle is the share."; }; readonly 'donut-chart': { readonly id: "donut-chart"; readonly chartTypeKeys: readonly ["donutChart"]; readonly role: "Same shares as a pie, with a hole in the middle."; readonly data: "Same as pie: categories that sum to a whole."; readonly visual: "Ring. Angle is the share."; }; readonly 'treemap-chart': { readonly id: "treemap-chart"; readonly chartTypeKeys: readonly ["treemapChart"]; readonly role: "Show magnitude, or a share of a total, as tile area. A second category nests tiles."; readonly data: "Category and a number. Optional subgroup for one card per group."; readonly visual: "Area-proportional tiles. Color follows magnitude."; }; readonly 'histogram-chart': { readonly id: "histogram-chart"; readonly chartTypeKeys: readonly ["histogramChart"]; readonly role: "Show the shape of one numeric variable."; readonly data: "Numeric samples, binned. Optional series stacks the bins."; readonly visual: "Adjacent bars along a linear x-axis."; }; readonly 'box-plot-chart': { readonly id: "box-plot-chart"; readonly chartTypeKeys: readonly ["boxplotChart"]; readonly role: "Summarize a numeric sample per category: median, quartiles, outliers."; readonly data: "Numeric samples, split by a category."; readonly visual: "Box, whiskers, and outlier points. Vertical or horizontal."; }; readonly 'violin-chart': { readonly id: "violin-chart"; readonly chartTypeKeys: readonly ["violinChart"]; readonly role: "Show the density of a numeric sample per category, with a box inside."; readonly data: "Numeric samples, split by a category."; readonly visual: "Kernel density plus a box overlay."; }; readonly 'scatter-plot-chart': { readonly id: "scatter-plot-chart"; readonly chartTypeKeys: readonly ["scatterplotChart", "qqPlot"]; readonly role: "Show the relationship between two numbers. Also a QQ plot of quantiles."; readonly data: "Numeric x, numeric y, optional group."; readonly visual: "One point per row. Color marks the group."; }; readonly 'bubble-chart': { readonly id: "bubble-chart"; readonly chartTypeKeys: readonly ["bubbleChart"]; readonly role: "Same two-number relationship as a scatter, with a third number as size."; readonly data: "Numeric x, numeric y, a size number, optional group."; readonly visual: "Point radius from the absolute size. Color marks the group."; }; readonly 'matrix-chart': { readonly id: "matrix-chart"; readonly chartTypeKeys: readonly ["matrixChart"]; readonly role: "Show the metric at each pair of categories."; readonly data: "Row category, column category, one number."; readonly visual: "Cell color on a sequential palette."; }; readonly 'punchcard-chart': { readonly id: "punchcard-chart"; readonly chartTypeKeys: readonly ["punchcardChart"]; readonly role: "Same two-category grid as a matrix, drawn as dots."; readonly data: "Row category, column category, one number."; readonly visual: "Dot size (and position) encodes the metric."; }; readonly 'radar-chart': { readonly id: "radar-chart"; readonly chartTypeKeys: readonly ["radarChart", "radarGroupedChart"]; readonly role: "Compare one or a few entities across several metrics on a shared scale."; readonly data: "Few entities, several numeric axes."; readonly visual: "Polygon on a polar grid. One shape, or one per series."; }; readonly 'parallel-coordinates-chart': { readonly id: "parallel-coordinates-chart"; readonly chartTypeKeys: readonly ["parallelCoordinatesChart"]; readonly role: "Compare many records across several numeric dimensions."; readonly data: "Many rows. Every numeric column is an axis."; readonly visual: "One polyline per record. Color follows the active axis."; }; readonly 'sankey-chart': { readonly id: "sankey-chart"; readonly chartTypeKeys: readonly ["sankeyChart"]; readonly role: "Show how much moves from a source category to a target category."; readonly data: "Source, target, and a value."; readonly visual: "Nodes and value-coloured ribbons."; }; readonly 'waterfall-chart': { readonly id: "waterfall-chart"; readonly chartTypeKeys: readonly ["waterfallChart"]; readonly role: "Show how signed steps add up to a total."; readonly data: "Ordered categories and a signed delta, or a running level."; readonly visual: "Floating bars. Vertical or horizontal."; }; readonly 'map-chart': { readonly id: "map-chart"; readonly chartTypeKeys: readonly ["mapChart", "UniversalMap"]; readonly role: "Place a metric on geography."; readonly data: "Region id or lat/lng, optional magnitude."; readonly visual: "Choropleth fill, bubbles, or spikes on a map."; }; readonly 'network-graph': { readonly id: "network-graph"; readonly chartTypeKeys: readonly ["networkGraphChart"]; readonly role: "Show what is connected to what."; readonly data: "Nodes and links."; readonly visual: "Force layout. Node size from a value, color from a category."; }; readonly 'kpi-widget': { readonly id: "kpi-widget"; readonly chartTypeKeys: readonly ["KPI", "KPIs"]; readonly role: "State a headline card: one number, its change, current versus previous, or the high and low of a category."; readonly data: "One metric. A change, a previous period, or a category for high and low, when that reading was asked."; readonly visual: "Cards, not a plot."; }; readonly 'status-gauge-widget': { readonly id: "status-gauge-widget"; readonly chartTypeKeys: readonly ["statusGaugeWidget"]; readonly role: "State one health score as a dial, plus the measures behind it."; readonly data: "A health or condition score that already exists, plus at least one other measure. Optional unit, status, min, and max."; readonly visual: "Semicircular health gauge and KPI cards with ticked range bars."; }; readonly 'step-line-chart': { readonly id: "step-line-chart"; readonly chartTypeKeys: readonly ["stepLineChart", "ksPlotChart", "rocCurveChart"]; readonly role: "Show a metric that holds until the next x. Also KS and ROC reference overlays."; readonly data: "Ordered x and a number, optional series. KS/ROC add a reference curve."; readonly visual: "Step line. `ksPlotChart` draws the ideal curve; `rocCurveChart` draws the diagonal."; }; readonly 'spark-line-chart': { readonly id: "spark-line-chart"; readonly chartTypeKeys: readonly ["sparkLineChart"]; readonly role: "Compact reading of a datetime series."; readonly data: "Datetime x and a number, optional series."; readonly visual: "Line with axes and a crosshair."; }; readonly 'spark-area-chart': { readonly id: "spark-area-chart"; readonly chartTypeKeys: readonly ["sparkAreaChart"]; readonly role: "Compact datetime series with the region under the line filled."; readonly data: "Datetime x and a number, optional series."; readonly visual: "Line filled to y = 0."; }; readonly 'scatter-sparkline-chart': { readonly id: "scatter-sparkline-chart"; readonly chartTypeKeys: readonly ["scatterSparklineChart"]; readonly role: "Datetime series as a line, with the underlying points still visible."; readonly data: "Datetime x, a number, and the raw points."; readonly visual: "Aggregated line with gradient fill plus jittered markers."; }; readonly 'partial-dependence-chart': { readonly id: "partial-dependence-chart"; readonly chartTypeKeys: readonly ["partialDependenceChart"]; readonly role: "Show how a model prediction moves as one feature changes."; readonly data: "Feature values, ICE curves, and their average."; readonly visual: "Faint ICE lines under a dashed average."; }; readonly 'bias-variance-tradeoff-chart': { readonly id: "bias-variance-tradeoff-chart"; readonly chartTypeKeys: readonly ["biasVarianceTradeoffChart"]; readonly role: "Show bias, variance, and total error against model complexity."; readonly data: "Complexity on x and the three error curves."; readonly visual: "Fixed diagnostic lines, not a general series."; }; readonly 'gini-impurity-entropy-chart': { readonly id: "gini-impurity-entropy-chart"; readonly chartTypeKeys: readonly ["giniImpurityEntropyChart"]; readonly role: "Show impurity of a binary split across the class probability."; readonly data: "Probability p, and the entropy / Gini / misclassification curves."; readonly visual: "Fixed diagnostic curves, optional split annotations."; }; }; export type ChartId = keyof typeof CHART_ROLES; export declare const CHART_FAMILIES: readonly [{ readonly id: "category-magnitude"; readonly question: "How do discrete groups compare on one metric?"; readonly data: "One category, one number, optional second category as a series."; readonly main: "bar-chart"; readonly alternatives: readonly [{ readonly id: "lollipop"; readonly when: "Same axes. Prefer it when a stem and a dot stay readable."; }, { readonly id: "line-chart"; readonly when: "The category has an order (time or sequence), so the slope means something."; }, { readonly id: "area-chart"; readonly when: "The category is ordered and the fill should show volume, not only the slope."; }, { readonly id: "area-grouped-bar-chart"; readonly when: "The same categories need bars and an area or line overlay together."; }, { readonly id: "radial-bar-chart"; readonly when: "Few categories, and ring length is the comparison."; }, { readonly id: "polar-area-chart"; readonly when: "Few categories, and wedge radius is the comparison. Not a share of a whole."; }]; }, { readonly id: "part-to-whole"; readonly question: "What share of a total does each category take?"; readonly data: "Categories whose metric sums to a whole. Low cardinality."; readonly main: "pie-chart"; readonly alternatives: readonly [{ readonly id: "donut-chart"; readonly when: "Same slices. The hole is only a drawing change."; }, { readonly id: "treemap-chart"; readonly when: "Area should carry the share, or a second category nests tiles inside each group."; }]; }, { readonly id: "ordered-series"; readonly question: "How does a metric move along an ordered axis?"; readonly data: "Ordered x (time or sequence) and a number, optional series."; readonly main: "line-chart"; readonly alternatives: readonly [{ readonly id: "area-chart"; readonly when: "Same line. The fill shows volume under it."; }, { readonly id: "step-line-chart"; readonly when: "The value holds until the next x, or the chart is a KS / ROC overlay."; }, { readonly id: "spark-line-chart"; readonly when: "The x is datetime and the reading should stay compact."; }, { readonly id: "spark-area-chart"; readonly when: "Compact datetime series with a fill to zero."; }, { readonly id: "scatter-sparkline-chart"; readonly when: "The datetime line should keep the raw points visible."; }, { readonly id: "bar-chart"; readonly when: "The ordered x is a short list of categories and the reading is a comparison, not a slope."; }]; }, { readonly id: "distribution"; readonly question: "What shape does a numeric variable take?"; readonly data: "Numeric samples. Optional category that splits the sample."; readonly main: "histogram-chart"; readonly alternatives: readonly [{ readonly id: "box-plot-chart"; readonly when: "The sample is split by category and the reading is quartiles and outliers."; }, { readonly id: "violin-chart"; readonly when: "The sample is split by category and the reading is the density, not only the bins."; }]; }, { readonly id: "two-measures"; readonly question: "How do two numeric measures relate?"; readonly data: "Numeric x, numeric y, optional group."; readonly main: "scatter-plot-chart"; readonly alternatives: readonly [{ readonly id: "bubble-chart"; readonly when: "A third number should set the point size."; }]; }, { readonly id: "two-way-magnitude"; readonly question: "What is the metric at each pair of categories?"; readonly data: "Row category, column category, one number."; readonly main: "matrix-chart"; readonly alternatives: readonly [{ readonly id: "punchcard-chart"; readonly when: "The same grid should be dots sized by the metric, not colored cells."; }]; }, { readonly id: "many-metrics"; readonly question: "How does an entity compare across several metrics?"; readonly data: "Several numeric measures. One profile, or many records."; readonly main: "radar-chart"; readonly alternatives: readonly [{ readonly id: "parallel-coordinates-chart"; readonly when: "There are many records, not one or a few profiles."; }]; }, { readonly id: "flow"; readonly question: "How much moves from a source category to a target category?"; readonly data: "Source, target, and a value."; readonly main: "sankey-chart"; readonly alternatives: readonly []; }, { readonly id: "contribution"; readonly question: "How do signed steps add up to a total?"; readonly data: "Ordered categories and a signed delta, or a running level."; readonly main: "waterfall-chart"; readonly alternatives: readonly []; }, { readonly id: "spatial"; readonly question: "Where is the metric?"; readonly data: "Region id or lat/lng, optional magnitude."; readonly main: "map-chart"; readonly alternatives: readonly []; }, { readonly id: "graph"; readonly question: "What is connected to what?"; readonly data: "Nodes and links."; readonly main: "network-graph"; readonly alternatives: readonly []; }, { readonly id: "headline"; readonly question: "What headline card fits: one number, its change, current versus previous, or the high and low category?"; readonly data: "One metric. Optional change, previous period, or a category that splits high and low."; readonly main: "kpi-widget"; readonly alternatives: readonly [{ readonly id: "status-gauge-widget"; readonly when: "At least two measures, and one of them is already a health or condition score. The dial is that score. Do not invent it."; }]; }, { readonly id: "model-dependence"; readonly question: "How does a model prediction move as one feature changes?"; readonly data: "Feature values and ICE curves."; readonly main: "partial-dependence-chart"; readonly alternatives: readonly []; }, { readonly id: "model-error"; readonly question: "How do bias and variance trade off against complexity?"; readonly data: "Complexity and the bias, variance, and total-error curves."; readonly main: "bias-variance-tradeoff-chart"; readonly alternatives: readonly []; }, { readonly id: "model-impurity"; readonly question: "How impure is a binary split across the class probability?"; readonly data: "Class probability and the impurity curves."; readonly main: "gini-impurity-entropy-chart"; readonly alternatives: readonly []; }]; export declare function chartRole(id: string): ChartRole | undefined; /** Words for a chart. The component id stays on the spec. */ export declare function chartName(id: string): string; /** Name plus what the drawing shows, so a reply never says `bar-chart`. */ export declare function chartLabel(id: string): string; /** Families where this chart is the main drawing or an alternative. */ export declare function familiesForChart(id: string): ChartFamily[]; export type ChartDrawings = { family: ChartFamily; main: ChartRole; alternatives: ChartRole[]; }; /** * The main chart and the other drawings of the same data. * Looks up the family whose `main` is this id. */ export declare function drawingsFor(mainId: string): ChartDrawings | undefined;