@tuicomponents/chart 0.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chart.ts","../src/schema.ts","../src/layout/bar.ts","../src/core/scaling.ts","../src/core/chars.ts","../src/layout/stacked-bar.ts","../src/layout/line.ts","../src/layout/area.ts","../src/layout/scatter.ts","../src/layout/pie.ts","../src/layout/heatmap.ts","../src/renderers/ansi.ts","../src/core/legend.ts","../src/core/axis-renderer.ts","../src/renderers/markdown.ts","../src/core/axis.ts","../src/core/grid.ts"],"sourcesContent":["/**\n * Main Chart component.\n */\n\nimport {\n BaseTuiComponent,\n type ComponentMetadata,\n type RenderContext,\n type RenderResult,\n measureLines,\n registry,\n} from \"@tuicomponents/core\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { chartInputSchema } from \"./schema.js\";\nimport type { ChartInput } from \"./types.js\";\nimport { computeBarLayout } from \"./layout/bar.js\";\nimport { computeStackedBarLayout } from \"./layout/stacked-bar.js\";\nimport { computeLineLayout } from \"./layout/line.js\";\nimport { computeAreaLayout } from \"./layout/area.js\";\nimport { computeScatterLayout } from \"./layout/scatter.js\";\nimport { computePieLayout } from \"./layout/pie.js\";\nimport { computeHeatmapLayout } from \"./layout/heatmap.js\";\nimport {\n renderBarChartAnsi,\n renderVerticalBarChartAnsi,\n renderStackedBarChartAnsi,\n renderLineChartAnsi,\n renderAreaChartAnsi,\n renderScatterChartAnsi,\n renderPieChartAnsi,\n renderHeatmapAnsi,\n} from \"./renderers/ansi.js\";\nimport {\n renderBarChartMarkdown,\n renderVerticalBarChartMarkdown,\n renderStackedBarChartMarkdown,\n renderLineChartMarkdown,\n renderAreaChartMarkdown,\n renderScatterChartMarkdown,\n renderPieChartMarkdown,\n renderHeatmapMarkdown,\n} from \"./renderers/markdown.js\";\n\n/**\n * Chart component for rendering various chart types.\n */\nclass ChartComponent extends BaseTuiComponent<\n ChartInput,\n typeof chartInputSchema\n> {\n readonly metadata: ComponentMetadata<ChartInput> = {\n name: \"chart\",\n description:\n \"Renders various chart types including bar, line, and area charts\",\n version: \"0.1.0\",\n supportedModes: [\"ansi\", \"markdown\"],\n examples: [\n {\n name: \"horizontal-bar\",\n description: \"Simple horizontal bar chart\",\n input: {\n type: \"bar\",\n series: [\n {\n name: \"Sales\",\n data: [\n { x: \"Q1\", y: 120 },\n { x: \"Q2\", y: 150 },\n { x: \"Q3\", y: 180 },\n { x: \"Q4\", y: 200 },\n ],\n },\n ],\n showValues: true,\n },\n },\n {\n name: \"vertical-bar\",\n description: \"Vertical bar chart (column chart)\",\n input: {\n type: \"bar-vertical\",\n series: [\n {\n name: \"Revenue\",\n data: [\n { x: \"Jan\", y: 65 },\n { x: \"Feb\", y: 80 },\n { x: \"Mar\", y: 95 },\n { x: \"Apr\", y: 70 },\n ],\n },\n ],\n height: 8,\n width: 30,\n },\n },\n {\n name: \"stacked-bar\",\n description: \"Stacked horizontal bar chart\",\n input: {\n type: \"bar-stacked\",\n series: [\n {\n name: \"Product A\",\n data: [\n { x: \"Q1\", y: 50 },\n { x: \"Q2\", y: 60 },\n { x: \"Q3\", y: 70 },\n ],\n },\n {\n name: \"Product B\",\n data: [\n { x: \"Q1\", y: 30 },\n { x: \"Q2\", y: 40 },\n { x: \"Q3\", y: 35 },\n ],\n },\n ],\n width: 40,\n },\n },\n {\n name: \"stacked-vertical\",\n description: \"Stacked vertical bar chart\",\n input: {\n type: \"bar-stacked-vertical\",\n series: [\n {\n name: \"Revenue\",\n data: [\n { x: \"Q1\", y: 100 },\n { x: \"Q2\", y: 120 },\n { x: \"Q3\", y: 90 },\n { x: \"Q4\", y: 150 },\n ],\n },\n {\n name: \"Costs\",\n data: [\n { x: \"Q1\", y: 60 },\n { x: \"Q2\", y: 70 },\n { x: \"Q3\", y: 55 },\n { x: \"Q4\", y: 80 },\n ],\n },\n {\n name: \"Profit\",\n data: [\n { x: \"Q1\", y: 40 },\n { x: \"Q2\", y: 50 },\n { x: \"Q3\", y: 35 },\n { x: \"Q4\", y: 70 },\n ],\n },\n ],\n height: 10,\n width: 35,\n },\n },\n {\n name: \"line\",\n description: \"Line chart with height blocks\",\n input: {\n type: \"line\",\n series: [\n {\n name: \"Temperature\",\n data: [\n { x: \"J\", y: 30 },\n { x: \"F\", y: 35 },\n { x: \"M\", y: 50 },\n { x: \"A\", y: 65 },\n { x: \"M\", y: 75 },\n { x: \"J\", y: 85 },\n { x: \"J\", y: 90 },\n { x: \"A\", y: 88 },\n { x: \"S\", y: 78 },\n { x: \"O\", y: 62 },\n { x: \"N\", y: 45 },\n { x: \"D\", y: 32 },\n ],\n },\n ],\n height: 8,\n width: 20,\n },\n },\n {\n name: \"multi-line\",\n description: \"Multiple series line chart\",\n input: {\n type: \"line\",\n series: [\n {\n name: \"2023\",\n data: [\n { x: \"Q1\", y: 100 },\n { x: \"Q2\", y: 120 },\n { x: \"Q3\", y: 110 },\n { x: \"Q4\", y: 140 },\n ],\n },\n {\n name: \"2024\",\n data: [\n { x: \"Q1\", y: 130 },\n { x: \"Q2\", y: 145 },\n { x: \"Q3\", y: 135 },\n { x: \"Q4\", y: 160 },\n ],\n },\n ],\n height: 6,\n width: 20,\n },\n },\n {\n name: \"area\",\n description: \"Area chart\",\n input: {\n type: \"area\",\n series: [\n {\n name: \"Users\",\n data: [\n { x: \"W1\", y: 100 },\n { x: \"W2\", y: 150 },\n { x: \"W3\", y: 180 },\n { x: \"W4\", y: 160 },\n { x: \"W5\", y: 200 },\n ],\n },\n ],\n height: 6,\n width: 15,\n },\n },\n {\n name: \"stacked-area\",\n description: \"Stacked area chart\",\n input: {\n type: \"area-stacked\",\n series: [\n {\n name: \"Mobile\",\n data: [\n { x: \"J\", y: 50 },\n { x: \"F\", y: 60 },\n { x: \"M\", y: 70 },\n { x: \"A\", y: 65 },\n ],\n },\n {\n name: \"Desktop\",\n data: [\n { x: \"J\", y: 100 },\n { x: \"F\", y: 90 },\n { x: \"M\", y: 85 },\n { x: \"A\", y: 95 },\n ],\n },\n ],\n height: 8,\n width: 15,\n },\n },\n {\n name: \"scatter\",\n description: \"Scatter plot with numeric axes\",\n input: {\n type: \"scatter\",\n series: [\n {\n name: \"Data\",\n data: [\n { x: 10, y: 20 },\n { x: 30, y: 50 },\n { x: 50, y: 30 },\n { x: 70, y: 80 },\n { x: 90, y: 60 },\n ],\n },\n ],\n height: 8,\n width: 30,\n },\n },\n {\n name: \"pie\",\n description: \"Pie chart with percentage breakdown\",\n input: {\n type: \"pie\",\n series: [\n {\n name: \"Revenue\",\n data: [\n { label: \"Sales\", x: \"Sales\", y: 45 },\n { label: \"Support\", x: \"Support\", y: 30 },\n { label: \"Other\", x: \"Other\", y: 25 },\n ],\n },\n ],\n height: 10,\n width: 30,\n },\n },\n {\n name: \"donut\",\n description: \"Donut chart with center label\",\n input: {\n type: \"donut\",\n series: [\n {\n name: \"Market Share\",\n data: [\n { label: \"Chrome\", x: \"Chrome\", y: 65 },\n { label: \"Firefox\", x: \"Firefox\", y: 20 },\n { label: \"Safari\", x: \"Safari\", y: 15 },\n ],\n },\n ],\n height: 10,\n width: 30,\n centerLabel: \"100%\",\n innerRadius: 0.5,\n },\n },\n {\n name: \"heatmap\",\n description: \"Heatmap showing intensity values\",\n input: {\n type: \"heatmap\",\n series: [\n {\n name: \"Activity\",\n data: [\n { x: \"Mon\", y: 10, label: \"9am\" },\n { x: \"Tue\", y: 50, label: \"9am\" },\n { x: \"Wed\", y: 80, label: \"9am\" },\n { x: \"Mon\", y: 30, label: \"10am\" },\n { x: \"Tue\", y: 70, label: \"10am\" },\n { x: \"Wed\", y: 90, label: \"10am\" },\n ],\n },\n ],\n height: 6,\n width: 25,\n heatmapStyle: \"blocks\",\n },\n },\n ],\n };\n\n readonly schema = chartInputSchema;\n\n override getJsonSchema(): object {\n return zodToJsonSchema(this.schema, {\n name: this.metadata.name,\n $refStrategy: \"none\",\n });\n }\n\n render(input: ChartInput, context: RenderContext): RenderResult {\n const parsed = this.schema.parse(input);\n\n if (\n parsed.series.length === 0 ||\n parsed.series.every((s) => s.data.length === 0)\n ) {\n return { output: \"\", actualWidth: 0, lineCount: 0 };\n }\n\n let output: string;\n\n switch (parsed.type) {\n case \"bar\": {\n const layout = computeBarLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderBarChartMarkdown(layout, { input: parsed })\n : renderBarChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"bar-vertical\": {\n const layout = computeBarLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderVerticalBarChartMarkdown(layout, { input: parsed })\n : renderVerticalBarChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"bar-stacked\":\n case \"bar-stacked-vertical\": {\n const layout = computeStackedBarLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderStackedBarChartMarkdown(layout, { input: parsed })\n : renderStackedBarChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"line\": {\n const layout = computeLineLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderLineChartMarkdown(layout, { input: parsed })\n : renderLineChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"area\":\n case \"area-stacked\": {\n const layout = computeAreaLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderAreaChartMarkdown(layout, { input: parsed })\n : renderAreaChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"scatter\": {\n const layout = computeScatterLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderScatterChartMarkdown(layout, { input: parsed })\n : renderScatterChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"pie\":\n case \"donut\": {\n const layout = computePieLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderPieChartMarkdown(layout, { input: parsed })\n : renderPieChartAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n case \"heatmap\": {\n const layout = computeHeatmapLayout(parsed);\n output =\n context.renderMode === \"markdown\"\n ? renderHeatmapMarkdown(layout, { input: parsed })\n : renderHeatmapAnsi(layout, {\n theme: context.theme,\n input: parsed,\n });\n break;\n }\n\n default: {\n // Exhaustiveness check - TypeScript will error if a case is missing\n const _exhaustiveCheck: never = parsed.type;\n throw new Error(`Unknown chart type: ${String(_exhaustiveCheck)}`);\n }\n }\n\n // Add title if present\n if (parsed.title) {\n const titleLine = context.theme\n ? context.theme.semantic.header(parsed.title)\n : parsed.title;\n output = titleLine + \"\\n\" + output;\n }\n\n const measured = measureLines(output);\n\n return {\n output,\n actualWidth: measured.maxWidth,\n lineCount: measured.lineCount,\n };\n }\n}\n\n/**\n * Factory function to create a chart component.\n */\nexport function createChart(): ChartComponent {\n return new ChartComponent();\n}\n\n// Register with global registry\nregistry.register(createChart);\n\nexport { ChartComponent };\n","/**\n * Zod schemas for chart input validation.\n */\n\nimport { z } from \"zod\";\n\n/**\n * Chart type variants.\n */\nexport const chartTypeSchema = z.enum([\n \"bar\", // Horizontal bars\n \"bar-vertical\", // Vertical bars (column chart)\n \"bar-stacked\", // Stacked horizontal bars\n \"bar-stacked-vertical\", // Stacked vertical bars\n \"line\", // Line chart (height blocks)\n \"area\", // Filled area\n \"area-stacked\", // Stacked area\n \"scatter\", // 2D scatter plot with X/Y axes\n \"pie\", // Pie chart (circular)\n \"donut\", // Donut chart (pie with inner radius)\n \"heatmap\", // 2D grid with intensity shading\n]);\n\n/**\n * Style options for bar fill.\n */\nexport const barStyleSchema = z.enum([\n \"block\", // ████████\n \"shaded\", // ▓▓▓▓▓▓▓▓\n \"light\", // ░░░░░░░░\n \"hash\", // ########\n \"equals\", // ========\n \"arrow\", // >>>>>>>>\n]);\n\n/**\n * Style options for line rendering.\n */\nexport const lineStyleSchema = z.enum([\n \"blocks\", // Height blocks: ▁▂▃▄▅▆▇█ (default)\n \"braille\", // Braille dots (high resolution)\n \"dots\", // Point markers: · • ●\n]);\n\n/**\n * Style options for scatter plot rendering.\n */\nexport const scatterStyleSchema = z.enum([\n \"dots\", // Simple character dots (●, ■, ▲)\n \"braille\", // High-resolution braille positioning\n]);\n\n/**\n * Marker shapes for scatter plot series distinction.\n */\nexport const scatterMarkerSchema = z.enum([\n \"circle\", // ●\n \"square\", // ■\n \"triangle\", // ▲\n \"diamond\", // ◆\n \"plus\", // +\n]);\n\n/**\n * Style options for heatmap rendering.\n */\nexport const heatmapStyleSchema = z.enum([\n \"blocks\", // ░▒▓█ (4 intensity levels)\n \"ascii\", // . : * # (4 levels, markdown-friendly)\n \"numeric\", // Show actual values in cells\n]);\n\n/**\n * Value format options.\n */\nexport const valueFormatSchema = z.enum([\n \"number\", // Regular number\n \"percent\", // Percentage\n \"compact\", // K/M/B suffixes\n \"currency\", // Dollar prefix\n]);\n\n/**\n * Legend position options.\n */\nexport const legendPositionSchema = z.enum([\n \"none\", // No legend\n \"top\", // Above chart\n \"bottom\", // Below chart\n \"right\", // To the right\n \"inline\", // Inline with data\n]);\n\n/**\n * A single data point in a chart.\n */\nexport const dataPointSchema = z.object({\n /**\n * Category or x-value.\n * Can be a string (categorical) or number (continuous).\n */\n x: z.union([z.string(), z.number()]),\n\n /**\n * Numeric y-value.\n */\n y: z.number(),\n\n /**\n * Optional custom label for this data point.\n */\n label: z.string().optional(),\n});\n\n/**\n * A series of data points.\n */\nexport const dataSeriesSchema = z.object({\n /**\n * Series name (used in legend).\n */\n name: z.string(),\n\n /**\n * Data points in this series.\n */\n data: z.array(dataPointSchema),\n\n /**\n * Optional style for this series.\n */\n style: barStyleSchema.optional(),\n});\n\n/**\n * Axis configuration.\n */\nexport const axisConfigSchema = z.object({\n /**\n * Axis title/label.\n */\n label: z.string().optional(),\n\n /**\n * Explicit minimum value (auto-computed if not set).\n */\n min: z.number().optional(),\n\n /**\n * Explicit maximum value (auto-computed if not set).\n */\n max: z.number().optional(),\n\n /**\n * Number of tick marks.\n * @default 5\n */\n tickCount: z.number().int().positive().default(5),\n\n /**\n * Whether to show tick marks.\n * @default true\n */\n showTicks: z.boolean().default(true),\n\n /**\n * Value format for tick labels.\n * @default \"number\"\n */\n format: valueFormatSchema.default(\"number\"),\n\n /**\n * Number of decimal places.\n */\n decimals: z.number().int().nonnegative().optional(),\n});\n\n/**\n * Legend configuration.\n */\nexport const legendConfigSchema = z.object({\n /**\n * Legend position.\n * @default \"bottom\"\n */\n position: legendPositionSchema.default(\"bottom\"),\n\n /**\n * Whether to use boxed style.\n * @default false\n */\n boxed: z.boolean().default(false),\n});\n\n/**\n * Grid configuration.\n */\nexport const gridConfigSchema = z.object({\n /**\n * Show horizontal grid lines.\n * @default false\n */\n horizontal: z.boolean().default(false),\n\n /**\n * Show vertical grid lines.\n * @default false\n */\n vertical: z.boolean().default(false),\n\n /**\n * Grid character.\n * @default \"·\"\n */\n char: z.string().default(\"·\"),\n});\n\n/**\n * Main chart input schema.\n */\nexport const chartInputSchema = z.object({\n /**\n * Chart type.\n */\n type: chartTypeSchema,\n\n /**\n * Data series to display.\n */\n series: z.array(dataSeriesSchema).min(1),\n\n /**\n * Chart title.\n */\n title: z.string().optional(),\n\n /**\n * X-axis configuration.\n */\n xAxis: axisConfigSchema.optional(),\n\n /**\n * Y-axis configuration.\n */\n yAxis: axisConfigSchema.optional(),\n\n /**\n * Legend configuration.\n */\n legend: legendConfigSchema.optional(),\n\n /**\n * Grid configuration.\n */\n grid: gridConfigSchema.optional(),\n\n /**\n * Chart width in characters.\n * @default 40\n */\n width: z.number().int().positive().default(40),\n\n /**\n * Chart height in lines.\n * @default 10\n */\n height: z.number().int().positive().default(10),\n\n /**\n * Show values on data points.\n * @default false\n */\n showValues: z.boolean().default(false),\n\n /**\n * Show axes.\n * @default true\n */\n showAxes: z.boolean().default(true),\n\n /**\n * Line/area rendering style.\n * @default \"blocks\"\n */\n lineStyle: lineStyleSchema.default(\"blocks\"),\n\n /**\n * Default bar style for series without explicit style.\n * @default \"block\"\n */\n barStyle: barStyleSchema.default(\"block\"),\n\n /**\n * Scatter plot rendering style.\n * @default \"dots\"\n */\n scatterStyle: scatterStyleSchema.default(\"dots\"),\n\n /**\n * Heatmap rendering style.\n * @default \"blocks\"\n */\n heatmapStyle: heatmapStyleSchema.default(\"blocks\"),\n\n /**\n * Center label for donut charts.\n * Displayed in the center of the donut.\n */\n centerLabel: z.string().optional(),\n\n /**\n * Inner radius ratio for donut charts (0-0.9).\n * 0 = pie chart, 0.5 = typical donut.\n * @default 0.5\n */\n innerRadius: z.number().min(0).max(0.9).default(0.5),\n});\n\n// Export inferred types are in types.ts\n","/**\n * Layout computation for horizontal and vertical bar charts.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n scaleValue,\n} from \"../core/scaling.js\";\nimport { getBarChar, SERIES_STYLES } from \"../core/chars.js\";\nimport type { ChartInputWithDefaults, BarLayout } from \"../types.js\";\nimport type { AxisLayout } from \"../core/axis.js\";\n\n/**\n * Computed layout for a bar chart.\n */\nexport interface BarChartLayout {\n /** Chart type */\n type: \"bar\" | \"bar-vertical\";\n /** Individual bar layouts */\n bars: BarLayout[];\n /** Categories (x-axis labels) */\n categories: string[];\n /** Maximum label width */\n maxLabelWidth: number;\n /** Maximum value width */\n maxValueWidth: number;\n /** Bar area width (for horizontal) or height (for vertical) */\n barAreaSize: number;\n /** Y-axis scale info */\n yScale: ReturnType<typeof computeNiceTicks>;\n /** Y-axis layout */\n yAxis?: AxisLayout;\n /** Whether to show values */\n showValues: boolean;\n /** Chart dimensions */\n width: number;\n height: number;\n}\n\n/**\n * Compute layout for a horizontal or vertical bar chart.\n *\n * @param input - Chart input with defaults\n * @returns Computed bar chart layout\n */\nexport function computeBarLayout(\n input: ChartInputWithDefaults\n): BarChartLayout {\n const isVertical = input.type === \"bar-vertical\";\n const series = input.series;\n\n // Extract all data points and categories\n const allValues: number[] = [];\n const categorySet = new Set<string>();\n\n for (const s of series) {\n for (const point of s.data) {\n allValues.push(point.y);\n categorySet.add(String(point.x));\n }\n }\n\n const categories = Array.from(categorySet);\n\n // Compute Y-scale from data\n const dataMin = Math.min(0, ...allValues);\n const dataMax = Math.max(...allValues);\n const yScale = computeNiceTicks({\n dataMin,\n dataMax,\n tickCount: input.yAxis?.tickCount ?? 5,\n includeZero: true,\n forceMin: input.yAxis?.min,\n forceMax: input.yAxis?.max,\n });\n\n // Calculate label widths\n let maxLabelWidth = 0;\n for (const category of categories) {\n const width = getStringWidth(category);\n if (width > maxLabelWidth) {\n maxLabelWidth = width;\n }\n }\n\n // Determine bar area size\n const barAreaSize = isVertical\n ? input.height - 2 // Reserve for x-axis\n : input.width - maxLabelWidth - 3; // Reserve for labels and spacing\n\n // Compute individual bar layouts\n const bars: BarLayout[] = [];\n const formattedValues: string[] = [];\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n const styleIndex = seriesIndex % SERIES_STYLES.length;\n const styleInfo = SERIES_STYLES[styleIndex];\n if (!styleInfo) continue;\n const barChar = s.style ? getBarChar(s.style) : styleInfo.char;\n const useBackticks = s.style ? false : styleInfo.useBackticks;\n\n for (let pointIndex = 0; pointIndex < s.data.length; pointIndex++) {\n const point = s.data[pointIndex];\n if (!point) continue;\n const value = point.y;\n const label = point.label ?? String(point.x);\n\n // Scale value to bar length\n const normalizedValue = scaleValue(\n value,\n yScale.min,\n yScale.max,\n barAreaSize\n );\n const length = Math.max(0, Math.round(normalizedValue));\n\n // Format value\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n const formattedValue = formatTickValue(value, format, decimals);\n formattedValues.push(formattedValue);\n\n // Calculate percentage\n const percentage =\n yScale.max !== yScale.min\n ? ((value - yScale.min) / (yScale.max - yScale.min)) * 100\n : 0;\n\n bars.push({\n seriesIndex,\n pointIndex,\n label,\n value,\n length,\n formattedValue,\n barChar,\n useBackticks,\n percentage,\n });\n }\n }\n\n // Calculate max value width\n let maxValueWidth = 0;\n for (const formatted of formattedValues) {\n const width = getStringWidth(formatted);\n if (width > maxValueWidth) {\n maxValueWidth = width;\n }\n }\n\n return {\n type: isVertical ? \"bar-vertical\" : \"bar\",\n bars,\n categories,\n maxLabelWidth,\n maxValueWidth,\n barAreaSize,\n yScale,\n showValues: input.showValues,\n width: input.width,\n height: input.height,\n };\n}\n\n/**\n * Group bars by category for multi-series charts.\n *\n * @param layout - Bar chart layout\n * @returns Map of category to bars\n */\nexport function groupBarsByCategory(\n layout: BarChartLayout\n): Map<string, BarLayout[]> {\n const groups = new Map<string, BarLayout[]>();\n\n for (const bar of layout.bars) {\n const existing = groups.get(bar.label);\n if (existing) {\n existing.push(bar);\n } else {\n groups.set(bar.label, [bar]);\n }\n }\n\n return groups;\n}\n","/**\n * Auto-scaling and nice number algorithms for axis ticks.\n *\n * Implements the standard D3.js-style nice interval algorithm\n * for producing human-readable axis tick values.\n */\n\n/**\n * Standard nice intervals for axis ticks.\n * These produce round, readable numbers.\n */\nconst NICE_INTERVALS = [1, 2, 2.5, 5, 10] as const;\n\n/**\n * Configuration for nice number computation.\n */\nexport interface NiceTicksOptions {\n /** Minimum data value */\n dataMin: number;\n /** Maximum data value */\n dataMax: number;\n /** Desired number of ticks (default: 5) */\n tickCount?: number | undefined;\n /** Whether to include zero if data is all positive (default: true) */\n includeZero?: boolean | undefined;\n /** Explicit minimum (overrides computed) */\n forceMin?: number | undefined;\n /** Explicit maximum (overrides computed) */\n forceMax?: number | undefined;\n}\n\n/**\n * Result from nice tick computation.\n */\nexport interface NiceTicksResult {\n /** Computed nice minimum */\n min: number;\n /** Computed nice maximum */\n max: number;\n /** Tick step size */\n step: number;\n /** Array of tick values */\n ticks: number[];\n}\n\n/**\n * Find the nearest nice interval for a raw step value.\n *\n * @param rawStep - Raw step value\n * @returns Nice step value\n */\nfunction findNiceStep(rawStep: number): number {\n if (rawStep === 0) return 1;\n\n const magnitude = Math.pow(10, Math.floor(Math.log10(Math.abs(rawStep))));\n const normalized = rawStep / magnitude;\n\n // Find nearest nice interval\n for (const interval of NICE_INTERVALS) {\n if (interval >= normalized) {\n return interval * magnitude;\n }\n }\n\n // Fallback to 10 * magnitude\n return 10 * magnitude;\n}\n\n/**\n * Round a number down to the nearest multiple of step.\n */\nfunction floorToStep(value: number, step: number): number {\n return Math.floor(value / step) * step;\n}\n\n/**\n * Round a number up to the nearest multiple of step.\n */\nfunction ceilToStep(value: number, step: number): number {\n return Math.ceil(value / step) * step;\n}\n\n/**\n * Compute nice axis ticks for a data range.\n *\n * This implements the standard algorithm for producing readable tick values:\n * 1. Compute raw step from range and desired tick count\n * 2. Round step to a nice interval (1, 2, 2.5, 5, 10 × 10^n)\n * 3. Round min/max to nice boundaries\n * 4. Generate evenly spaced tick values\n *\n * @param options - Configuration options\n * @returns Computed ticks with nice min/max/step\n *\n * @example\n * ```ts\n * computeNiceTicks({ dataMin: 3, dataMax: 97 })\n * // Returns { min: 0, max: 100, step: 20, ticks: [0, 20, 40, 60, 80, 100] }\n *\n * computeNiceTicks({ dataMin: 0.003, dataMax: 0.097, tickCount: 4 })\n * // Returns { min: 0, max: 0.1, step: 0.025, ticks: [0, 0.025, 0.05, 0.075, 0.1] }\n * ```\n */\nexport function computeNiceTicks(options: NiceTicksOptions): NiceTicksResult {\n const {\n dataMin,\n dataMax,\n tickCount = 5,\n includeZero = true,\n forceMin,\n forceMax,\n } = options;\n\n // Handle edge cases - only use auto-range for single value if no forced values\n if (dataMin === dataMax && forceMin === undefined && forceMax === undefined) {\n // Single value - create a range around it\n const center = dataMin;\n const half = center === 0 ? 5 : Math.abs(center) * 0.5;\n const ticks = [center - half, center, center + half];\n return {\n min: ticks[0] ?? center - half,\n max: ticks[2] ?? center + half,\n step: half,\n ticks,\n };\n }\n\n // Adjust range to include zero if requested\n let effectiveMin = dataMin;\n let effectiveMax = dataMax;\n\n if (includeZero) {\n if (effectiveMin > 0) effectiveMin = 0;\n if (effectiveMax < 0) effectiveMax = 0;\n }\n\n // Apply force overrides\n if (forceMin !== undefined) effectiveMin = forceMin;\n if (forceMax !== undefined) effectiveMax = forceMax;\n\n // Compute nice step\n const range = effectiveMax - effectiveMin;\n const rawStep = range / Math.max(1, tickCount - 1);\n const niceStep = findNiceStep(rawStep);\n\n // Round boundaries to nice values\n let niceMin = forceMin ?? floorToStep(effectiveMin, niceStep);\n let niceMax = forceMax ?? ceilToStep(effectiveMax, niceStep);\n\n // Ensure min/max actually encompass the data\n if (niceMin > dataMin) niceMin -= niceStep;\n if (niceMax < dataMax) niceMax += niceStep;\n\n // Generate tick values\n const ticks: number[] = [];\n // Use a small epsilon to handle floating point errors\n const epsilon = niceStep * 1e-10;\n\n for (let value = niceMin; value <= niceMax + epsilon; value += niceStep) {\n // Round to avoid floating point artifacts\n const roundedValue = Math.round(value * 1e12) / 1e12;\n ticks.push(roundedValue);\n }\n\n return {\n min: niceMin,\n max: niceMax,\n step: niceStep,\n ticks,\n };\n}\n\n/**\n * Format a tick value for display.\n *\n * @param value - Numeric value\n * @param format - Format type\n * @param decimals - Number of decimal places\n * @returns Formatted string\n */\nexport function formatTickValue(\n value: number,\n format: \"number\" | \"percent\" | \"compact\" | \"currency\" = \"number\",\n decimals?: number\n): string {\n switch (format) {\n case \"percent\":\n return `${(value * 100).toFixed(decimals ?? 0)}%`;\n\n case \"compact\": {\n const abs = Math.abs(value);\n if (abs >= 1_000_000_000) {\n return `${(value / 1_000_000_000).toFixed(decimals ?? 1)}B`;\n }\n if (abs >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(decimals ?? 1)}M`;\n }\n if (abs >= 1_000) {\n return `${(value / 1_000).toFixed(decimals ?? 1)}K`;\n }\n return value.toFixed(decimals ?? 0);\n }\n\n case \"currency\":\n return `$${value.toLocaleString(\"en-US\", {\n minimumFractionDigits: decimals ?? 0,\n maximumFractionDigits: decimals ?? 0,\n })}`;\n\n case \"number\":\n default:\n if (decimals !== undefined) {\n return value.toFixed(decimals);\n }\n // Auto-detect appropriate precision\n if (Number.isInteger(value)) {\n return value.toLocaleString(\"en-US\");\n }\n return value.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n });\n }\n}\n\n/**\n * Compute the scale factor to map a value to a pixel position.\n *\n * @param value - Data value\n * @param min - Scale minimum\n * @param max - Scale maximum\n * @param size - Available size (pixels/characters)\n * @returns Position in range [0, size]\n */\nexport function scaleValue(\n value: number,\n min: number,\n max: number,\n size: number\n): number {\n if (max === min) return size / 2;\n return ((value - min) / (max - min)) * size;\n}\n\n/**\n * Inverse of scaleValue - map a position back to data value.\n *\n * @param position - Position in range [0, size]\n * @param min - Scale minimum\n * @param max - Scale maximum\n * @param size - Available size (pixels/characters)\n * @returns Data value\n */\nexport function unscaleValue(\n position: number,\n min: number,\n max: number,\n size: number\n): number {\n if (size === 0) return min;\n return min + (position / size) * (max - min);\n}\n","/**\n * Box-drawing and block characters for chart rendering.\n */\n\n/**\n * Axis line characters using Unicode box-drawing.\n */\nexport const AXIS_CHARS = {\n /** Y-axis line (│) */\n vertical: \"│\",\n /** X-axis line (─) */\n horizontal: \"─\",\n /** Origin corner (└) */\n origin: \"└\",\n /** Y-axis tick (├) - points right */\n yTick: \"├\",\n /** X-axis tick (┬) - points up */\n xTick: \"┬\",\n /** Grid intersection (┼) */\n cross: \"┼\",\n /** Y-axis with grid (┤) - points left */\n yTickLeft: \"┤\",\n /** X-axis tick (┴) - points down */\n xTickDown: \"┴\",\n} as const;\n\n/**\n * Height blocks for line/area charts.\n * 8 levels of vertical fill from 1/8 to full.\n */\nexport const HEIGHT_BLOCKS = [\n \"▁\", // 1/8\n \"▂\", // 2/8\n \"▃\", // 3/8\n \"▄\", // 4/8\n \"▅\", // 5/8\n \"▆\", // 6/8\n \"▇\", // 7/8\n \"█\", // 8/8 (full)\n] as const;\n\n/**\n * Bar fill characters for different visual styles.\n */\nexport const BAR_CHARS = {\n /** Solid block █ */\n block: \"█\",\n /** Dark shade ▓ */\n shaded: \"▓\",\n /** Light shade ░ */\n light: \"░\",\n /** Hash # */\n hash: \"#\",\n /** Equals = */\n equals: \"=\",\n /** Arrow > */\n arrow: \">\",\n} as const;\n\n/**\n * Braille base character for high-resolution rendering.\n * Unicode U+2800 (blank braille pattern).\n */\nexport const BRAILLE_BASE = 0x2800;\n\n/**\n * Dot positions in a braille cell (standard Unicode layout):\n * ```\n * 1 4\n * 2 5\n * 3 6\n * 7 8\n * ```\n * Each dot adds 2^(position-1) to the base.\n */\nexport const BRAILLE_DOTS = {\n topLeft: 1,\n upperLeft: 2,\n lowerLeft: 3,\n bottomLeft: 7,\n topRight: 4,\n upperRight: 5,\n lowerRight: 6,\n bottomRight: 8,\n} as const;\n\n/**\n * Convert a value (0-1) to a height block character.\n *\n * @param normalized - Value between 0 and 1\n * @returns Appropriate height block character\n */\nexport function valueToBlock(normalized: number): string {\n if (normalized <= 0) return \" \";\n const index = Math.min(7, Math.floor(normalized * 8));\n return HEIGHT_BLOCKS[index] ?? \"█\";\n}\n\n/**\n * Get the bar fill character for a given style.\n *\n * @param style - Bar style name\n * @returns Corresponding fill character\n */\nexport function getBarChar(\n style: \"block\" | \"shaded\" | \"light\" | \"hash\" | \"equals\" | \"arrow\"\n): string {\n return BAR_CHARS[style];\n}\n\n/**\n * Convert an array of dot positions to a braille character.\n *\n * @param dots - Array of dot positions (1-8)\n * @returns Unicode braille character\n */\nexport function toBrailleChar(dots: number[]): string {\n let pattern = 0;\n for (const dot of dots) {\n if (dot >= 1 && dot <= 8) {\n pattern |= 1 << (dot - 1);\n }\n }\n return String.fromCharCode(BRAILLE_BASE + pattern);\n}\n\n/**\n * Series visual distinction styles.\n * Uses combination of fill characters and markdown highlighting.\n */\nexport const SERIES_STYLES = [\n { char: \"█\", useBackticks: false }, // Solid, plain\n { char: \"█\", useBackticks: true }, // Solid, highlighted\n { char: \"▓\", useBackticks: false }, // Shaded, plain\n { char: \"░\", useBackticks: true }, // Light, highlighted\n] as const;\n\n/**\n * Scatter plot marker characters for multi-series distinction.\n */\nexport const SCATTER_MARKERS = {\n circle: \"●\",\n square: \"■\",\n triangle: \"▲\",\n diamond: \"◆\",\n plus: \"+\",\n} as const;\n\n/**\n * Array of scatter markers for series rotation.\n */\nexport const SCATTER_MARKER_SEQUENCE = [\"●\", \"■\", \"▲\", \"◆\", \"+\"] as const;\n\n/**\n * Heatmap intensity characters (low to high).\n * 5 levels from empty to full.\n */\nexport const HEATMAP_BLOCKS = [\" \", \"░\", \"▒\", \"▓\", \"█\"] as const;\n\n/**\n * ASCII-safe heatmap characters (low to high).\n * 5 levels for markdown-friendly output.\n */\nexport const HEATMAP_ASCII = [\" \", \".\", \":\", \"*\", \"#\"] as const;\n\n/**\n * Convert a normalized value (0-1) to a heatmap character.\n *\n * @param normalized - Value between 0 and 1\n * @param style - \"blocks\" for Unicode blocks, \"ascii\" for ASCII chars\n * @returns Appropriate intensity character\n */\nexport function valueToHeatmapChar(\n normalized: number,\n style: \"blocks\" | \"ascii\"\n): string {\n const chars = style === \"blocks\" ? HEATMAP_BLOCKS : HEATMAP_ASCII;\n if (normalized <= 0) return chars[0];\n if (normalized >= 1) return chars[chars.length - 1] ?? \" \";\n const index = Math.min(\n chars.length - 1,\n Math.floor(normalized * chars.length)\n );\n return chars[index] ?? \" \";\n}\n\n/**\n * Line-drawing characters for connecting points.\n */\nexport const LINE_CHARS = {\n /** Point marker */\n point: \"●\",\n /** Horizontal line */\n horizontal: \"─\",\n /** Vertical line */\n vertical: \"│\",\n /** Rising diagonal (approximation) */\n rising: \"╱\",\n /** Falling diagonal (approximation) */\n falling: \"╲\",\n} as const;\n\n/**\n * Braille dot grid for a single character cell.\n * Layout (x, y where y=0 is top):\n * (0,0) (1,0) -> dots 1, 4\n * (0,1) (1,1) -> dots 2, 5\n * (0,2) (1,2) -> dots 3, 6\n * (0,3) (1,3) -> dots 7, 8\n */\nconst BRAILLE_DOT_MAP: Record<string, number> = {\n \"0,0\": 1,\n \"0,1\": 2,\n \"0,2\": 3,\n \"0,3\": 7,\n \"1,0\": 4,\n \"1,1\": 5,\n \"1,2\": 6,\n \"1,3\": 8,\n};\n\n/**\n * A braille canvas for drawing high-resolution graphics.\n * Each character cell contains a 2x4 grid of dots.\n */\nexport class BrailleCanvas {\n /** Width in character cells */\n readonly width: number;\n /** Height in character cells */\n readonly height: number;\n /** Dot grid (width*2 x height*4) */\n private dots: boolean[][];\n /** Series index for each dot (for coloring) */\n private seriesIndices: (number | null)[][];\n\n constructor(width: number, height: number) {\n this.width = width;\n this.height = height;\n // Initialize dot grid (2 dots per char width, 4 dots per char height)\n const dotWidth = width * 2;\n const dotHeight = height * 4;\n this.dots = Array.from({ length: dotHeight }, () =>\n Array.from({ length: dotWidth }, () => false)\n );\n this.seriesIndices = Array.from({ length: dotHeight }, () =>\n Array.from({ length: dotWidth }, () => null)\n );\n }\n\n /**\n * Set a dot at the given dot coordinates.\n */\n setDot(dotX: number, dotY: number, seriesIndex = 0): void {\n if (\n dotX >= 0 &&\n dotX < this.width * 2 &&\n dotY >= 0 &&\n dotY < this.height * 4\n ) {\n const dotRow = this.dots[dotY];\n const seriesRow = this.seriesIndices[dotY];\n if (dotRow && seriesRow) {\n dotRow[dotX] = true;\n seriesRow[dotX] = seriesIndex;\n }\n }\n }\n\n /**\n * Draw a line between two points using Bresenham's algorithm.\n * Coordinates are in dot space (width*2 x height*4).\n */\n drawLine(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n seriesIndex = 0\n ): void {\n const dx = Math.abs(x1 - x0);\n const dy = Math.abs(y1 - y0);\n const sx = x0 < x1 ? 1 : -1;\n const sy = y0 < y1 ? 1 : -1;\n let err = dx - dy;\n\n let x = x0;\n let y = y0;\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Bresenham's algorithm loop\n while (true) {\n this.setDot(x, y, seriesIndex);\n\n if (x === x1 && y === y1) break;\n\n const e2 = 2 * err;\n if (e2 > -dy) {\n err -= dy;\n x += sx;\n }\n if (e2 < dx) {\n err += dx;\n y += sy;\n }\n }\n }\n\n /**\n * Draw a point marker (fills more dots for visibility).\n */\n drawPoint(dotX: number, dotY: number, seriesIndex = 0): void {\n // Draw a small cluster of dots for the point marker\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n this.setDot(dotX + dx, dotY + dy, seriesIndex);\n }\n }\n }\n\n /**\n * Draw a circle outline using the midpoint circle algorithm.\n * Coordinates are in dot space (width*2 x height*4).\n *\n * @param centerX - Center X in dot coordinates\n * @param centerY - Center Y in dot coordinates\n * @param radius - Radius in dot units\n * @param seriesIndex - Series index for coloring\n */\n drawCircle(\n centerX: number,\n centerY: number,\n radius: number,\n seriesIndex = 0\n ): void {\n if (radius <= 0) return;\n\n // Midpoint circle algorithm\n let x = radius;\n let y = 0;\n let err = 1 - radius;\n\n while (x >= y) {\n // Draw all 8 octants\n this.setDot(centerX + x, centerY + y, seriesIndex);\n this.setDot(centerX - x, centerY + y, seriesIndex);\n this.setDot(centerX + x, centerY - y, seriesIndex);\n this.setDot(centerX - x, centerY - y, seriesIndex);\n this.setDot(centerX + y, centerY + x, seriesIndex);\n this.setDot(centerX - y, centerY + x, seriesIndex);\n this.setDot(centerX + y, centerY - x, seriesIndex);\n this.setDot(centerX - y, centerY - x, seriesIndex);\n\n y++;\n if (err < 0) {\n err += 2 * y + 1;\n } else {\n x--;\n err += 2 * (y - x) + 1;\n }\n }\n }\n\n /**\n * Draw an arc (portion of a circle).\n * Angles are in radians, 0 = top (12 o'clock), increasing clockwise.\n *\n * @param centerX - Center X in dot coordinates\n * @param centerY - Center Y in dot coordinates\n * @param radius - Radius in dot units\n * @param startAngle - Start angle in radians (0 = top)\n * @param endAngle - End angle in radians\n * @param seriesIndex - Series index for coloring\n */\n drawArc(\n centerX: number,\n centerY: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n seriesIndex = 0\n ): void {\n if (radius <= 0) return;\n\n // Normalize angles to 0-2π\n const twoPi = Math.PI * 2;\n startAngle = ((startAngle % twoPi) + twoPi) % twoPi;\n endAngle = ((endAngle % twoPi) + twoPi) % twoPi;\n\n // Calculate number of steps based on arc length\n const arcLength =\n endAngle > startAngle\n ? endAngle - startAngle\n : twoPi - startAngle + endAngle;\n const steps = Math.max(8, Math.ceil(radius * arcLength * 0.5));\n\n for (let i = 0; i <= steps; i++) {\n const t = i / steps;\n let angle: number;\n if (endAngle > startAngle) {\n angle = startAngle + t * (endAngle - startAngle);\n } else {\n angle = startAngle + t * (twoPi - startAngle + endAngle);\n if (angle >= twoPi) angle -= twoPi;\n }\n // Convert from \"0 = top\" to standard math coordinates\n // Math: 0 = right, π/2 = top; Our: 0 = top, π/2 = right\n const mathAngle = angle - Math.PI / 2;\n const x = Math.round(centerX + radius * Math.cos(mathAngle));\n const y = Math.round(centerY + radius * Math.sin(mathAngle));\n this.setDot(x, y, seriesIndex);\n }\n }\n\n /**\n * Fill a wedge (pie slice) from center to edge.\n * Angles are in radians, 0 = top (12 o'clock), increasing clockwise.\n *\n * @param centerX - Center X in dot coordinates\n * @param centerY - Center Y in dot coordinates\n * @param radius - Outer radius in dot units\n * @param startAngle - Start angle in radians (0 = top)\n * @param endAngle - End angle in radians\n * @param seriesIndex - Series index for coloring\n * @param innerRadius - Inner radius for donut (0 for pie)\n */\n fillWedge(\n centerX: number,\n centerY: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n seriesIndex = 0,\n innerRadius = 0\n ): void {\n if (radius <= 0) return;\n\n // Normalize angles to 0-2π\n const twoPi = Math.PI * 2;\n startAngle = ((startAngle % twoPi) + twoPi) % twoPi;\n endAngle = ((endAngle % twoPi) + twoPi) % twoPi;\n\n // Use radial filling - draw lines from center to edge\n const arcLength =\n endAngle > startAngle\n ? endAngle - startAngle\n : twoPi - startAngle + endAngle;\n\n // More angular steps for larger arcs\n const angleSteps = Math.max(8, Math.ceil(radius * arcLength * 0.3));\n\n for (let i = 0; i <= angleSteps; i++) {\n const t = i / angleSteps;\n let angle: number;\n if (endAngle > startAngle) {\n angle = startAngle + t * (endAngle - startAngle);\n } else {\n angle = startAngle + t * (twoPi - startAngle + endAngle);\n if (angle >= twoPi) angle -= twoPi;\n }\n\n // Convert from \"0 = top\" to standard math coordinates\n const mathAngle = angle - Math.PI / 2;\n const cos = Math.cos(mathAngle);\n const sin = Math.sin(mathAngle);\n\n // Draw radial line from inner to outer radius\n const startR = Math.ceil(innerRadius);\n for (let r = startR; r <= radius; r++) {\n const x = Math.round(centerX + r * cos);\n const y = Math.round(centerY + r * sin);\n this.setDot(x, y, seriesIndex);\n }\n }\n }\n\n /**\n * Get the braille character at the given character cell.\n */\n getChar(charX: number, charY: number): string {\n const dots: number[] = [];\n const dotBaseX = charX * 2;\n const dotBaseY = charY * 4;\n\n for (let dy = 0; dy < 4; dy++) {\n for (let dx = 0; dx < 2; dx++) {\n const dotX = dotBaseX + dx;\n const dotY = dotBaseY + dy;\n const dotRow = this.dots[dotY];\n if (\n dotY >= 0 &&\n dotY < this.height * 4 &&\n dotX >= 0 &&\n dotX < this.width * 2 &&\n dotRow?.[dotX]\n ) {\n const dotNum = BRAILLE_DOT_MAP[`${String(dx)},${String(dy)}`];\n if (dotNum) {\n dots.push(dotNum);\n }\n }\n }\n }\n\n if (dots.length === 0) {\n return \" \";\n }\n\n return toBrailleChar(dots);\n }\n\n /**\n * Get the dominant series index for a character cell.\n */\n getSeriesIndex(charX: number, charY: number): number | null {\n const counts = new Map<number, number>();\n const dotBaseX = charX * 2;\n const dotBaseY = charY * 4;\n\n for (let dy = 0; dy < 4; dy++) {\n for (let dx = 0; dx < 2; dx++) {\n const dotX = dotBaseX + dx;\n const dotY = dotBaseY + dy;\n if (\n dotY >= 0 &&\n dotY < this.height * 4 &&\n dotX >= 0 &&\n dotX < this.width * 2\n ) {\n const seriesRow = this.seriesIndices[dotY];\n const idx = seriesRow?.[dotX];\n if (idx !== null && idx !== undefined) {\n counts.set(idx, (counts.get(idx) ?? 0) + 1);\n }\n }\n }\n }\n\n let maxCount = 0;\n let maxIndex: number | null = null;\n for (const [idx, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxIndex = idx;\n }\n }\n\n return maxIndex;\n }\n\n /**\n * Render the entire canvas to a 2D array of characters.\n */\n render(): { chars: string[][]; seriesIndices: (number | null)[][] } {\n const chars: string[][] = [];\n const indices: (number | null)[][] = [];\n\n for (let y = 0; y < this.height; y++) {\n const row: string[] = [];\n const indexRow: (number | null)[] = [];\n for (let x = 0; x < this.width; x++) {\n row.push(this.getChar(x, y));\n indexRow.push(this.getSeriesIndex(x, y));\n }\n chars.push(row);\n indices.push(indexRow);\n }\n\n return { chars, seriesIndices: indices };\n }\n}\n","/**\n * Layout computation for stacked bar charts.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n scaleValue,\n} from \"../core/scaling.js\";\nimport { getBarChar, SERIES_STYLES } from \"../core/chars.js\";\nimport type {\n ChartInputWithDefaults,\n BarLayout,\n StackedBarLayout,\n} from \"../types.js\";\n\n/**\n * Computed layout for a stacked bar chart.\n */\nexport interface StackedBarChartLayout {\n /** Chart type */\n type: \"bar-stacked\" | \"bar-stacked-vertical\";\n /** Stacked bars by category */\n stacks: StackedBarLayout[];\n /** Series names for legend */\n seriesNames: string[];\n /** Series styles for legend */\n seriesStyles: { char: string; useBackticks: boolean }[];\n /** Maximum label width */\n maxLabelWidth: number;\n /** Maximum total value width */\n maxValueWidth: number;\n /** Bar area width/height */\n barAreaSize: number;\n /** Y-scale */\n yScale: ReturnType<typeof computeNiceTicks>;\n /** Whether to show values */\n showValues: boolean;\n /** Chart dimensions */\n width: number;\n height: number;\n}\n\n/**\n * Compute layout for a stacked bar chart.\n *\n * @param input - Chart input with defaults\n * @returns Computed stacked bar layout\n */\nexport function computeStackedBarLayout(\n input: ChartInputWithDefaults\n): StackedBarChartLayout {\n const isVertical = input.type === \"bar-stacked-vertical\";\n const series = input.series;\n\n // Build category -> series -> value map\n const categoryTotals = new Map<string, number>();\n const categoryData = new Map<string, Map<number, number>>();\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n for (const point of s.data) {\n const category = String(point.x);\n const value = point.y;\n\n // Track total per category\n const currentTotal = categoryTotals.get(category) ?? 0;\n categoryTotals.set(category, currentTotal + value);\n\n // Track per-series values\n let seriesMap = categoryData.get(category);\n if (!seriesMap) {\n seriesMap = new Map();\n categoryData.set(category, seriesMap);\n }\n seriesMap.set(seriesIndex, value);\n }\n }\n\n const categories = Array.from(categoryTotals.keys());\n\n // Compute Y-scale from totals\n const maxTotal = Math.max(...categoryTotals.values());\n const yScale = computeNiceTicks({\n dataMin: 0,\n dataMax: maxTotal,\n tickCount: input.yAxis?.tickCount ?? 5,\n includeZero: true,\n forceMin: input.yAxis?.min,\n forceMax: input.yAxis?.max,\n });\n\n // Calculate label widths\n let maxLabelWidth = 0;\n for (const category of categories) {\n const width = getStringWidth(category);\n if (width > maxLabelWidth) {\n maxLabelWidth = width;\n }\n }\n\n // Determine bar area size\n const barAreaSize = isVertical\n ? input.height - 2\n : input.width - maxLabelWidth - 3;\n\n // Build stacked bar layouts\n const stacks: StackedBarLayout[] = [];\n let maxValueWidth = 0;\n\n for (const category of categories) {\n const seriesMap = categoryData.get(category);\n const total = categoryTotals.get(category);\n if (!seriesMap || total === undefined) continue;\n const segments: BarLayout[] = [];\n\n let cumulativeValue = 0;\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const value = seriesMap.get(seriesIndex) ?? 0;\n if (value <= 0) continue;\n\n const styleIndex = seriesIndex % SERIES_STYLES.length;\n const styleInfo = SERIES_STYLES[styleIndex];\n if (!styleInfo) continue;\n const s = series[seriesIndex];\n if (!s) continue;\n const barChar = s.style ? getBarChar(s.style) : styleInfo.char;\n const useBackticks = s.style ? false : styleInfo.useBackticks;\n\n // Scale cumulative position\n const startPos = scaleValue(\n cumulativeValue,\n yScale.min,\n yScale.max,\n barAreaSize\n );\n cumulativeValue += value;\n const endPos = scaleValue(\n cumulativeValue,\n yScale.min,\n yScale.max,\n barAreaSize\n );\n const length = Math.max(1, Math.round(endPos - startPos));\n\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n const formattedValue = formatTickValue(value, format, decimals);\n\n const valueWidth = getStringWidth(formattedValue);\n if (valueWidth > maxValueWidth) {\n maxValueWidth = valueWidth;\n }\n\n segments.push({\n seriesIndex,\n pointIndex: categories.indexOf(category),\n label: category,\n value,\n length,\n formattedValue,\n barChar,\n useBackticks,\n percentage: total > 0 ? (value / total) * 100 : 0,\n });\n }\n\n stacks.push({\n label: category,\n segments,\n total,\n });\n }\n\n // Build series info for legend\n const seriesNames = series.map((s) => s.name);\n const seriesStyles = series\n .map((s, i) => {\n const styleIndex = i % SERIES_STYLES.length;\n const styleInfo = SERIES_STYLES[styleIndex];\n if (!styleInfo) return null;\n return {\n char: s.style ? getBarChar(s.style) : styleInfo.char,\n useBackticks: s.style ? false : styleInfo.useBackticks,\n };\n })\n .filter(\n (style): style is { char: string; useBackticks: boolean } =>\n style !== null\n );\n\n return {\n type: isVertical ? \"bar-stacked-vertical\" : \"bar-stacked\",\n stacks,\n seriesNames,\n seriesStyles,\n maxLabelWidth,\n maxValueWidth,\n barAreaSize,\n yScale,\n showValues: input.showValues,\n width: input.width,\n height: input.height,\n };\n}\n","/**\n * Layout computation for line charts.\n *\n * Supports multiple rendering styles:\n * - \"blocks\": Simple line-drawing characters (●, ╱, ╲, ─)\n * - \"braille\": High-resolution braille dot patterns\n * - \"dots\": Point markers only\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n scaleValue,\n} from \"../core/scaling.js\";\nimport { BrailleCanvas, SERIES_STYLES } from \"../core/chars.js\";\nimport type {\n ChartInputWithDefaults,\n LineStyle,\n ValueFormat,\n} from \"../types.js\";\n\n/**\n * A single point in the line chart.\n */\nexport interface LinePoint {\n /** X position (column index) */\n x: number;\n /** Y value (data value) */\n value: number;\n /** Normalized Y (0-1) */\n normalizedY: number;\n /** Series index */\n seriesIndex: number;\n}\n\n/**\n * A row in the line chart display.\n */\nexport interface LineRow {\n /** Y-axis label for this row */\n yLabel?: string | undefined;\n /** Y-axis value at this row */\n yValue: number;\n /** Characters for each column */\n chars: string[];\n /** Whether each char uses backticks (for multi-series distinction) */\n useBackticks: boolean[];\n /** Series index for each column (for ANSI coloring) */\n seriesIndices: (number | null)[];\n}\n\n/**\n * Computed layout for a line chart.\n */\nexport interface LineChartLayout {\n /** Chart type */\n type: \"line\";\n /** Line style */\n lineStyle: LineStyle;\n /** X-axis categories */\n categories: string[];\n /** Series names */\n seriesNames: string[];\n /** Points per series */\n points: LinePoint[][];\n /** Display rows (top to bottom) */\n rows: LineRow[];\n /** Y-scale */\n yScale: ReturnType<typeof computeNiceTicks>;\n /** X-axis label width */\n maxXLabelWidth: number;\n /** Y-axis label width */\n yAxisWidth: number;\n /** Chart dimensions */\n width: number;\n height: number;\n /** Whether to show values */\n showValues: boolean;\n}\n\n/**\n * Line drawing characters for connecting points.\n */\nconst LINE_DRAW = {\n horizontal: \"─\",\n point: \"●\",\n rise: \"╱\",\n fall: \"╲\",\n} as const;\n\n/**\n * Compute layout for a line chart.\n */\nexport function computeLineLayout(\n input: ChartInputWithDefaults\n): LineChartLayout {\n const series = input.series;\n const lineStyle = input.lineStyle;\n\n // Extract all values and categories\n const allValues: number[] = [];\n const categorySet = new Set<string>();\n\n for (const s of series) {\n for (const point of s.data) {\n allValues.push(point.y);\n categorySet.add(String(point.x));\n }\n }\n\n const categories = Array.from(categorySet);\n const seriesNames = series.map((s) => s.name);\n\n // Compute Y-scale\n const dataMin = Math.min(...allValues);\n const dataMax = Math.max(...allValues);\n const yScale = computeNiceTicks({\n dataMin,\n dataMax,\n tickCount: input.yAxis?.tickCount ?? 5,\n includeZero: input.yAxis?.min === undefined,\n forceMin: input.yAxis?.min,\n forceMax: input.yAxis?.max,\n });\n\n // Calculate axis widths\n let maxXLabelWidth = 0;\n for (const category of categories) {\n const width = getStringWidth(category);\n if (width > maxXLabelWidth) {\n maxXLabelWidth = width;\n }\n }\n\n // Calculate Y-axis label width\n let yAxisWidth = 0;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n for (const tick of yScale.ticks) {\n const label = formatTickValue(tick, format, decimals);\n const width = getStringWidth(label);\n if (width > yAxisWidth) {\n yAxisWidth = width;\n }\n }\n yAxisWidth += 2;\n\n const chartHeight = input.height - 2;\n\n // Choose layout based on line style\n if (lineStyle === \"braille\") {\n return computeBrailleLayout(\n input,\n categories,\n seriesNames,\n series,\n yScale,\n yAxisWidth,\n chartHeight,\n format,\n decimals\n );\n } else {\n return computeBlocksLayout(\n input,\n categories,\n seriesNames,\n series,\n yScale,\n yAxisWidth,\n chartHeight,\n format,\n decimals,\n lineStyle\n );\n }\n}\n\n/**\n * Compute layout using simple line-drawing characters.\n */\nfunction computeBlocksLayout(\n input: ChartInputWithDefaults,\n categories: string[],\n seriesNames: string[],\n series: ChartInputWithDefaults[\"series\"],\n yScale: ReturnType<typeof computeNiceTicks>,\n yAxisWidth: number,\n chartHeight: number,\n format: ValueFormat,\n decimals: number | undefined,\n lineStyle: LineStyle\n): LineChartLayout {\n // Two columns per category to allow for connecting lines\n const chartWidth = categories.length * 2 - 1;\n\n // Build points array\n const points: LinePoint[][] = [];\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n const seriesPoints: LinePoint[] = [];\n\n for (const point of s.data) {\n const categoryIndex = categories.indexOf(String(point.x));\n const colPos = categoryIndex * 2;\n const normalizedY = scaleValue(point.y, yScale.min, yScale.max, 1);\n const clampedY = Math.max(0, Math.min(1, normalizedY));\n\n seriesPoints.push({\n x: colPos,\n value: point.y,\n normalizedY: clampedY,\n seriesIndex,\n });\n }\n\n seriesPoints.sort((a, b) => a.x - b.x);\n points.push(seriesPoints);\n }\n\n // Build character grid\n const grid: string[][] = [];\n const seriesGrid: (number | null)[][] = [];\n\n for (let row = 0; row < chartHeight; row++) {\n grid.push(Array(chartWidth).fill(\" \") as string[]);\n seriesGrid.push(Array(chartWidth).fill(null) as (number | null)[]);\n }\n\n // Draw lines between consecutive points for each series\n for (let seriesIndex = 0; seriesIndex < points.length; seriesIndex++) {\n const seriesPoints = points[seriesIndex];\n if (!seriesPoints) continue;\n\n for (let i = 0; i < seriesPoints.length; i++) {\n const p = seriesPoints[i];\n if (!p) continue;\n const row = Math.floor((1 - p.normalizedY) * (chartHeight - 0.001));\n const col = p.x;\n\n if (row >= 0 && row < chartHeight && col >= 0 && col < chartWidth) {\n const gridRow = grid[row];\n const seriesGridRow = seriesGrid[row];\n if (!gridRow || !seriesGridRow) continue;\n\n // Draw point marker (unless dots-only mode)\n gridRow[col] = lineStyle === \"dots\" ? \"●\" : LINE_DRAW.point;\n seriesGridRow[col] = seriesIndex;\n\n // Draw connecting line to next point (skip for dots mode)\n if (lineStyle !== \"dots\" && i < seriesPoints.length - 1) {\n const nextP = seriesPoints[i + 1];\n if (!nextP) continue;\n const nextRow = Math.floor(\n (1 - nextP.normalizedY) * (chartHeight - 0.001)\n );\n const nextCol = nextP.x;\n\n if (nextCol > col + 1) {\n const rowDiff = nextRow - row;\n const colDiff = nextCol - col;\n\n for (let c = col + 1; c < nextCol; c++) {\n const t = (c - col) / colDiff;\n const interpRow = Math.round(row + rowDiff * t);\n\n const interpGridRow = grid[interpRow];\n const interpSeriesGridRow = seriesGrid[interpRow];\n if (\n interpRow >= 0 &&\n interpRow < chartHeight &&\n interpGridRow?.[c] === \" \"\n ) {\n if (rowDiff < 0) {\n interpGridRow[c] = LINE_DRAW.rise;\n } else if (rowDiff > 0) {\n interpGridRow[c] = LINE_DRAW.fall;\n } else {\n interpGridRow[c] = LINE_DRAW.horizontal;\n }\n if (interpSeriesGridRow) {\n interpSeriesGridRow[c] = seriesIndex;\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Build display rows with Y-axis labels\n const rows: LineRow[] = [];\n\n for (let rowIndex = 0; rowIndex < chartHeight; rowIndex++) {\n const rowBottom = 1 - (rowIndex + 1) / chartHeight;\n const rowTop = 1 - rowIndex / chartHeight;\n\n let yLabel: string | undefined;\n let yValue = yScale.min + rowTop * (yScale.max - yScale.min);\n\n for (const tick of yScale.ticks) {\n const tickNormalized = (tick - yScale.min) / (yScale.max - yScale.min);\n if (tickNormalized > rowBottom && tickNormalized <= rowTop) {\n yLabel = formatTickValue(tick, format, decimals);\n yValue = tick;\n break;\n }\n }\n\n const chars = grid[rowIndex];\n const seriesIndices = seriesGrid[rowIndex];\n if (!chars || !seriesIndices) continue;\n\n const useBackticks = seriesIndices.map((idx) => {\n if (idx === null) return false;\n const styleIndex = idx % SERIES_STYLES.length;\n return SERIES_STYLES[styleIndex]?.useBackticks ?? false;\n });\n\n rows.push({ yLabel, yValue, chars, useBackticks, seriesIndices });\n }\n\n return {\n type: \"line\",\n lineStyle: input.lineStyle,\n categories,\n seriesNames,\n points,\n rows,\n yScale,\n maxXLabelWidth: Math.max(...categories.map((c) => getStringWidth(c))),\n yAxisWidth,\n width: input.width,\n height: input.height,\n showValues: input.showValues,\n };\n}\n\n/**\n * Compute layout using braille characters for high-resolution lines.\n */\nfunction computeBrailleLayout(\n input: ChartInputWithDefaults,\n categories: string[],\n seriesNames: string[],\n series: ChartInputWithDefaults[\"series\"],\n yScale: ReturnType<typeof computeNiceTicks>,\n yAxisWidth: number,\n chartHeight: number,\n format: ValueFormat,\n decimals: number | undefined\n): LineChartLayout {\n // For braille, we want more horizontal resolution\n // Each braille char is 2 dots wide, so use more chars per category\n const charsPerCategory = 3;\n const chartWidth = categories.length * charsPerCategory;\n\n // Build points array with braille coordinates\n const points: LinePoint[][] = [];\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n const seriesPoints: LinePoint[] = [];\n\n for (const point of s.data) {\n const categoryIndex = categories.indexOf(String(point.x));\n // Center point within category area\n const colPos =\n categoryIndex * charsPerCategory + Math.floor(charsPerCategory / 2);\n const normalizedY = scaleValue(point.y, yScale.min, yScale.max, 1);\n const clampedY = Math.max(0, Math.min(1, normalizedY));\n\n seriesPoints.push({\n x: colPos,\n value: point.y,\n normalizedY: clampedY,\n seriesIndex,\n });\n }\n\n seriesPoints.sort((a, b) => a.x - b.x);\n points.push(seriesPoints);\n }\n\n // Create braille canvas\n const canvas = new BrailleCanvas(chartWidth, chartHeight);\n\n // Draw lines for each series\n for (let seriesIndex = 0; seriesIndex < points.length; seriesIndex++) {\n const seriesPoints = points[seriesIndex];\n if (!seriesPoints) continue;\n\n for (let i = 0; i < seriesPoints.length; i++) {\n const p = seriesPoints[i];\n if (!p) continue;\n\n // Convert to dot coordinates\n // X: center of the character cell (each char is 2 dots wide)\n const dotX = p.x * 2 + 1;\n // Y: invert because dot Y=0 is top, normalizedY=1 is top\n const dotY = Math.round((1 - p.normalizedY) * (chartHeight * 4 - 1));\n\n // Draw line to next point\n if (i < seriesPoints.length - 1) {\n const nextP = seriesPoints[i + 1];\n if (nextP) {\n const nextDotX = nextP.x * 2 + 1;\n const nextDotY = Math.round(\n (1 - nextP.normalizedY) * (chartHeight * 4 - 1)\n );\n canvas.drawLine(dotX, dotY, nextDotX, nextDotY, seriesIndex);\n }\n }\n\n // Draw point marker\n canvas.drawPoint(dotX, dotY, seriesIndex);\n }\n }\n\n // Render canvas to characters\n const rendered = canvas.render();\n\n // Build display rows with Y-axis labels\n const rows: LineRow[] = [];\n\n for (let rowIndex = 0; rowIndex < chartHeight; rowIndex++) {\n const rowBottom = 1 - (rowIndex + 1) / chartHeight;\n const rowTop = 1 - rowIndex / chartHeight;\n\n let yLabel: string | undefined;\n let yValue = yScale.min + rowTop * (yScale.max - yScale.min);\n\n for (const tick of yScale.ticks) {\n const tickNormalized = (tick - yScale.min) / (yScale.max - yScale.min);\n if (tickNormalized > rowBottom && tickNormalized <= rowTop) {\n yLabel = formatTickValue(tick, format, decimals);\n yValue = tick;\n break;\n }\n }\n\n const chars = rendered.chars[rowIndex] ?? [];\n const seriesIndices = rendered.seriesIndices[rowIndex] ?? [];\n\n const useBackticks = seriesIndices.map((idx) => {\n if (idx === null) return false;\n const styleIndex = idx % SERIES_STYLES.length;\n return SERIES_STYLES[styleIndex]?.useBackticks ?? false;\n });\n\n rows.push({ yLabel, yValue, chars, useBackticks, seriesIndices });\n }\n\n return {\n type: \"line\",\n lineStyle: input.lineStyle,\n categories,\n seriesNames,\n points,\n rows,\n yScale,\n maxXLabelWidth: Math.max(...categories.map((c) => getStringWidth(c))),\n yAxisWidth,\n width: input.width,\n height: input.height,\n showValues: input.showValues,\n };\n}\n","/**\n * Layout computation for area and stacked area charts.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n scaleValue,\n} from \"../core/scaling.js\";\nimport { valueToBlock, SERIES_STYLES } from \"../core/chars.js\";\nimport type { ChartInputWithDefaults, LineStyle } from \"../types.js\";\n\n/**\n * A column in the area chart with stacked values.\n */\nexport interface AreaColumn {\n /** X position */\n x: number;\n /** Category label */\n label: string;\n /** Cumulative values per series (bottom to top) */\n cumulativeValues: number[];\n /** Normalized cumulative heights (0-1) */\n normalizedHeights: number[];\n}\n\n/**\n * A row in the area chart display.\n */\nexport interface AreaRow {\n /** Y-axis label */\n yLabel?: string | undefined;\n /** Characters for each column */\n chars: string[];\n /** Whether each char uses backticks */\n useBackticks: boolean[];\n /** Fill character for each column */\n fillChars: string[];\n}\n\n/**\n * Computed layout for an area chart.\n */\nexport interface AreaChartLayout {\n /** Chart type */\n type: \"area\" | \"area-stacked\";\n /** Line style */\n lineStyle: LineStyle;\n /** X-axis categories */\n categories: string[];\n /** Series names */\n seriesNames: string[];\n /** Series styles */\n seriesStyles: { char: string; useBackticks: boolean }[];\n /** Column data */\n columns: AreaColumn[];\n /** Display rows (top to bottom) */\n rows: AreaRow[];\n /** Y-scale */\n yScale: ReturnType<typeof computeNiceTicks>;\n /** Y-axis label width */\n yAxisWidth: number;\n /** Chart dimensions */\n width: number;\n height: number;\n /** Whether to show values */\n showValues: boolean;\n}\n\n/**\n * Compute layout for an area or stacked area chart.\n *\n * @param input - Chart input with defaults\n * @returns Computed area chart layout\n */\nexport function computeAreaLayout(\n input: ChartInputWithDefaults\n): AreaChartLayout {\n const isStacked = input.type === \"area-stacked\";\n const series = input.series;\n const lineStyle = input.lineStyle;\n\n // Build category -> series -> value map\n const categoryData = new Map<string, number[]>();\n const categories: string[] = [];\n\n // First pass: collect categories in order\n for (const s of series) {\n for (const point of s.data) {\n const category = String(point.x);\n if (!categoryData.has(category)) {\n categoryData.set(\n category,\n new Array(series.length).fill(0) as number[]\n );\n categories.push(category);\n }\n }\n }\n\n // Second pass: fill in values\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n for (const point of s.data) {\n const category = String(point.x);\n const values = categoryData.get(category);\n if (!values) continue;\n values[seriesIndex] = point.y;\n }\n }\n\n // Compute cumulative values and find max\n let maxValue = 0;\n const columns: AreaColumn[] = [];\n\n for (let i = 0; i < categories.length; i++) {\n const category = categories[i];\n if (!category) continue;\n const values = categoryData.get(category);\n if (!values) continue;\n\n const cumulativeValues: number[] = [];\n let cumulative = 0;\n\n for (const value of values) {\n if (isStacked) {\n cumulative += value;\n cumulativeValues.push(cumulative);\n } else {\n cumulativeValues.push(value);\n if (value > cumulative) cumulative = value;\n }\n }\n\n if (cumulative > maxValue) maxValue = cumulative;\n\n columns.push({\n x: i,\n label: category,\n cumulativeValues,\n normalizedHeights: [], // Fill in after we have scale\n });\n }\n\n // Compute Y-scale\n const yScale = computeNiceTicks({\n dataMin: 0,\n dataMax: maxValue,\n tickCount: input.yAxis?.tickCount ?? 5,\n includeZero: true,\n forceMin: input.yAxis?.min,\n forceMax: input.yAxis?.max,\n });\n\n // Calculate normalized heights\n for (const column of columns) {\n column.normalizedHeights = column.cumulativeValues.map((v) =>\n scaleValue(v, yScale.min, yScale.max, 1)\n );\n }\n\n // Calculate Y-axis label width\n let yAxisWidth = 0;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n for (const tick of yScale.ticks) {\n const label = formatTickValue(tick, format, decimals);\n const width = getStringWidth(label);\n if (width > yAxisWidth) {\n yAxisWidth = width;\n }\n }\n yAxisWidth += 2;\n\n // Build series style info\n const seriesNames = series.map((s) => s.name);\n const seriesStyles = series.map((_, i) => {\n const styleIndex = i % SERIES_STYLES.length;\n const style = SERIES_STYLES[styleIndex];\n if (!style) throw new Error(`Invalid style index: ${String(styleIndex)}`);\n return style;\n });\n\n // Determine chart height\n const chartHeight = input.height - 2;\n\n // Build display rows\n const rows: AreaRow[] = [];\n\n for (let rowIndex = 0; rowIndex < chartHeight; rowIndex++) {\n const rowBottom = 1 - (rowIndex + 1) / chartHeight;\n const rowTop = 1 - rowIndex / chartHeight;\n\n // Find Y tick label\n let yLabel: string | undefined;\n for (const tick of yScale.ticks) {\n const tickNormalized = (tick - yScale.min) / (yScale.max - yScale.min);\n if (tickNormalized > rowBottom && tickNormalized <= rowTop) {\n yLabel = formatTickValue(tick, format, decimals);\n break;\n }\n }\n\n // Build characters for each column\n const chars: string[] = [];\n const useBackticks: boolean[] = [];\n const fillChars: string[] = [];\n\n for (const column of columns) {\n // Find which series this row belongs to\n let activeSeriesIndex = -1;\n let fillLevel = 0;\n\n for (\n let seriesIndex = column.normalizedHeights.length - 1;\n seriesIndex >= 0;\n seriesIndex--\n ) {\n const height = column.normalizedHeights[seriesIndex];\n if (height === undefined) continue;\n const prevHeight =\n seriesIndex > 0\n ? (column.normalizedHeights[seriesIndex - 1] ?? 0)\n : 0;\n\n if (height > rowBottom && prevHeight < rowTop) {\n activeSeriesIndex = seriesIndex;\n // Calculate fill level within the row\n const effectiveTop = Math.min(height, rowTop);\n const effectiveBottom = Math.max(prevHeight, rowBottom);\n fillLevel = (effectiveTop - effectiveBottom) / (rowTop - rowBottom);\n break;\n }\n }\n\n if (activeSeriesIndex >= 0) {\n const char = valueToBlock(fillLevel);\n const style = seriesStyles[activeSeriesIndex];\n if (!style) {\n chars.push(\" \");\n useBackticks.push(false);\n fillChars.push(\" \");\n } else {\n chars.push(char);\n useBackticks.push(style.useBackticks);\n fillChars.push(style.char);\n }\n } else {\n chars.push(\" \");\n useBackticks.push(false);\n fillChars.push(\" \");\n }\n }\n\n rows.push({\n yLabel,\n chars,\n useBackticks,\n fillChars,\n });\n }\n\n return {\n type: isStacked ? \"area-stacked\" : \"area\",\n lineStyle,\n categories,\n seriesNames,\n seriesStyles,\n columns,\n rows,\n yScale,\n yAxisWidth,\n width: input.width,\n height: input.height,\n showValues: input.showValues,\n };\n}\n","/**\n * Layout computation for scatter plots.\n *\n * Supports multiple rendering styles:\n * - \"dots\": Simple character markers (●, ■, ▲, ◆, +)\n * - \"braille\": High-resolution braille dot patterns\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n scaleValue,\n} from \"../core/scaling.js\";\nimport { BrailleCanvas, SCATTER_MARKER_SEQUENCE } from \"../core/chars.js\";\nimport type { ChartInputWithDefaults, ScatterStyle } from \"../types.js\";\nimport type { NiceTicksResult } from \"../core/scaling.js\";\n\n/**\n * A single point in the scatter plot.\n */\nexport interface ScatterPoint {\n /** Original X data value */\n dataX: number;\n /** Original Y data value */\n dataY: number;\n /** Character column position */\n charX: number;\n /** Character row position */\n charY: number;\n /** Series index for coloring/marker */\n seriesIndex: number;\n}\n\n/**\n * Computed layout for a scatter chart.\n */\nexport interface ScatterChartLayout {\n /** Chart type */\n type: \"scatter\";\n /** Scatter rendering style */\n scatterStyle: ScatterStyle;\n /** Series names */\n seriesNames: string[];\n /** All points across series */\n points: ScatterPoint[];\n /** X-axis scale */\n xScale: NiceTicksResult;\n /** Y-axis scale */\n yScale: NiceTicksResult;\n /** Y-axis label width */\n yAxisWidth: number;\n /** Chart area width (excluding Y-axis) */\n chartWidth: number;\n /** Chart area height (excluding X-axis) */\n chartHeight: number;\n /** Total width */\n width: number;\n /** Total height */\n height: number;\n /** Character grid for dots mode */\n grid?: string[][];\n /** Series indices for each grid cell */\n seriesIndices?: (number | null)[][];\n /** Braille canvas render result (for braille mode) */\n brailleChars?: string[][];\n /** Braille series indices */\n brailleSeriesIndices?: (number | null)[][];\n}\n\n/**\n * Compute layout for a scatter plot.\n */\nexport function computeScatterLayout(\n input: ChartInputWithDefaults\n): ScatterChartLayout {\n const series = input.series;\n const scatterStyle = input.scatterStyle;\n\n // Extract all X and Y values\n const allXValues: number[] = [];\n const allYValues: number[] = [];\n\n for (const s of series) {\n for (const point of s.data) {\n const xVal = typeof point.x === \"number\" ? point.x : parseFloat(point.x);\n if (!isNaN(xVal)) {\n allXValues.push(xVal);\n }\n allYValues.push(point.y);\n }\n }\n\n if (allXValues.length === 0 || allYValues.length === 0) {\n return {\n type: \"scatter\",\n scatterStyle,\n seriesNames: series.map((s) => s.name),\n points: [],\n xScale: { min: 0, max: 100, step: 20, ticks: [0, 20, 40, 60, 80, 100] },\n yScale: { min: 0, max: 100, step: 20, ticks: [0, 20, 40, 60, 80, 100] },\n yAxisWidth: 6,\n chartWidth: input.width - 6,\n chartHeight: input.height - 2,\n width: input.width,\n height: input.height,\n };\n }\n\n const seriesNames = series.map((s) => s.name);\n\n // Compute scales\n const xDataMin = Math.min(...allXValues);\n const xDataMax = Math.max(...allXValues);\n const yDataMin = Math.min(...allYValues);\n const yDataMax = Math.max(...allYValues);\n\n const xScale = computeNiceTicks({\n dataMin: xDataMin,\n dataMax: xDataMax,\n tickCount: input.xAxis?.tickCount ?? 5,\n includeZero: input.xAxis?.min === undefined,\n forceMin: input.xAxis?.min,\n forceMax: input.xAxis?.max,\n });\n\n const yScale = computeNiceTicks({\n dataMin: yDataMin,\n dataMax: yDataMax,\n tickCount: input.yAxis?.tickCount ?? 5,\n includeZero: input.yAxis?.min === undefined,\n forceMin: input.yAxis?.min,\n forceMax: input.yAxis?.max,\n });\n\n // Calculate axis label widths\n const yFormat = input.yAxis?.format ?? \"number\";\n const yDecimals = input.yAxis?.decimals;\n let yAxisWidth = 0;\n for (const tick of yScale.ticks) {\n const label = formatTickValue(tick, yFormat, yDecimals);\n const width = getStringWidth(label);\n if (width > yAxisWidth) {\n yAxisWidth = width;\n }\n }\n yAxisWidth += 2; // Padding\n\n // Chart dimensions\n const chartHeight = input.height - 2; // Reserve for X-axis\n const chartWidth = input.width - yAxisWidth - 1; // Reserve for Y-axis\n\n // Build points array\n const points: ScatterPoint[] = [];\n\n for (let seriesIndex = 0; seriesIndex < series.length; seriesIndex++) {\n const s = series[seriesIndex];\n if (!s) continue;\n\n for (const point of s.data) {\n const xVal = typeof point.x === \"number\" ? point.x : parseFloat(point.x);\n if (isNaN(xVal)) continue;\n\n const normalizedX = scaleValue(xVal, xScale.min, xScale.max, 1);\n const normalizedY = scaleValue(point.y, yScale.min, yScale.max, 1);\n\n const charX = Math.round(\n Math.max(0, Math.min(1, normalizedX)) * (chartWidth - 1)\n );\n const charY = Math.round(\n (1 - Math.max(0, Math.min(1, normalizedY))) * (chartHeight - 1)\n );\n\n points.push({\n dataX: xVal,\n dataY: point.y,\n charX,\n charY,\n seriesIndex,\n });\n }\n }\n\n // Build grid based on style\n if (scatterStyle === \"braille\") {\n return computeBrailleScatterLayout(\n input,\n seriesNames,\n points,\n xScale,\n yScale,\n yAxisWidth,\n chartWidth,\n chartHeight\n );\n } else {\n return computeDotsScatterLayout(\n input,\n seriesNames,\n points,\n xScale,\n yScale,\n yAxisWidth,\n chartWidth,\n chartHeight\n );\n }\n}\n\n/**\n * Compute scatter layout using simple character markers.\n */\nfunction computeDotsScatterLayout(\n input: ChartInputWithDefaults,\n seriesNames: string[],\n points: ScatterPoint[],\n xScale: NiceTicksResult,\n yScale: NiceTicksResult,\n yAxisWidth: number,\n chartWidth: number,\n chartHeight: number\n): ScatterChartLayout {\n // Create character grid\n const grid: string[][] = [];\n const seriesIndices: (number | null)[][] = [];\n\n for (let row = 0; row < chartHeight; row++) {\n grid.push(Array<string>(chartWidth).fill(\" \"));\n seriesIndices.push(Array<number | null>(chartWidth).fill(null));\n }\n\n // Plot points\n for (const point of points) {\n if (\n point.charY >= 0 &&\n point.charY < chartHeight &&\n point.charX >= 0 &&\n point.charX < chartWidth\n ) {\n // Use different markers for different series\n const marker =\n SCATTER_MARKER_SEQUENCE[\n point.seriesIndex % SCATTER_MARKER_SEQUENCE.length\n ];\n if (!marker) continue;\n const gridRow = grid[point.charY];\n const seriesRow = seriesIndices[point.charY];\n if (!gridRow || !seriesRow) continue;\n gridRow[point.charX] = marker;\n seriesRow[point.charX] = point.seriesIndex;\n }\n }\n\n return {\n type: \"scatter\",\n scatterStyle: \"dots\",\n seriesNames,\n points,\n xScale,\n yScale,\n yAxisWidth,\n chartWidth,\n chartHeight,\n width: input.width,\n height: input.height,\n grid,\n seriesIndices,\n };\n}\n\n/**\n * Compute scatter layout using braille characters.\n */\nfunction computeBrailleScatterLayout(\n input: ChartInputWithDefaults,\n seriesNames: string[],\n points: ScatterPoint[],\n xScale: NiceTicksResult,\n yScale: NiceTicksResult,\n yAxisWidth: number,\n chartWidth: number,\n chartHeight: number\n): ScatterChartLayout {\n // Create braille canvas\n const canvas = new BrailleCanvas(chartWidth, chartHeight);\n\n // Plot points in braille\n for (const point of points) {\n // Convert to dot coordinates (2x width, 4x height)\n // Braille has 2 dots per character width, 4 dots per character height\n const dotX = Math.round(\n scaleValue(point.dataX, xScale.min, xScale.max, chartWidth * 2 - 1)\n );\n // Invert Y since terminal rows go top-to-bottom but data goes bottom-to-top\n const normalizedY = scaleValue(point.dataY, yScale.min, yScale.max, 1);\n const dotY = Math.round((1 - normalizedY) * (chartHeight * 4 - 1));\n\n // Draw a small marker\n canvas.drawPoint(dotX, dotY, point.seriesIndex);\n }\n\n // Render canvas\n const rendered = canvas.render();\n\n return {\n type: \"scatter\",\n scatterStyle: \"braille\",\n seriesNames,\n points,\n xScale,\n yScale,\n yAxisWidth,\n chartWidth,\n chartHeight,\n width: input.width,\n height: input.height,\n brailleChars: rendered.chars,\n brailleSeriesIndices: rendered.seriesIndices,\n };\n}\n","/**\n * Layout computation for pie and donut charts.\n *\n * Uses braille characters to draw circular charts with filled wedges.\n */\n\nimport { BrailleCanvas, SERIES_STYLES } from \"../core/chars.js\";\nimport type { ChartInputWithDefaults } from \"../types.js\";\n\n/**\n * A single slice in a pie chart.\n */\nexport interface PieSlice {\n /** Slice label */\n label: string;\n /** Slice value */\n value: number;\n /** Percentage of total (0-100) */\n percentage: number;\n /** Start angle in radians (0 = top, clockwise) */\n startAngle: number;\n /** End angle in radians */\n endAngle: number;\n /** Display character for legend */\n barChar: string;\n /** Whether to use backticks in markdown */\n useBackticks: boolean;\n /** Series index */\n seriesIndex: number;\n}\n\n/**\n * Computed layout for a pie or donut chart.\n */\nexport interface PieChartLayout {\n /** Chart type */\n type: \"pie\" | \"donut\";\n /** Slices data */\n slices: PieSlice[];\n /** Total value */\n total: number;\n /** Radius in character cells */\n radius: number;\n /** Center X in character cells */\n centerX: number;\n /** Center Y in character cells */\n centerY: number;\n /** Inner radius (0 for pie, >0 for donut) */\n innerRadius: number;\n /** Center label for donut */\n centerLabel?: string;\n /** Chart width */\n width: number;\n /** Chart height */\n height: number;\n /** Braille canvas rendered characters */\n brailleChars: string[][];\n /** Series indices for each character */\n brailleSeriesIndices: (number | null)[][];\n /** Series styles */\n seriesStyles: readonly { char: string; useBackticks: boolean }[];\n}\n\n/**\n * Compute layout for a pie or donut chart.\n */\nexport function computePieLayout(\n input: ChartInputWithDefaults\n): PieChartLayout {\n const type = input.type as \"pie\" | \"donut\";\n const series = input.series;\n\n // Collect all data points as slices\n // For pie charts, we use the first series and each data point becomes a slice\n const slicesData: { label: string; value: number }[] = [];\n for (const s of series) {\n for (const point of s.data) {\n const label = point.label ?? String(point.x);\n // Only accept positive values (filter out zero and negative)\n if (point.y > 0) {\n slicesData.push({ label, value: point.y });\n }\n }\n }\n\n // Calculate total\n const total = slicesData.reduce((sum, s) => sum + s.value, 0);\n\n // Handle edge case: no data or zero total\n if (total === 0 || slicesData.length === 0) {\n return {\n type,\n slices: [],\n total: 0,\n radius: 0,\n centerX: Math.floor(input.width / 2),\n centerY: Math.floor(input.height / 2),\n innerRadius: 0,\n ...(input.centerLabel !== undefined && {\n centerLabel: input.centerLabel,\n }),\n width: input.width,\n height: input.height,\n brailleChars: [],\n brailleSeriesIndices: [],\n seriesStyles: SERIES_STYLES,\n };\n }\n\n // Calculate dimensions\n // Reserve space for legend at bottom\n const chartHeight = input.height - 2;\n const chartWidth = input.width;\n\n // Radius in character cells\n // Terminal characters have a ~2:1 aspect ratio (taller than wide visually)\n // Braille cells are 2 dots wide x 4 dots tall\n // To make circles appear round, we compute radius in character cells,\n // then scale differently for X and Y when converting to dot coordinates\n const maxRadiusY = Math.floor(chartHeight / 2);\n const maxRadiusX = Math.floor(chartWidth / 2);\n const radius = Math.min(maxRadiusX, maxRadiusY);\n\n // Center position\n const centerX = Math.floor(chartWidth / 2);\n const centerY = Math.floor(chartHeight / 2);\n\n // Inner radius for donut (in character cells)\n const innerRadiusRatio = type === \"donut\" ? input.innerRadius : 0;\n\n // Build slices with angles\n const slices: PieSlice[] = [];\n let currentAngle = 0; // Start at top (0 radians)\n\n for (let i = 0; i < slicesData.length; i++) {\n const data = slicesData[i];\n if (!data) continue;\n const percentage = (data.value / total) * 100;\n const arcAngle = (data.value / total) * Math.PI * 2;\n\n const style = SERIES_STYLES[i % SERIES_STYLES.length];\n if (!style) continue;\n\n slices.push({\n label: data.label,\n value: data.value,\n percentage,\n startAngle: currentAngle,\n endAngle: currentAngle + arcAngle,\n barChar: style.char,\n useBackticks: style.useBackticks,\n seriesIndex: i,\n });\n\n currentAngle += arcAngle;\n }\n\n // Create braille canvas and draw\n const canvas = new BrailleCanvas(chartWidth, chartHeight);\n\n // Convert character cell coordinates to dot coordinates\n // Each char cell is 2 dots wide x 4 dots tall\n const dotCenterX = centerX * 2;\n const dotCenterY = centerY * 4;\n // Scale radius: in X direction, 1 char = 2 dots; in Y direction, 1 char = 4 dots\n // For a circle that looks round, we need to compensate\n const dotRadiusX = radius * 2;\n const dotRadiusY = radius * 4;\n const dotRadius = Math.min(dotRadiusX, dotRadiusY);\n const _dotInnerRadius = dotRadius * innerRadiusRatio;\n\n // Draw each slice\n for (const slice of slices) {\n // Use fillWedge with aspect ratio compensation\n // We'll draw with ellipse compensation\n drawEllipticalWedge(\n canvas,\n dotCenterX,\n dotCenterY,\n dotRadiusX,\n dotRadiusY,\n slice.startAngle,\n slice.endAngle,\n slice.seriesIndex,\n dotRadiusX * innerRadiusRatio,\n dotRadiusY * innerRadiusRatio\n );\n }\n\n // Render canvas\n const rendered = canvas.render();\n\n return {\n type,\n slices,\n total,\n radius,\n centerX,\n centerY,\n innerRadius: radius * innerRadiusRatio,\n ...(input.centerLabel !== undefined && { centerLabel: input.centerLabel }),\n width: input.width,\n height: input.height,\n brailleChars: rendered.chars,\n brailleSeriesIndices: rendered.seriesIndices,\n seriesStyles: SERIES_STYLES,\n };\n}\n\n/**\n * Draw an elliptical wedge to compensate for terminal character aspect ratio.\n *\n * Terminal characters have a ~2:1 aspect ratio (taller than wide). This function\n * draws wedges with separate X and Y radii to produce circles that appear round\n * on screen.\n *\n * @param canvas - Braille canvas to draw on\n * @param centerX - Center X coordinate in dot space\n * @param centerY - Center Y coordinate in dot space\n * @param radiusX - Horizontal radius in dots\n * @param radiusY - Vertical radius in dots\n * @param startAngle - Start angle in radians (0 = top, clockwise)\n * @param endAngle - End angle in radians\n * @param seriesIndex - Series index for coloring\n * @param innerRadiusX - Inner horizontal radius for donut hole\n * @param innerRadiusY - Inner vertical radius for donut hole\n */\nfunction drawEllipticalWedge(\n canvas: BrailleCanvas,\n centerX: number,\n centerY: number,\n radiusX: number,\n radiusY: number,\n startAngle: number,\n endAngle: number,\n seriesIndex: number,\n innerRadiusX: number,\n innerRadiusY: number\n): void {\n if (radiusX <= 0 || radiusY <= 0) return;\n\n const twoPi = Math.PI * 2;\n startAngle = ((startAngle % twoPi) + twoPi) % twoPi;\n endAngle = ((endAngle % twoPi) + twoPi) % twoPi;\n\n // Calculate arc length for step count\n const arcLength =\n endAngle > startAngle\n ? endAngle - startAngle\n : twoPi - startAngle + endAngle;\n\n // More steps for larger arcs\n const avgRadius = (radiusX + radiusY) / 2;\n const angleSteps = Math.max(16, Math.ceil(avgRadius * arcLength * 0.4));\n\n for (let i = 0; i <= angleSteps; i++) {\n const t = i / angleSteps;\n let angle: number;\n if (endAngle > startAngle) {\n angle = startAngle + t * (endAngle - startAngle);\n } else {\n angle = startAngle + t * (twoPi - startAngle + endAngle);\n if (angle >= twoPi) angle -= twoPi;\n }\n\n // Convert from \"0 = top\" to standard math coordinates\n const mathAngle = angle - Math.PI / 2;\n const cos = Math.cos(mathAngle);\n const sin = Math.sin(mathAngle);\n\n // Draw radial line from inner to outer with ellipse scaling\n const maxR = Math.max(radiusX, radiusY);\n const innerR = Math.max(innerRadiusX, innerRadiusY);\n\n for (let r = Math.ceil(innerR); r <= maxR; r++) {\n // Scale by aspect ratio\n const scaleX = radiusX / maxR;\n const scaleY = radiusY / maxR;\n const x = Math.round(centerX + r * cos * scaleX);\n const y = Math.round(centerY + r * sin * scaleY);\n canvas.setDot(x, y, seriesIndex);\n }\n }\n}\n","/**\n * Layout computation for heatmap charts.\n *\n * Renders a 2D grid with intensity shading based on values.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport { valueToHeatmapChar } from \"../core/chars.js\";\nimport type { ChartInputWithDefaults, HeatmapStyle } from \"../types.js\";\n\n/**\n * A single cell in the heatmap.\n */\nexport interface HeatmapCell {\n /** Row index */\n row: number;\n /** Column index */\n col: number;\n /** Raw value */\n value: number;\n /** Normalized value (0-1) */\n normalizedValue: number;\n /** Display character */\n displayChar: string;\n}\n\n/**\n * Computed layout for a heatmap chart.\n */\nexport interface HeatmapChartLayout {\n /** Chart type */\n type: \"heatmap\";\n /** Heatmap rendering style */\n heatmapStyle: HeatmapStyle;\n /** Row labels */\n rowLabels: string[];\n /** Column labels */\n colLabels: string[];\n /** Cell data grid (rows x cols) */\n cells: HeatmapCell[][];\n /** Value range */\n valueRange: { min: number; max: number };\n /** Width of each cell in characters */\n cellWidth: number;\n /** Width for column spacing (max of cellWidth and longest column label) */\n colLabelWidth: number;\n /** Width of row labels */\n rowLabelWidth: number;\n /** Total width */\n width: number;\n /** Total height */\n height: number;\n}\n\n/**\n * Compute layout for a heatmap chart.\n */\nexport function computeHeatmapLayout(\n input: ChartInputWithDefaults\n): HeatmapChartLayout {\n const series = input.series;\n const heatmapStyle = input.heatmapStyle;\n\n // Extract row/col labels and values from data\n const rowLabelSet = new Set<string>();\n const colLabelSet = new Set<string>();\n // Use JSON-stringified tuple as key to avoid collisions when labels contain special chars\n const valueMap = new Map<string, number>();\n\n for (const s of series) {\n for (const point of s.data) {\n // For heatmap, we interpret data as:\n // - x: column label\n // - y: value\n // - label: row label (if provided), otherwise series name\n const colLabel = String(point.x);\n const rowLabel = point.label ?? s.name;\n const value = point.y;\n\n rowLabelSet.add(rowLabel);\n colLabelSet.add(colLabel);\n valueMap.set(JSON.stringify([rowLabel, colLabel]), value);\n }\n }\n\n const rowLabels = Array.from(rowLabelSet);\n const colLabels = Array.from(colLabelSet);\n\n // Calculate value range\n const values = Array.from(valueMap.values());\n const minValue = values.length > 0 ? Math.min(...values) : 0;\n const maxValue = values.length > 0 ? Math.max(...values) : 1;\n const valueRange = { min: minValue, max: maxValue };\n\n // Calculate label widths\n let rowLabelWidth = 0;\n for (const label of rowLabels) {\n const width = getStringWidth(label);\n if (width > rowLabelWidth) {\n rowLabelWidth = width;\n }\n }\n rowLabelWidth += 2; // Padding\n\n // Calculate cell width\n // For numeric mode, cells need to show values\n let cellWidth: number;\n if (heatmapStyle === \"numeric\") {\n // Calculate based on max value width\n const maxValueWidth = Math.max(\n getStringWidth(formatValue(minValue)),\n getStringWidth(formatValue(maxValue))\n );\n cellWidth = Math.max(3, maxValueWidth + 1);\n } else {\n // For blocks/ascii, use 2-char cells for visibility\n cellWidth = 2;\n }\n\n // Calculate column label width (max of cellWidth and longest column label)\n let colLabelWidth = cellWidth;\n for (const label of colLabels) {\n const width = getStringWidth(label);\n if (width > colLabelWidth) {\n colLabelWidth = width;\n }\n }\n\n // Build cell grid\n const cells: HeatmapCell[][] = [];\n\n for (let rowIdx = 0; rowIdx < rowLabels.length; rowIdx++) {\n const rowLabel = rowLabels[rowIdx];\n if (!rowLabel) continue;\n const rowCells: HeatmapCell[] = [];\n\n for (let colIdx = 0; colIdx < colLabels.length; colIdx++) {\n const colLabel = colLabels[colIdx];\n if (!colLabel) continue;\n const key = JSON.stringify([rowLabel, colLabel]);\n const value = valueMap.get(key) ?? 0;\n\n // Normalize value\n const range = maxValue - minValue;\n const normalizedValue = range > 0 ? (value - minValue) / range : 0.5;\n\n // Get display character\n let displayChar: string;\n if (heatmapStyle === \"numeric\") {\n displayChar = formatValue(value);\n } else {\n const baseChar = valueToHeatmapChar(\n normalizedValue,\n heatmapStyle === \"blocks\" ? \"blocks\" : \"ascii\"\n );\n displayChar = baseChar.repeat(cellWidth);\n }\n\n rowCells.push({\n row: rowIdx,\n col: colIdx,\n value,\n normalizedValue,\n displayChar,\n });\n }\n\n cells.push(rowCells);\n }\n\n return {\n type: \"heatmap\",\n heatmapStyle,\n rowLabels,\n colLabels,\n cells,\n valueRange,\n cellWidth,\n colLabelWidth,\n rowLabelWidth,\n width: input.width,\n height: input.height,\n };\n}\n\n/**\n * Format a numeric value for display.\n */\nfunction formatValue(value: number): string {\n if (Number.isInteger(value)) {\n return String(value);\n }\n if (Math.abs(value) >= 100) {\n return value.toFixed(0);\n }\n if (Math.abs(value) >= 10) {\n return value.toFixed(1);\n }\n return value.toFixed(2);\n}\n","/**\n * ANSI renderer for charts.\n *\n * Produces ANSI escape code output for rich terminal rendering.\n */\n\nimport { padToWidth, type TuiTheme } from \"@tuicomponents/core\";\nimport { AXIS_CHARS } from \"../core/chars.js\";\nimport { formatTickValue } from \"../core/scaling.js\";\nimport {\n computeLegendLayout,\n type LegendItem,\n type LegendRow,\n} from \"../core/legend.js\";\nimport {\n computeYAxisRow,\n renderXAxis,\n type YAxisConfig,\n} from \"../core/axis-renderer.js\";\nimport type { BarChartLayout } from \"../layout/bar.js\";\nimport type { StackedBarChartLayout } from \"../layout/stacked-bar.js\";\nimport type { LineChartLayout } from \"../layout/line.js\";\nimport type { AreaChartLayout } from \"../layout/area.js\";\nimport type { ScatterChartLayout } from \"../layout/scatter.js\";\nimport type { PieChartLayout } from \"../layout/pie.js\";\nimport type { HeatmapChartLayout } from \"../layout/heatmap.js\";\nimport type { ChartInputWithDefaults } from \"../types.js\";\n\n/**\n * Render a legend row with ANSI colors.\n * Uses secondary color for items that would use backticks in markdown mode.\n */\nfunction renderLegendRowAnsi(row: LegendRow, theme?: TuiTheme): string {\n return row.items\n .map((item) => {\n const symbol =\n item.useBackticks && theme\n ? theme.semantic.secondary(item.symbol)\n : theme\n ? theme.semantic.primary(item.symbol)\n : item.symbol;\n return `${symbol} ${item.name}`;\n })\n .join(\" \");\n}\n\n/**\n * Render options for ANSI output.\n */\nexport interface AnsiRenderOptions {\n /** Theme for colors */\n theme?: TuiTheme | undefined;\n /** Chart input for configuration */\n input: ChartInputWithDefaults;\n}\n\n/**\n * Render a horizontal bar chart to ANSI.\n */\nexport function renderBarChartAnsi(\n layout: BarChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme } = options;\n const lines: string[] = [];\n\n for (const bar of layout.bars) {\n // Build label\n const label = padToWidth(bar.label, layout.maxLabelWidth);\n const coloredLabel = theme ? theme.semantic.header(label) : label;\n\n // Build bar\n const barStr = bar.barChar.repeat(bar.length);\n const coloredBar = theme ? theme.semantic.primary(barStr) : barStr;\n\n // Build value\n const coloredValue = theme\n ? theme.semantic.secondary(bar.formattedValue)\n : bar.formattedValue;\n\n if (layout.showValues) {\n lines.push(`${coloredLabel} ${coloredBar} ${coloredValue}`);\n } else {\n lines.push(`${coloredLabel} ${coloredBar}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a vertical bar chart to ANSI.\n */\nexport function renderVerticalBarChartAnsi(\n layout: BarChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n const chartHeight = layout.barAreaSize;\n const numBars = layout.bars.length;\n const barWidth = Math.max(1, Math.floor((layout.width - 2) / numBars) - 1);\n\n // Build Y-axis labels\n const yAxisWidth = layout.maxValueWidth + 2;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Render rows from top to bottom\n for (let row = chartHeight - 1; row >= 0; row--) {\n const rowThreshold = (row + 1) / chartHeight;\n\n // Y-axis label\n let yLabel = \" \".repeat(yAxisWidth);\n for (const tick of layout.yScale.ticks) {\n const tickNorm =\n (tick - layout.yScale.min) / (layout.yScale.max - layout.yScale.min);\n if (Math.abs(tickNorm - rowThreshold) < 0.5 / chartHeight) {\n yLabel =\n padToWidth(formatTickValue(tick, format, decimals), yAxisWidth - 1) +\n \" \";\n break;\n }\n }\n\n // Axis line\n const axisChar = row === 0 ? AXIS_CHARS.origin : AXIS_CHARS.vertical;\n\n // Build bar segments\n const segments: string[] = [];\n for (const bar of layout.bars) {\n const barNorm = bar.length / layout.barAreaSize;\n if (barNorm >= rowThreshold) {\n const barSegment = bar.barChar.repeat(barWidth);\n segments.push(theme ? theme.semantic.primary(barSegment) : barSegment);\n } else {\n segments.push(\" \".repeat(barWidth));\n }\n }\n\n lines.push(`${yLabel}${axisChar}${segments.join(\" \")}`);\n }\n\n // X-axis line\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.width - yAxisWidth - 1);\n lines.push(\" \".repeat(yAxisWidth) + AXIS_CHARS.origin + xAxisLine);\n\n // X-axis labels\n const xLabels: string[] = [];\n for (const bar of layout.bars) {\n xLabels.push(padToWidth(bar.label, barWidth));\n }\n lines.push(\" \".repeat(yAxisWidth + 1) + xLabels.join(\" \"));\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a stacked bar chart to ANSI.\n */\nexport function renderStackedBarChartAnsi(\n layout: StackedBarChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n const isVertical = layout.type === \"bar-stacked-vertical\";\n\n if (isVertical) {\n const chartHeight = layout.barAreaSize;\n const numStacks = layout.stacks.length;\n const barWidth = Math.max(\n 1,\n Math.floor((layout.width - 2) / numStacks) - 1\n );\n const yAxisWidth = layout.maxValueWidth + 2;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Configure Y-axis\n const yAxisConfig: YAxisConfig = {\n scale: layout.yScale,\n chartHeight,\n labelWidth: yAxisWidth,\n format,\n decimals,\n };\n\n // Render rows from top to bottom\n for (let row = chartHeight - 1; row >= 0; row--) {\n const rowBottom = row / chartHeight;\n const rowTop = (row + 1) / chartHeight;\n\n // Get Y-axis label and tick mark using shared abstraction\n const { label: yLabel, axisChar } = computeYAxisRow(row, yAxisConfig);\n const segments: string[] = [];\n\n for (const stack of layout.stacks) {\n // Find which segment is active at this row\n let activeSegment = null;\n let cumHeight = 0;\n\n for (const segment of stack.segments) {\n const segmentHeight = segment.length / layout.barAreaSize;\n // Check if row overlaps with this segment's range\n if (rowBottom < cumHeight + segmentHeight && rowTop > cumHeight) {\n activeSegment = segment;\n break;\n }\n cumHeight += segmentHeight;\n }\n\n if (activeSegment) {\n const barSegment = activeSegment.barChar.repeat(barWidth);\n segments.push(\n theme ? theme.semantic.primary(barSegment) : barSegment\n );\n } else {\n segments.push(\" \".repeat(barWidth));\n }\n }\n\n lines.push(`${yLabel}${axisChar}${segments.join(\" \")}`);\n }\n\n // Render X-axis using shared abstraction\n const xAxis = renderXAxis({\n categories: layout.stacks.map((s) => s.label),\n barWidth,\n yAxisWidth,\n chartWidth: layout.width,\n minValue: layout.yScale.min,\n format,\n decimals,\n });\n lines.push(xAxis.axisLine);\n lines.push(xAxis.labelLine);\n } else {\n // Horizontal stacked bars\n for (const stack of layout.stacks) {\n const label = padToWidth(stack.label, layout.maxLabelWidth);\n const coloredLabel = theme ? theme.semantic.header(label) : label;\n\n // Build stacked bar\n let barStr = \"\";\n for (const segment of stack.segments) {\n const segmentStr = segment.barChar.repeat(segment.length);\n barStr += theme ? theme.semantic.primary(segmentStr) : segmentStr;\n }\n\n lines.push(`${coloredLabel} ${barStr}`);\n }\n }\n\n // Add legend\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const style = layout.seriesStyles[i];\n if (!style) {\n throw new Error(`Missing series style at index ${String(i)}`);\n }\n return {\n name,\n symbol: style.char,\n useBackticks: style.useBackticks,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(\"\");\n for (const row of legendLayout.rows) {\n lines.push(renderLegendRowAnsi(row, theme));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a line chart to ANSI.\n */\nexport function renderLineChartAnsi(\n layout: LineChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n // Chart width is based on the number of character columns in the rendered rows\n const chartWidth = layout.rows[0]?.chars.length ?? layout.categories.length;\n\n // Render rows\n for (const row of layout.rows) {\n // Y-axis label\n const yLabel = row.yLabel\n ? padToWidth(row.yLabel, layout.yAxisWidth - 1) + \" \"\n : \" \".repeat(layout.yAxisWidth);\n\n // Build line content with series-based coloring\n let content = \"\";\n for (let i = 0; i < row.chars.length; i++) {\n const char = row.chars[i];\n if (char === undefined) {\n continue;\n }\n const seriesIdx = row.seriesIndices[i];\n if (char !== \" \" && theme) {\n // Use secondary color for odd-indexed series\n if (\n seriesIdx !== null &&\n seriesIdx !== undefined &&\n seriesIdx % 2 === 1\n ) {\n content += theme.semantic.secondary(char);\n } else {\n content += theme.semantic.primary(char);\n }\n } else {\n content += char;\n }\n }\n\n lines.push(`${yLabel}${AXIS_CHARS.vertical}${content}`);\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(chartWidth);\n lines.push(\" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine);\n\n // X-axis labels - position depends on layout style\n const labelLine: string[] = Array<string>(chartWidth).fill(\" \");\n const isBraille = layout.lineStyle === \"braille\";\n const spacing = isBraille ? 3 : 2; // chars per category\n for (let i = 0; i < layout.categories.length; i++) {\n const label = layout.categories[i];\n if (label === undefined) {\n continue;\n }\n const pos = isBraille\n ? i * spacing + Math.floor(spacing / 2) // center for braille\n : i * spacing; // even positions for blocks\n if (pos < chartWidth) {\n labelLine[pos] = label.charAt(0) || \" \";\n }\n }\n lines.push(\" \".repeat(layout.yAxisWidth + 1) + labelLine.join(\"\"));\n\n // Legend for multi-series\n if (layout.seriesNames.length > 1) {\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n return {\n name,\n symbol: \"⣿\", // Use braille full block for line chart legend\n useBackticks: i % 2 === 1,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(\"\");\n for (const row of legendLayout.rows) {\n lines.push(renderLegendRowAnsi(row, theme));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render an area chart to ANSI.\n */\nexport function renderAreaChartAnsi(\n layout: AreaChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n // Render rows\n for (const row of layout.rows) {\n const yLabel = row.yLabel\n ? padToWidth(row.yLabel, layout.yAxisWidth - 1) + \" \"\n : \" \".repeat(layout.yAxisWidth);\n\n let content = \"\";\n for (const char of row.chars) {\n if (char !== \" \" && theme) {\n content += theme.semantic.primary(char);\n } else {\n content += char;\n }\n }\n\n lines.push(`${yLabel}${AXIS_CHARS.vertical}${content}`);\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.categories.length);\n lines.push(\" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine);\n\n // X-axis labels\n const xLabels = layout.categories.map((c) => c.charAt(0) || \" \").join(\"\");\n lines.push(\" \".repeat(layout.yAxisWidth + 1) + xLabels);\n\n // Legend\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const style = layout.seriesStyles[i];\n if (!style) {\n throw new Error(`Missing series style at index ${String(i)}`);\n }\n return {\n name,\n symbol: style.char,\n useBackticks: style.useBackticks,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(\"\");\n for (const row of legendLayout.rows) {\n lines.push(renderLegendRowAnsi(row, theme));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a scatter chart to ANSI.\n */\nexport function renderScatterChartAnsi(\n layout: ScatterChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Render rows from top to bottom\n for (let rowIndex = 0; rowIndex < layout.chartHeight; rowIndex++) {\n // Y-axis label\n let yLabel = \" \".repeat(layout.yAxisWidth);\n const rowTop = 1 - rowIndex / layout.chartHeight;\n const rowBottom = 1 - (rowIndex + 1) / layout.chartHeight;\n\n for (const tick of layout.yScale.ticks) {\n const tickNorm =\n (tick - layout.yScale.min) / (layout.yScale.max - layout.yScale.min);\n if (tickNorm > rowBottom && tickNorm <= rowTop) {\n yLabel =\n padToWidth(\n formatTickValue(tick, format, decimals),\n layout.yAxisWidth - 1\n ) + \" \";\n break;\n }\n }\n\n // Build row content\n let content = \"\";\n if (layout.scatterStyle === \"braille\" && layout.brailleChars) {\n const rowChars = layout.brailleChars[rowIndex] ?? [];\n const rowIndices = layout.brailleSeriesIndices?.[rowIndex] ?? [];\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n continue;\n }\n const seriesIdx = rowIndices[i];\n if (char !== \" \" && theme) {\n if (\n seriesIdx !== null &&\n seriesIdx !== undefined &&\n seriesIdx % 2 === 1\n ) {\n content += theme.semantic.secondary(char);\n } else {\n content += theme.semantic.primary(char);\n }\n } else {\n content += char;\n }\n }\n } else if (layout.grid) {\n const rowChars = layout.grid[rowIndex] ?? [];\n const rowIndices = layout.seriesIndices?.[rowIndex] ?? [];\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n continue;\n }\n const seriesIdx = rowIndices[i];\n if (char !== \" \" && theme) {\n if (\n seriesIdx !== null &&\n seriesIdx !== undefined &&\n seriesIdx % 2 === 1\n ) {\n content += theme.semantic.secondary(char);\n } else {\n content += theme.semantic.primary(char);\n }\n } else {\n content += char;\n }\n }\n }\n\n lines.push(`${yLabel}${AXIS_CHARS.vertical}${content}`);\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.chartWidth);\n lines.push(\" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine);\n\n // X-axis labels\n const xFormat = input.xAxis?.format ?? \"number\";\n const xDecimals = input.xAxis?.decimals;\n const labelPositions: { pos: number; label: string }[] = [];\n\n for (const tick of layout.xScale.ticks) {\n const norm =\n (tick - layout.xScale.min) / (layout.xScale.max - layout.xScale.min);\n const pos = Math.round(norm * (layout.chartWidth - 1));\n const label = formatTickValue(tick, xFormat, xDecimals);\n labelPositions.push({ pos, label });\n }\n\n // Build X-axis label line\n const labelLine: string[] = Array<string>(layout.chartWidth).fill(\" \");\n for (const { pos, label } of labelPositions) {\n // Try to center label around position\n const halfLen = Math.floor(label.length / 2);\n const startPos = Math.max(\n 0,\n Math.min(layout.chartWidth - label.length, pos - halfLen)\n );\n for (let i = 0; i < label.length && startPos + i < layout.chartWidth; i++) {\n const char = label[i];\n if (char !== undefined) {\n labelLine[startPos + i] = char;\n }\n }\n }\n lines.push(\" \".repeat(layout.yAxisWidth + 1) + labelLine.join(\"\"));\n\n // Legend for multi-series\n if (layout.seriesNames.length > 1) {\n const symbolArray = [\"●\", \"■\", \"▲\", \"◆\", \"+\"] as const;\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const symbol =\n layout.scatterStyle === \"braille\" ? \"⣿\" : symbolArray[i % 5];\n if (!symbol) {\n throw new Error(`Missing symbol at index ${String(i % 5)}`);\n }\n return {\n name,\n symbol,\n useBackticks: i % 2 === 1,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(\"\");\n for (const row of legendLayout.rows) {\n lines.push(renderLegendRowAnsi(row, theme));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a pie or donut chart to ANSI.\n */\nexport function renderPieChartAnsi(\n layout: PieChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme, input } = options;\n const lines: string[] = [];\n\n // Handle empty chart\n if (layout.slices.length === 0) {\n lines.push(\"No data\");\n return lines.join(\"\\n\");\n }\n\n // Render the braille canvas rows\n for (let rowIndex = 0; rowIndex < layout.brailleChars.length; rowIndex++) {\n const rowChars = layout.brailleChars[rowIndex] ?? [];\n const rowIndices = layout.brailleSeriesIndices[rowIndex] ?? [];\n\n let content = \"\";\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n continue;\n }\n const seriesIdx = rowIndices[i];\n if (char !== \" \" && theme) {\n if (\n seriesIdx !== null &&\n seriesIdx !== undefined &&\n seriesIdx % 2 === 1\n ) {\n content += theme.semantic.secondary(char);\n } else {\n content += theme.semantic.primary(char);\n }\n } else {\n content += char;\n }\n }\n\n // Add center label for donut if this is the center row\n if (\n layout.type === \"donut\" &&\n layout.centerLabel &&\n rowIndex === Math.floor(layout.brailleChars.length / 2)\n ) {\n // Try to overlay center label\n const labelLen = layout.centerLabel.length;\n const startPos = Math.floor((layout.width - labelLen) / 2);\n if (startPos >= 0) {\n // eslint-disable-next-line @typescript-eslint/no-misused-spread -- intentionally decomposing string into chars for overlay\n const contentArray = [...content];\n for (\n let i = 0;\n i < labelLen && startPos + i < contentArray.length;\n i++\n ) {\n const char = layout.centerLabel[i];\n if (char !== undefined) {\n contentArray[startPos + i] = char;\n }\n }\n content = contentArray.join(\"\");\n }\n }\n\n lines.push(content);\n }\n\n // Add legend\n const legendItems: LegendItem[] = layout.slices.map((slice) => ({\n name: `${slice.label} ${slice.percentage.toFixed(0)}%`,\n symbol: slice.barChar,\n useBackticks: slice.useBackticks,\n }));\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(\"\");\n for (const row of legendLayout.rows) {\n lines.push(renderLegendRowAnsi(row, theme));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a heatmap chart to ANSI.\n */\nexport function renderHeatmapAnsi(\n layout: HeatmapChartLayout,\n options: AnsiRenderOptions\n): string {\n const { theme } = options;\n const lines: string[] = [];\n\n // Header row with column labels\n const colLabelRow =\n \" \".repeat(layout.rowLabelWidth) +\n layout.colLabels\n .map((label) => padToWidth(label, layout.colLabelWidth))\n .join(\" \");\n lines.push(colLabelRow);\n\n // Data rows\n for (let rowIdx = 0; rowIdx < layout.rowLabels.length; rowIdx++) {\n const rowLabel = layout.rowLabels[rowIdx];\n if (rowLabel === undefined) {\n continue;\n }\n const rowCells = layout.cells[rowIdx] ?? [];\n\n let row = padToWidth(rowLabel, layout.rowLabelWidth);\n\n for (const cell of rowCells) {\n let cellStr: string;\n if (layout.heatmapStyle === \"numeric\") {\n cellStr = padToWidth(cell.displayChar, layout.colLabelWidth);\n } else {\n // Pad display char to align with column headers\n cellStr = padToWidth(cell.displayChar, layout.colLabelWidth);\n }\n\n // Apply color based on intensity\n if (theme) {\n if (cell.normalizedValue > 0.5) {\n cellStr = theme.semantic.primary(cellStr);\n } else if (cell.normalizedValue > 0.25) {\n cellStr = theme.semantic.secondary(cellStr);\n }\n }\n\n row += cellStr + \" \";\n }\n\n lines.push(row.trimEnd());\n }\n\n // Add scale legend\n if (layout.heatmapStyle !== \"numeric\") {\n lines.push(\"\");\n const scaleLabel =\n layout.heatmapStyle === \"blocks\"\n ? `Scale: ░ ${String(layout.valueRange.min)} ▒ ▓ █ ${String(layout.valueRange.max)}`\n : `Scale: . ${String(layout.valueRange.min)} : * # ${String(layout.valueRange.max)}`;\n lines.push(theme ? theme.semantic.secondary(scaleLabel) : scaleLabel);\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Legend layout computation.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\n\n/**\n * Legend position options.\n */\nexport type LegendPosition = \"none\" | \"top\" | \"bottom\" | \"right\" | \"inline\";\n\n/**\n * A single legend item.\n */\nexport interface LegendItem {\n /** Series name */\n name: string;\n /** Symbol character */\n symbol: string;\n /** Whether to use inline code (backticks) for markdown */\n useBackticks: boolean;\n}\n\n/**\n * Configuration for legend layout.\n */\nexport interface LegendOptions {\n /** Legend items */\n items: LegendItem[];\n /** Legend position */\n position: LegendPosition;\n /** Whether to use boxed style */\n boxed?: boolean;\n /** Maximum width for wrapping */\n maxWidth?: number;\n}\n\n/**\n * A row of legend items.\n */\nexport interface LegendRow {\n /** Items in this row */\n items: LegendItem[];\n /** Total width of this row */\n width: number;\n}\n\n/**\n * Computed legend layout.\n */\nexport interface LegendLayout {\n /** Position of the legend */\n position: LegendPosition;\n /** Whether legend is boxed */\n boxed: boolean;\n /** Legend rows */\n rows: LegendRow[];\n /** Total width of legend */\n totalWidth: number;\n /** Total height of legend (rows) */\n totalHeight: number;\n}\n\n/**\n * Get the display width of a single legend item.\n *\n * Format: \"█ Name\" or \"`█` Name\" (with backticks)\n *\n * @param item - Legend item\n * @returns Display width in characters\n */\nexport function getLegendItemWidth(item: LegendItem): number {\n // Symbol + space + name\n const baseWidth = getStringWidth(item.symbol) + 1 + getStringWidth(item.name);\n\n // Backticks add 1 space before (for visual alignment compensation in markdown)\n if (item.useBackticks) {\n return baseWidth + 1;\n }\n\n return baseWidth;\n}\n\n/**\n * Format a legend item as a string.\n *\n * @param item - Legend item\n * @param forMarkdown - Whether to format for markdown\n * @returns Formatted string\n */\nexport function formatLegendItem(\n item: LegendItem,\n forMarkdown: boolean\n): string {\n if (forMarkdown && item.useBackticks) {\n return ` \\`${item.symbol}\\` ${item.name}`;\n }\n return `${item.symbol} ${item.name}`;\n}\n\n/**\n * Compute the layout for a legend.\n *\n * @param options - Legend configuration\n * @returns Computed legend layout\n */\nexport function computeLegendLayout(options: LegendOptions): LegendLayout {\n const { items, position, boxed = false, maxWidth = 80 } = options;\n\n if (position === \"none\" || items.length === 0) {\n return {\n position,\n boxed,\n rows: [],\n totalWidth: 0,\n totalHeight: 0,\n };\n }\n\n // Calculate item widths\n const itemWidths = items.map((item) => getLegendItemWidth(item));\n\n // Separator between items\n const _separator = \" \"; // Two spaces\n const separatorWidth = 2;\n\n // Try to fit all items on one row\n const rows: LegendRow[] = [];\n let currentRow: LegendItem[] = [];\n let currentWidth = 0;\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const itemWidth = itemWidths[i];\n if (!item || itemWidth === undefined) continue;\n const widthWithSeparator =\n currentRow.length > 0 ? itemWidth + separatorWidth : itemWidth;\n\n if (currentWidth + widthWithSeparator > maxWidth && currentRow.length > 0) {\n // Start new row\n rows.push({ items: currentRow, width: currentWidth });\n currentRow = [item];\n currentWidth = itemWidth;\n } else {\n currentRow.push(item);\n currentWidth += widthWithSeparator;\n }\n }\n\n // Add final row\n if (currentRow.length > 0) {\n rows.push({ items: currentRow, width: currentWidth });\n }\n\n // Calculate total dimensions\n const totalWidth = Math.max(...rows.map((r) => r.width));\n const totalHeight = rows.length + (boxed ? 2 : 0); // Add 2 for box borders\n\n return {\n position,\n boxed,\n rows,\n totalWidth,\n totalHeight,\n };\n}\n\n/**\n * Render a legend row as a string.\n *\n * @param row - Legend row\n * @param forMarkdown - Whether to render for markdown\n * @returns Rendered string\n */\nexport function renderLegendRow(row: LegendRow, forMarkdown: boolean): string {\n return row.items\n .map((item) => formatLegendItem(item, forMarkdown))\n .join(\" \");\n}\n","/**\n * Shared axis rendering utilities for vertical charts.\n *\n * Provides consistent Y-axis and X-axis rendering with tick marks\n * across all chart types (bar, stacked bar, line, area).\n */\n\nimport { padToWidth } from \"@tuicomponents/core\";\nimport { AXIS_CHARS } from \"./chars.js\";\nimport { formatTickValue } from \"./scaling.js\";\n\n/**\n * Y-axis scale information.\n */\nexport interface YAxisScale {\n min: number;\n max: number;\n ticks: number[];\n}\n\n/**\n * Configuration for Y-axis rendering.\n */\nexport interface YAxisConfig {\n /** Scale with min, max, and tick values */\n scale: YAxisScale;\n /** Total chart height in rows */\n chartHeight: number;\n /** Width reserved for Y-axis labels */\n labelWidth: number;\n /** Number format */\n format?: \"number\" | \"percent\" | \"currency\" | \"compact\" | undefined;\n /** Decimal places */\n decimals?: number | undefined;\n}\n\n/**\n * Result of Y-axis label computation for a single row.\n */\nexport interface YAxisRowResult {\n /** Formatted label (padded to labelWidth) or spaces if no tick */\n label: string;\n /** Whether this row has a tick mark */\n hasTick: boolean;\n /** The axis character to use (┤ for tick, │ otherwise) */\n axisChar: string;\n}\n\n/**\n * Compute Y-axis label and tick mark for a given row.\n *\n * @param row - Row index (0 = bottom, chartHeight-1 = top)\n * @param config - Y-axis configuration\n * @returns Label, tick status, and axis character for this row\n */\nexport function computeYAxisRow(\n row: number,\n config: YAxisConfig\n): YAxisRowResult {\n const {\n scale,\n chartHeight,\n labelWidth,\n format = \"number\",\n decimals,\n } = config;\n\n const rowBottom = row / chartHeight;\n const rowTop = (row + 1) / chartHeight;\n\n let label = \" \".repeat(labelWidth);\n let hasTick = false;\n\n for (const tick of scale.ticks) {\n const tickNorm = (tick - scale.min) / (scale.max - scale.min);\n\n // Skip the zero tick - it goes on the x-axis line\n if (tickNorm < 0.001) continue;\n\n // Use inclusive upper bound, exclusive lower bound with small epsilon\n const epsilon = 0.001;\n if (tickNorm > rowBottom - epsilon && tickNorm <= rowTop) {\n label =\n padToWidth(formatTickValue(tick, format, decimals), labelWidth - 1) +\n \" \";\n hasTick = true;\n break;\n }\n }\n\n const axisChar = hasTick ? AXIS_CHARS.yTickLeft : AXIS_CHARS.vertical;\n\n return { label, hasTick, axisChar };\n}\n\n/**\n * Configuration for X-axis rendering.\n */\nexport interface XAxisConfig {\n /** Category labels */\n categories: string[];\n /** Width of each bar/category area */\n barWidth: number;\n /** Width reserved for Y-axis (for alignment) */\n yAxisWidth: number;\n /** Total chart width */\n chartWidth: number;\n /** Minimum value for zero label */\n minValue: number;\n /** Number format for zero label */\n format?: \"number\" | \"percent\" | \"currency\" | \"compact\" | undefined;\n /** Decimal places for zero label */\n decimals?: number | undefined;\n}\n\n/**\n * Result of X-axis rendering.\n */\nexport interface XAxisResult {\n /** The X-axis line with origin and tick marks */\n axisLine: string;\n /** The category labels line (centered under ticks) */\n labelLine: string;\n}\n\n/**\n * Render the X-axis with tick marks and centered labels.\n *\n * @param config - X-axis configuration\n * @returns Axis line and label line\n */\nexport function renderXAxis(config: XAxisConfig): XAxisResult {\n const {\n categories,\n barWidth,\n yAxisWidth,\n chartWidth,\n minValue,\n format = \"number\",\n decimals,\n } = config;\n\n // Zero label aligned with origin\n const zeroLabel =\n padToWidth(formatTickValue(minValue, format, decimals), yAxisWidth - 1) +\n \" \";\n\n // Build x-axis line with tick marks at category centers\n let xAxisLine = \"\";\n for (let i = 0; i < categories.length; i++) {\n const tickPos = Math.floor(barWidth / 2);\n const beforeTick = AXIS_CHARS.horizontal.repeat(tickPos);\n const afterTick = AXIS_CHARS.horizontal.repeat(barWidth - tickPos - 1);\n xAxisLine += beforeTick + AXIS_CHARS.xTick + afterTick;\n if (i < categories.length - 1) {\n xAxisLine += AXIS_CHARS.horizontal; // Space between bars\n }\n }\n\n // Fill remaining width\n const remaining = chartWidth - yAxisWidth - xAxisLine.length - 1;\n if (remaining > 0) {\n xAxisLine += AXIS_CHARS.horizontal.repeat(remaining);\n }\n\n const fullAxisLine = zeroLabel + AXIS_CHARS.origin + xAxisLine;\n\n // Build label line with centered labels\n let labelLine = \"\";\n for (let i = 0; i < categories.length; i++) {\n const label = categories[i];\n if (!label) continue;\n const tickPos = Math.floor(barWidth / 2);\n const labelStart = Math.max(0, tickPos - Math.floor(label.length / 2));\n const labelEnd = labelStart + label.length;\n const paddingBefore = \" \".repeat(labelStart);\n const paddingAfter = \" \".repeat(Math.max(0, barWidth - labelEnd));\n labelLine += paddingBefore + label + paddingAfter;\n if (i < categories.length - 1) {\n labelLine += \" \"; // Space between bars\n }\n }\n\n const fullLabelLine = \" \".repeat(yAxisWidth + 1) + labelLine;\n\n return {\n axisLine: fullAxisLine,\n labelLine: fullLabelLine,\n };\n}\n\n/**\n * Configuration for a complete chart area with axes.\n */\nexport interface ChartAreaConfig {\n /** Y-axis configuration */\n yAxis: YAxisConfig;\n /** X-axis configuration */\n xAxis: XAxisConfig;\n}\n\n/**\n * Helper to build a complete row with Y-axis and content.\n *\n * @param row - Row index\n * @param content - The chart content for this row\n * @param config - Y-axis configuration\n * @returns Complete row string with Y-axis label and content\n */\nexport function buildChartRow(\n row: number,\n content: string,\n config: YAxisConfig\n): string {\n const { label, axisChar } = computeYAxisRow(row, config);\n return `${label}${axisChar}${content}`;\n}\n","/**\n * Markdown renderer for charts.\n *\n * Produces markdown-friendly output using a two-color system:\n * - Primary: Plain text\n * - Secondary: Inline code (backticks)\n */\n\nimport { padToWidth, anchorLine, DEFAULT_ANCHOR } from \"@tuicomponents/core\";\nimport { AXIS_CHARS } from \"../core/chars.js\";\nimport { formatTickValue } from \"../core/scaling.js\";\nimport {\n renderLegendRow,\n computeLegendLayout,\n type LegendItem,\n} from \"../core/legend.js\";\nimport {\n computeYAxisRow,\n renderXAxis,\n type YAxisConfig,\n} from \"../core/axis-renderer.js\";\nimport type { BarChartLayout } from \"../layout/bar.js\";\nimport type { StackedBarChartLayout } from \"../layout/stacked-bar.js\";\nimport type { LineChartLayout } from \"../layout/line.js\";\nimport type { AreaChartLayout } from \"../layout/area.js\";\nimport type { ScatterChartLayout } from \"../layout/scatter.js\";\nimport type { PieChartLayout } from \"../layout/pie.js\";\nimport type { HeatmapChartLayout } from \"../layout/heatmap.js\";\nimport type { ChartInputWithDefaults } from \"../types.js\";\n\n/**\n * Render options for markdown output.\n */\nexport interface MarkdownRenderOptions {\n /** Chart input for configuration */\n input: ChartInputWithDefaults;\n}\n\n/**\n * Wrap text in inline code if needed.\n */\nfunction wrapInlineCode(text: string, useBackticks: boolean): string {\n if (useBackticks) {\n return ` \\`${text}\\``;\n }\n return text;\n}\n\n/**\n * Render a horizontal bar chart to markdown.\n */\nexport function renderBarChartMarkdown(\n layout: BarChartLayout,\n _options: MarkdownRenderOptions\n): string {\n const lines: string[] = [];\n\n for (const bar of layout.bars) {\n const label = padToWidth(bar.label, layout.maxLabelWidth);\n const barStr = bar.barChar.repeat(bar.length);\n const styledBar = wrapInlineCode(barStr, bar.useBackticks);\n\n let content: string;\n if (layout.showValues) {\n content = `${label} ${styledBar} ${bar.formattedValue}`;\n } else {\n content = `${label} ${styledBar}`;\n }\n\n // Add compensation for backticks\n if (bar.useBackticks) {\n content += \" \";\n }\n\n lines.push(anchorLine(content, DEFAULT_ANCHOR));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a vertical bar chart to markdown.\n */\nexport function renderVerticalBarChartMarkdown(\n layout: BarChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n const chartHeight = layout.barAreaSize;\n const numBars = layout.bars.length;\n const barWidth = Math.max(1, Math.floor((layout.width - 2) / numBars) - 1);\n const yAxisWidth = layout.maxValueWidth + 2;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Render rows from top to bottom\n for (let row = chartHeight - 1; row >= 0; row--) {\n const rowThreshold = (row + 1) / chartHeight;\n\n // Y-axis label\n let yLabel = \" \".repeat(yAxisWidth);\n for (const tick of layout.yScale.ticks) {\n const tickNorm =\n (tick - layout.yScale.min) / (layout.yScale.max - layout.yScale.min);\n if (Math.abs(tickNorm - rowThreshold) < 0.5 / chartHeight) {\n yLabel =\n padToWidth(formatTickValue(tick, format, decimals), yAxisWidth - 1) +\n \" \";\n break;\n }\n }\n\n const axisChar = row === 0 ? AXIS_CHARS.origin : AXIS_CHARS.vertical;\n\n // Build bar segments\n const segments: string[] = [];\n for (const bar of layout.bars) {\n const barNorm = bar.length / layout.barAreaSize;\n if (barNorm >= rowThreshold) {\n const barSegment = bar.barChar.repeat(barWidth);\n segments.push(wrapInlineCode(barSegment, bar.useBackticks));\n } else {\n segments.push(\" \".repeat(barWidth));\n }\n }\n\n lines.push(\n anchorLine(`${yLabel}${axisChar}${segments.join(\" \")}`, DEFAULT_ANCHOR)\n );\n }\n\n // X-axis line\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.width - yAxisWidth - 1);\n lines.push(\n anchorLine(\n \" \".repeat(yAxisWidth) + AXIS_CHARS.origin + xAxisLine,\n DEFAULT_ANCHOR\n )\n );\n\n // X-axis labels\n const xLabels: string[] = [];\n for (const bar of layout.bars) {\n xLabels.push(padToWidth(bar.label, barWidth));\n }\n lines.push(\n anchorLine(\" \".repeat(yAxisWidth + 1) + xLabels.join(\" \"), DEFAULT_ANCHOR)\n );\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a stacked bar chart to markdown.\n */\nexport function renderStackedBarChartMarkdown(\n layout: StackedBarChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n const isVertical = layout.type === \"bar-stacked-vertical\";\n\n if (isVertical) {\n const chartHeight = layout.barAreaSize;\n const numStacks = layout.stacks.length;\n const barWidth = Math.max(\n 1,\n Math.floor((layout.width - 2) / numStacks) - 1\n );\n const yAxisWidth = layout.maxValueWidth + 2;\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Configure Y-axis\n const yAxisConfig: YAxisConfig = {\n scale: layout.yScale,\n chartHeight,\n labelWidth: yAxisWidth,\n format,\n decimals,\n };\n\n for (let row = chartHeight - 1; row >= 0; row--) {\n const rowBottom = row / chartHeight;\n const rowTop = (row + 1) / chartHeight;\n\n // Get Y-axis label and tick mark using shared abstraction\n const { label: yLabel, axisChar } = computeYAxisRow(row, yAxisConfig);\n const segments: string[] = [];\n\n for (const stack of layout.stacks) {\n let activeSegment = null;\n let cumHeight = 0;\n\n for (const segment of stack.segments) {\n const segmentHeight = segment.length / layout.barAreaSize;\n // Check if row overlaps with this segment's range\n if (rowBottom < cumHeight + segmentHeight && rowTop > cumHeight) {\n activeSegment = segment;\n break;\n }\n cumHeight += segmentHeight;\n }\n\n if (activeSegment) {\n const barSegment = activeSegment.barChar.repeat(barWidth);\n // Don't use wrapInlineCode to avoid leading space in bar segments\n if (activeSegment.useBackticks) {\n segments.push(`\\`${barSegment}\\``);\n } else {\n segments.push(barSegment);\n }\n } else {\n segments.push(\" \".repeat(barWidth));\n }\n }\n\n lines.push(\n anchorLine(`${yLabel}${axisChar}${segments.join(\" \")}`, DEFAULT_ANCHOR)\n );\n }\n\n // Render X-axis using shared abstraction\n const xAxis = renderXAxis({\n categories: layout.stacks.map((s) => s.label),\n barWidth,\n yAxisWidth,\n chartWidth: layout.width,\n minValue: layout.yScale.min,\n format,\n decimals,\n });\n lines.push(anchorLine(xAxis.axisLine, DEFAULT_ANCHOR));\n lines.push(anchorLine(xAxis.labelLine, DEFAULT_ANCHOR));\n } else {\n // Horizontal stacked bars\n for (const stack of layout.stacks) {\n const label = padToWidth(stack.label, layout.maxLabelWidth);\n\n // Build stacked bar with alternating styles\n // Don't use wrapInlineCode here as segments should be continuous without gaps\n let barStr = \"\";\n for (const segment of stack.segments) {\n const segmentStr = segment.barChar.repeat(segment.length);\n if (segment.useBackticks) {\n barStr += `\\`${segmentStr}\\``;\n } else {\n barStr += segmentStr;\n }\n }\n\n lines.push(anchorLine(`${label} ${barStr}`, DEFAULT_ANCHOR));\n }\n }\n\n // Add legend\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const style = layout.seriesStyles[i];\n if (!style) {\n throw new Error(`Missing style for series ${String(i)}`);\n }\n return {\n name,\n symbol: style.char,\n useBackticks: style.useBackticks,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n for (const row of legendLayout.rows) {\n lines.push(anchorLine(renderLegendRow(row, true), DEFAULT_ANCHOR));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a line chart to markdown.\n */\nexport function renderLineChartMarkdown(\n layout: LineChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n // Chart width is based on the number of character columns in the rendered rows\n const chartWidth = layout.rows[0]?.chars.length ?? layout.categories.length;\n\n // Render rows\n for (const row of layout.rows) {\n const yLabel = row.yLabel\n ? padToWidth(row.yLabel, layout.yAxisWidth - 1) + \" \"\n : \" \".repeat(layout.yAxisWidth);\n\n let content = \"\";\n for (let i = 0; i < row.chars.length; i++) {\n const char = row.chars[i];\n const useBackticks = row.useBackticks[i];\n if (char === undefined || useBackticks === undefined) {\n throw new Error(`Missing char or useBackticks at index ${String(i)}`);\n }\n content += wrapInlineCode(char, useBackticks && char !== \" \");\n }\n\n lines.push(\n anchorLine(`${yLabel}${AXIS_CHARS.vertical}${content}`, DEFAULT_ANCHOR)\n );\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(chartWidth);\n lines.push(\n anchorLine(\n \" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine,\n DEFAULT_ANCHOR\n )\n );\n\n // X-axis labels - position depends on layout style\n const labelLine = Array<string>(chartWidth).fill(\" \");\n const isBraille = layout.lineStyle === \"braille\";\n const spacing = isBraille ? 3 : 2; // chars per category\n for (let i = 0; i < layout.categories.length; i++) {\n const label = layout.categories[i];\n if (label === undefined) {\n throw new Error(`Missing category at index ${String(i)}`);\n }\n const pos = isBraille\n ? i * spacing + Math.floor(spacing / 2) // center for braille\n : i * spacing; // even positions for blocks\n if (pos < chartWidth) {\n labelLine[pos] = label.charAt(0) || \" \";\n }\n }\n lines.push(\n anchorLine(\n \" \".repeat(layout.yAxisWidth + 1) + labelLine.join(\"\"),\n DEFAULT_ANCHOR\n )\n );\n\n // Legend for multi-series\n if (layout.seriesNames.length > 1) {\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n return {\n name,\n symbol: \"⣿\", // Use braille full block for line chart legend\n useBackticks: i % 2 === 1,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n for (const row of legendLayout.rows) {\n lines.push(anchorLine(renderLegendRow(row, true), DEFAULT_ANCHOR));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render an area chart to markdown.\n */\nexport function renderAreaChartMarkdown(\n layout: AreaChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n // Render rows\n for (const row of layout.rows) {\n const yLabel = row.yLabel\n ? padToWidth(row.yLabel, layout.yAxisWidth - 1) + \" \"\n : \" \".repeat(layout.yAxisWidth);\n\n let content = \"\";\n for (let i = 0; i < row.chars.length; i++) {\n const char = row.chars[i];\n const useBackticks = row.useBackticks[i];\n if (char === undefined || useBackticks === undefined) {\n throw new Error(`Missing char or useBackticks at index ${String(i)}`);\n }\n content += wrapInlineCode(char, useBackticks && char !== \" \");\n }\n\n lines.push(\n anchorLine(`${yLabel}${AXIS_CHARS.vertical}${content}`, DEFAULT_ANCHOR)\n );\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.categories.length);\n lines.push(\n anchorLine(\n \" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine,\n DEFAULT_ANCHOR\n )\n );\n\n // X-axis labels\n const xLabels = layout.categories.map((c) => c.charAt(0) || \" \").join(\"\");\n lines.push(\n anchorLine(\" \".repeat(layout.yAxisWidth + 1) + xLabels, DEFAULT_ANCHOR)\n );\n\n // Legend\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const style = layout.seriesStyles[i];\n if (!style) {\n throw new Error(`Missing style for series ${String(i)}`);\n }\n return {\n name,\n symbol: style.char,\n useBackticks: style.useBackticks,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n for (const row of legendLayout.rows) {\n lines.push(anchorLine(renderLegendRow(row, true), DEFAULT_ANCHOR));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a scatter chart to markdown.\n */\nexport function renderScatterChartMarkdown(\n layout: ScatterChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n const format = input.yAxis?.format ?? \"number\";\n const decimals = input.yAxis?.decimals;\n\n // Render rows from top to bottom\n for (let rowIndex = 0; rowIndex < layout.chartHeight; rowIndex++) {\n // Y-axis label\n let yLabel = \" \".repeat(layout.yAxisWidth);\n const rowTop = 1 - rowIndex / layout.chartHeight;\n const rowBottom = 1 - (rowIndex + 1) / layout.chartHeight;\n\n for (const tick of layout.yScale.ticks) {\n const tickNorm =\n (tick - layout.yScale.min) / (layout.yScale.max - layout.yScale.min);\n if (tickNorm > rowBottom && tickNorm <= rowTop) {\n yLabel =\n padToWidth(\n formatTickValue(tick, format, decimals),\n layout.yAxisWidth - 1\n ) + \" \";\n break;\n }\n }\n\n // Build row content\n let content = \"\";\n if (layout.scatterStyle === \"braille\" && layout.brailleChars) {\n const rowChars = layout.brailleChars[rowIndex] ?? [];\n const rowIndices = layout.brailleSeriesIndices?.[rowIndex] ?? [];\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n throw new Error(`Missing char at index ${String(i)}`);\n }\n const seriesIdx = rowIndices[i];\n const useBackticks =\n seriesIdx !== null && seriesIdx !== undefined && seriesIdx % 2 === 1;\n content += wrapInlineCode(char, useBackticks && char !== \" \");\n }\n } else if (layout.grid) {\n const rowChars = layout.grid[rowIndex] ?? [];\n const rowIndices = layout.seriesIndices?.[rowIndex] ?? [];\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n throw new Error(`Missing char at index ${String(i)}`);\n }\n const seriesIdx = rowIndices[i];\n const useBackticks =\n seriesIdx !== null && seriesIdx !== undefined && seriesIdx % 2 === 1;\n content += wrapInlineCode(char, useBackticks && char !== \" \");\n }\n }\n\n lines.push(\n anchorLine(`${yLabel}${AXIS_CHARS.vertical}${content}`, DEFAULT_ANCHOR)\n );\n }\n\n // X-axis\n const xAxisLine = AXIS_CHARS.horizontal.repeat(layout.chartWidth);\n lines.push(\n anchorLine(\n \" \".repeat(layout.yAxisWidth) + AXIS_CHARS.origin + xAxisLine,\n DEFAULT_ANCHOR\n )\n );\n\n // X-axis labels\n const xFormat = input.xAxis?.format ?? \"number\";\n const xDecimals = input.xAxis?.decimals;\n const labelPositions: { pos: number; label: string }[] = [];\n\n for (const tick of layout.xScale.ticks) {\n const norm =\n (tick - layout.xScale.min) / (layout.xScale.max - layout.xScale.min);\n const pos = Math.round(norm * (layout.chartWidth - 1));\n const label = formatTickValue(tick, xFormat, xDecimals);\n labelPositions.push({ pos, label });\n }\n\n // Build X-axis label line\n const labelLine = Array<string>(layout.chartWidth).fill(\" \");\n for (const { pos, label } of labelPositions) {\n const halfLen = Math.floor(label.length / 2);\n const startPos = Math.max(\n 0,\n Math.min(layout.chartWidth - label.length, pos - halfLen)\n );\n for (let i = 0; i < label.length && startPos + i < layout.chartWidth; i++) {\n const char = label[i];\n if (char === undefined) {\n throw new Error(`Missing char at index ${String(i)}`);\n }\n labelLine[startPos + i] = char;\n }\n }\n lines.push(\n anchorLine(\n \" \".repeat(layout.yAxisWidth + 1) + labelLine.join(\"\"),\n DEFAULT_ANCHOR\n )\n );\n\n // Legend for multi-series\n if (layout.seriesNames.length > 1) {\n const legendItems: LegendItem[] = layout.seriesNames.map((name, i) => {\n const symbols = [\"●\", \"■\", \"▲\", \"◆\", \"+\"];\n const symbol = layout.scatterStyle === \"braille\" ? \"⣿\" : symbols[i % 5];\n if (!symbol) {\n throw new Error(`Missing symbol for series ${String(i)}`);\n }\n return {\n name,\n symbol,\n useBackticks: i % 2 === 1,\n };\n });\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n for (const row of legendLayout.rows) {\n lines.push(anchorLine(renderLegendRow(row, true), DEFAULT_ANCHOR));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a pie or donut chart to markdown.\n */\nexport function renderPieChartMarkdown(\n layout: PieChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input } = options;\n const lines: string[] = [];\n\n // Handle empty chart\n if (layout.slices.length === 0) {\n lines.push(anchorLine(\"No data\", DEFAULT_ANCHOR));\n return lines.join(\"\\n\");\n }\n\n // Render the braille canvas rows\n for (let rowIndex = 0; rowIndex < layout.brailleChars.length; rowIndex++) {\n const rowChars = layout.brailleChars[rowIndex] ?? [];\n const rowIndices = layout.brailleSeriesIndices[rowIndex] ?? [];\n\n let content = \"\";\n for (let i = 0; i < rowChars.length; i++) {\n const char = rowChars[i];\n if (char === undefined) {\n throw new Error(`Missing char at index ${String(i)}`);\n }\n const seriesIdx = rowIndices[i];\n const useBackticks =\n seriesIdx !== null && seriesIdx !== undefined && seriesIdx % 2 === 1;\n content += wrapInlineCode(char, useBackticks && char !== \" \");\n }\n\n // Add center label for donut if this is the center row\n if (\n layout.type === \"donut\" &&\n layout.centerLabel &&\n rowIndex === Math.floor(layout.brailleChars.length / 2)\n ) {\n const labelLen = layout.centerLabel.length;\n const startPos = Math.floor((layout.width - labelLen) / 2);\n if (startPos >= 0) {\n // eslint-disable-next-line @typescript-eslint/no-misused-spread -- intentional string spread for character manipulation\n const contentArray = [...content];\n for (\n let i = 0;\n i < labelLen && startPos + i < contentArray.length;\n i++\n ) {\n const char = layout.centerLabel[i];\n if (char === undefined) {\n throw new Error(`Missing centerLabel char at index ${String(i)}`);\n }\n contentArray[startPos + i] = char;\n }\n content = contentArray.join(\"\");\n }\n }\n\n lines.push(anchorLine(content, DEFAULT_ANCHOR));\n }\n\n // Add legend\n const legendItems: LegendItem[] = layout.slices.map((slice) => ({\n name: `${slice.label} ${slice.percentage.toFixed(0)}%`,\n symbol: slice.barChar,\n useBackticks: slice.useBackticks,\n }));\n\n const legendLayout = computeLegendLayout({\n items: legendItems,\n position: input.legend?.position ?? \"bottom\",\n maxWidth: layout.width,\n });\n\n if (legendLayout.rows.length > 0) {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n for (const row of legendLayout.rows) {\n lines.push(anchorLine(renderLegendRow(row, true), DEFAULT_ANCHOR));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a heatmap chart to markdown.\n */\nexport function renderHeatmapMarkdown(\n layout: HeatmapChartLayout,\n options: MarkdownRenderOptions\n): string {\n const { input: _input } = options;\n const lines: string[] = [];\n\n // Handle empty chart\n if (layout.cells.length === 0 || (layout.cells[0]?.length ?? 0) === 0) {\n lines.push(anchorLine(\"No data\", DEFAULT_ANCHOR));\n return lines.join(\"\\n\");\n }\n\n // Column header row\n const colHeaderPadding = \" \".repeat(layout.rowLabelWidth);\n const colHeaders = layout.colLabels\n .map((label: string) => padToWidth(label, layout.colLabelWidth))\n .join(\"\");\n lines.push(anchorLine(`${colHeaderPadding}${colHeaders}`, DEFAULT_ANCHOR));\n\n // Data rows\n for (let rowIdx = 0; rowIdx < layout.rowLabels.length; rowIdx++) {\n const rowLabelText = layout.rowLabels[rowIdx];\n if (!rowLabelText) continue;\n const rowLabel = padToWidth(rowLabelText, layout.rowLabelWidth);\n const rowCells = layout.cells[rowIdx];\n if (!rowCells) continue;\n\n let rowContent = \"\";\n for (const cell of rowCells) {\n // For numeric style, don't use backticks; for blocks/ascii, use intensity-based styling\n if (layout.heatmapStyle === \"numeric\") {\n rowContent += padToWidth(cell.displayChar, layout.colLabelWidth);\n } else {\n // Alternate backticks for visual distinction, pad to align with column headers\n const useBackticks = cell.normalizedValue > 0.5;\n const paddedChar = padToWidth(cell.displayChar, layout.colLabelWidth);\n const styled = wrapInlineCode(paddedChar, useBackticks);\n rowContent += styled;\n }\n }\n\n lines.push(anchorLine(`${rowLabel}${rowContent}`, DEFAULT_ANCHOR));\n }\n\n // Add scale legend for non-numeric styles\n if (layout.heatmapStyle !== \"numeric\") {\n lines.push(anchorLine(\"\", DEFAULT_ANCHOR));\n const scaleChars =\n layout.heatmapStyle === \"blocks\"\n ? [\"░\", \"▒\", \"▓\", \"█\"]\n : [\".\", \":\", \"*\", \"#\"];\n const scaleLabels = [\"Low\", \"\", \"\", \"High\"];\n let scaleLine = \"Scale: \";\n for (let i = 0; i < scaleChars.length; i++) {\n const char = scaleChars[i] ?? \"\";\n const label = scaleLabels[i] ?? \"\";\n scaleLine += `${char} ${label}`;\n if (i < scaleChars.length - 1) scaleLine += \" \";\n }\n lines.push(anchorLine(scaleLine, DEFAULT_ANCHOR));\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Axis layout computation for chart rendering.\n */\n\nimport { getStringWidth } from \"@tuicomponents/core\";\nimport {\n computeNiceTicks,\n formatTickValue,\n type NiceTicksResult,\n} from \"./scaling.js\";\n\n/**\n * Axis orientation.\n */\nexport type AxisOrientation = \"horizontal\" | \"vertical\";\n\n/**\n * Axis position relative to the chart area.\n */\nexport type AxisPosition = \"left\" | \"right\" | \"top\" | \"bottom\";\n\n/**\n * Configuration for axis layout computation.\n */\nexport interface AxisLayoutOptions {\n /** Data minimum value */\n dataMin: number;\n /** Data maximum value */\n dataMax: number;\n /** Available space for the axis (characters) */\n size: number;\n /** Axis orientation */\n orientation: AxisOrientation;\n /** Axis position */\n position: AxisPosition;\n /** Desired number of ticks */\n tickCount?: number;\n /** Whether to show tick marks */\n showTicks?: boolean;\n /** Label format */\n format?: \"number\" | \"percent\" | \"compact\" | \"currency\";\n /** Decimal places for labels */\n decimals?: number;\n /** Axis title */\n label?: string;\n /** Force minimum value */\n forceMin?: number;\n /** Force maximum value */\n forceMax?: number;\n /** Include zero in range */\n includeZero?: boolean;\n}\n\n/**\n * A single tick mark on an axis.\n */\nexport interface AxisTick {\n /** Tick value */\n value: number;\n /** Formatted label string */\n label: string;\n /** Position along axis (0 to size) */\n position: number;\n}\n\n/**\n * Computed axis layout.\n */\nexport interface AxisLayout {\n /** Axis orientation */\n orientation: AxisOrientation;\n /** Axis position */\n position: AxisPosition;\n /** Nice scale information */\n scale: NiceTicksResult;\n /** Computed tick marks */\n ticks: AxisTick[];\n /** Maximum label width (for alignment) */\n maxLabelWidth: number;\n /** Axis title */\n title?: string | undefined;\n /** Total axis width (including labels and padding) */\n totalWidth: number;\n /** Total axis height (including labels and padding) */\n totalHeight: number;\n}\n\n/**\n * Compute the layout for an axis.\n *\n * @param options - Axis configuration\n * @returns Computed axis layout\n */\nexport function computeAxisLayout(options: AxisLayoutOptions): AxisLayout {\n const {\n dataMin,\n dataMax,\n size,\n orientation,\n position,\n tickCount = 5,\n showTicks = true,\n format = \"number\",\n decimals,\n label,\n forceMin,\n forceMax,\n includeZero = true,\n } = options;\n\n // Compute nice tick values\n const scale = computeNiceTicks({\n dataMin,\n dataMax,\n tickCount,\n includeZero,\n forceMin,\n forceMax,\n });\n\n // Generate tick objects with formatted labels\n const ticks: AxisTick[] = scale.ticks.map((value) => {\n const label = formatTickValue(value, format, decimals);\n // Map value to position along the axis\n const normalizedPosition = (value - scale.min) / (scale.max - scale.min);\n const position =\n orientation === \"vertical\"\n ? size * (1 - normalizedPosition) // Invert for vertical (0 at bottom)\n : size * normalizedPosition;\n\n return { value, label, position };\n });\n\n // Calculate maximum label width\n let maxLabelWidth = 0;\n for (const tick of ticks) {\n const width = getStringWidth(tick.label);\n if (width > maxLabelWidth) {\n maxLabelWidth = width;\n }\n }\n\n // Calculate total dimensions\n let totalWidth: number;\n let totalHeight: number;\n\n if (orientation === \"vertical\") {\n // Vertical axis: width is label width + tick mark + gap\n totalWidth = maxLabelWidth + (showTicks ? 2 : 1);\n totalHeight = size;\n } else {\n // Horizontal axis: height is 1 line + label if present\n totalWidth = size;\n totalHeight = 1 + (label ? 1 : 0);\n }\n\n return {\n orientation,\n position,\n scale,\n ticks,\n maxLabelWidth,\n title: label,\n totalWidth,\n totalHeight,\n };\n}\n\n/**\n * Compute layouts for both axes of a chart.\n */\nexport interface DualAxisLayoutOptions {\n /** X-axis data min */\n xMin: number;\n /** X-axis data max */\n xMax: number;\n /** Y-axis data min */\n yMin: number;\n /** Y-axis data max */\n yMax: number;\n /** Chart width (characters) */\n chartWidth: number;\n /** Chart height (characters) */\n chartHeight: number;\n /** X-axis configuration */\n xAxis?: Partial<AxisLayoutOptions>;\n /** Y-axis configuration */\n yAxis?: Partial<AxisLayoutOptions>;\n}\n\n/**\n * Result of dual axis computation.\n */\nexport interface DualAxisLayout {\n /** X-axis layout */\n xAxis: AxisLayout;\n /** Y-axis layout */\n yAxis: AxisLayout;\n /** Available chart area width after axis labels */\n chartAreaWidth: number;\n /** Available chart area height after axis labels */\n chartAreaHeight: number;\n /** X offset of chart area */\n chartAreaX: number;\n /** Y offset of chart area */\n chartAreaY: number;\n}\n\n/**\n * Compute layouts for both X and Y axes.\n *\n * @param options - Dual axis configuration\n * @returns Both axis layouts and chart area dimensions\n */\nexport function computeDualAxisLayout(\n options: DualAxisLayoutOptions\n): DualAxisLayout {\n const {\n xMin,\n xMax,\n yMin,\n yMax,\n chartWidth,\n chartHeight,\n xAxis: xAxisOpts = {},\n yAxis: yAxisOpts = {},\n } = options;\n\n // First pass: compute Y-axis to get label width\n const yAxisInitial = computeAxisLayout({\n dataMin: yMin,\n dataMax: yMax,\n size: chartHeight,\n orientation: \"vertical\",\n position: \"left\",\n ...yAxisOpts,\n });\n\n // Calculate available chart area\n const chartAreaX = yAxisInitial.totalWidth;\n const chartAreaY = 0;\n const chartAreaWidth = Math.max(1, chartWidth - yAxisInitial.totalWidth);\n const chartAreaHeight = Math.max(1, chartHeight - 2); // Reserve 2 lines for x-axis\n\n // Recompute Y-axis with final height\n const yAxis = computeAxisLayout({\n dataMin: yMin,\n dataMax: yMax,\n size: chartAreaHeight,\n orientation: \"vertical\",\n position: \"left\",\n ...yAxisOpts,\n });\n\n // Compute X-axis with final width\n const xAxis = computeAxisLayout({\n dataMin: xMin,\n dataMax: xMax,\n size: chartAreaWidth,\n orientation: \"horizontal\",\n position: \"bottom\",\n ...xAxisOpts,\n });\n\n return {\n xAxis,\n yAxis,\n chartAreaWidth,\n chartAreaHeight,\n chartAreaX,\n chartAreaY,\n };\n}\n","/**\n * Grid line computation for chart backgrounds.\n */\n\nimport type { AxisLayout } from \"./axis.js\";\n\n/**\n * Configuration for grid computation.\n */\nexport interface GridOptions {\n /** Chart area width */\n width: number;\n /** Chart area height */\n height: number;\n /** X-axis layout (for vertical grid lines) */\n xAxis?: AxisLayout;\n /** Y-axis layout (for horizontal grid lines) */\n yAxis?: AxisLayout;\n /** Show horizontal grid lines */\n showHorizontal?: boolean;\n /** Show vertical grid lines */\n showVertical?: boolean;\n /** Grid character */\n char?: string;\n}\n\n/**\n * A single grid line.\n */\nexport interface GridLine {\n /** Line orientation */\n orientation: \"horizontal\" | \"vertical\";\n /** Position along perpendicular axis */\n position: number;\n /** Start position */\n start: number;\n /** End position */\n end: number;\n}\n\n/**\n * Computed grid layout.\n */\nexport interface GridLayout {\n /** Horizontal grid lines */\n horizontalLines: GridLine[];\n /** Vertical grid lines */\n verticalLines: GridLine[];\n /** Grid character */\n char: string;\n}\n\n/**\n * Default grid character (center dot).\n */\nexport const DEFAULT_GRID_CHAR = \"·\";\n\n/**\n * Compute grid lines for a chart.\n *\n * @param options - Grid configuration\n * @returns Computed grid layout\n */\nexport function computeGridLayout(options: GridOptions): GridLayout {\n const {\n width,\n height,\n xAxis,\n yAxis,\n showHorizontal = true,\n showVertical = false,\n char = DEFAULT_GRID_CHAR,\n } = options;\n\n const horizontalLines: GridLine[] = [];\n const verticalLines: GridLine[] = [];\n\n // Generate horizontal lines from Y-axis ticks\n if (showHorizontal && yAxis) {\n for (const tick of yAxis.ticks) {\n // Skip first and last ticks (at boundaries)\n if (tick.position === 0 || tick.position === height) continue;\n\n horizontalLines.push({\n orientation: \"horizontal\",\n position: Math.round(tick.position),\n start: 0,\n end: width,\n });\n }\n }\n\n // Generate vertical lines from X-axis ticks\n if (showVertical && xAxis) {\n for (const tick of xAxis.ticks) {\n // Skip first and last ticks (at boundaries)\n if (tick.position === 0 || tick.position === width) continue;\n\n verticalLines.push({\n orientation: \"vertical\",\n position: Math.round(tick.position),\n start: 0,\n end: height,\n });\n }\n }\n\n return {\n horizontalLines,\n verticalLines,\n char,\n };\n}\n\n/**\n * Create a 2D character grid with grid lines.\n *\n * @param width - Grid width\n * @param height - Grid height\n * @param grid - Grid layout\n * @returns 2D array of characters\n */\nexport function createGridBuffer(\n width: number,\n height: number,\n grid: GridLayout\n): string[][] {\n // Initialize with spaces\n const buffer: string[][] = [];\n for (let y = 0; y < height; y++) {\n const row: string[] = [];\n for (let x = 0; x < width; x++) {\n row.push(\" \");\n }\n buffer.push(row);\n }\n\n // Draw horizontal grid lines\n for (const line of grid.horizontalLines) {\n const y = line.position;\n if (y >= 0 && y < height) {\n const row = buffer[y];\n if (row) {\n for (let x = line.start; x < line.end && x < width; x++) {\n row[x] = grid.char;\n }\n }\n }\n }\n\n // Draw vertical grid lines (overwrites horizontal at intersections)\n for (const line of grid.verticalLines) {\n const x = line.position;\n if (x >= 0 && x < width) {\n for (let y = line.start; y < line.end && y < height; y++) {\n const row = buffer[y];\n if (row) {\n row[x] = grid.char;\n }\n }\n }\n }\n\n return buffer;\n}\n"],"mappings":"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","names":["ticks","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","getStringWidth","padToWidth","getStringWidth","padToWidth","padToWidth","padToWidth","getStringWidth","label","position","getStringWidth"]}