--- name: ggterm-markdown description: Generate markdown reports with embedded ggterm visualizations. Use when creating analysis reports, documenting results, exporting findings, or when the user wants plots in markdown format for sharing or documentation. allowed-tools: Write, Read, Bash(bun:*), Bash(npx:*) --- # Markdown Reports with ggterm Generate analysis reports with embedded terminal visualizations and reproducible plot specifications. ## Report Structure A well-structured analysis report includes: 1. **Title and Overview** - What was analyzed and why 2. **Data Summary** - Shape, columns, key statistics 3. **Visualizations** - Embedded plots with interpretations 4. **Findings** - Key insights from the analysis 5. **Appendix** - Plot specifications for reproducibility ## Basic Report Template ```typescript import { gg, geom_point, geom_line } from '@ggterm/core' import { writeFileSync } from 'fs' // Create plots const scatterPlot = gg(data) .aes({ x: 'x', y: 'y', color: 'category' }) .geom(geom_point()) .labs({ title: 'Relationship Analysis' }) const trendPlot = gg(data) .aes({ x: 'time', y: 'value' }) .geom(geom_line()) .labs({ title: 'Trend Over Time' }) // Render plots to strings const scatter = scatterPlot.render({ width: 72, height: 18 }) const trend = trendPlot.render({ width: 72, height: 18 }) // Build markdown report const report = `# Analysis Report: ${datasetName} ## Overview This report analyzes ${data.length} observations across ${Object.keys(data[0]).length} variables. ## Data Summary | Metric | Value | |--------|-------| | Rows | ${data.length} | | Columns | ${Object.keys(data[0]).length} | | Date Range | ${minDate} to ${maxDate} | ## Visualizations ### Scatter Plot \`\`\` ${scatter} \`\`\` **Interpretation**: The scatter plot shows [describe the relationship observed]. ### Trend Analysis \`\`\` ${trend} \`\`\` **Interpretation**: The trend indicates [describe the pattern observed]. ## Key Findings 1. **Finding 1**: Description of first key insight 2. **Finding 2**: Description of second key insight 3. **Finding 3**: Description of third key insight ## Appendix: Plot Specifications
Scatter Plot Spec (JSON) \`\`\`json ${JSON.stringify(scatterPlot.spec(), null, 2)} \`\`\`
Trend Plot Spec (JSON) \`\`\`json ${JSON.stringify(trendPlot.spec(), null, 2)} \`\`\`
--- *Generated with ggterm* ` writeFileSync('analysis-report.md', report) console.log('Report saved to analysis-report.md') ``` ## Embedding Multiple Plots For reports with many visualizations: ```typescript interface PlotSection { title: string plot: GGPlot interpretation: string } function generateReport( title: string, overview: string, sections: PlotSection[], findings: string[] ): string { const plotSections = sections.map(({ title, plot, interpretation }) => ` ### ${title} \`\`\` ${plot.render({ width: 72, height: 16 })} \`\`\` **Interpretation**: ${interpretation} `).join('\n') const findingsList = findings .map((f, i) => `${i + 1}. ${f}`) .join('\n') const specs = sections.map(({ title, plot }) => `
${title} Spec \`\`\`json ${JSON.stringify(plot.spec(), null, 2)} \`\`\`
`).join('\n') return `# ${title} ## Overview ${overview} ## Visualizations ${plotSections} ## Key Findings ${findingsList} ## Appendix: Reproducibility ${specs} --- *Generated with ggterm* ` } ``` ## Width Guidelines Choose plot width based on target context: | Context | Width | Height | Notes | |---------|-------|--------|-------| | GitHub README | 72-80 | 16-20 | Standard terminal width | | GitHub Issues | 72 | 14-18 | Compact for discussions | | Documentation | 80-100 | 20-24 | More detail | | Presentations | 60-70 | 12-16 | Readable at distance | ## Including Data Tables ```typescript function markdownTable(data: Record[], columns?: string[]): string { const cols = columns || Object.keys(data[0]) const header = `| ${cols.join(' | ')} |` const separator = `| ${cols.map(() => '---').join(' | ')} |` const rows = data.map(row => `| ${cols.map(c => String(row[c] ?? '')).join(' | ')} |` ).join('\n') return `${header}\n${separator}\n${rows}` } // Usage const summaryTable = markdownTable([ { metric: 'Mean', value: mean.toFixed(2) }, { metric: 'Median', value: median.toFixed(2) }, { metric: 'Std Dev', value: std.toFixed(2) }, ]) ``` ## Full Example: EDA Report ```typescript import { gg, geom_histogram, geom_boxplot, geom_point, facet_wrap } from '@ggterm/core' import { writeFileSync } from 'fs' // Assume data is loaded const numericCols = ['age', 'income', 'score'] const categoricalCols = ['region', 'segment'] // Generate distribution plots const distributions = numericCols.map(col => ({ title: `Distribution of ${col}`, plot: gg(data).aes({ x: col }).geom(geom_histogram({ bins: 20 })), interpretation: `Shows the distribution of ${col} values.` })) // Generate comparison plots const comparisons = categoricalCols.map(cat => ({ title: `Score by ${cat}`, plot: gg(data).aes({ x: cat, y: 'score' }).geom(geom_boxplot()), interpretation: `Compares score across ${cat} groups.` })) // Correlation scatter const correlation = { title: 'Age vs Income', plot: gg(data) .aes({ x: 'age', y: 'income', color: 'region' }) .geom(geom_point({ alpha: 0.6 })), interpretation: 'Shows relationship between age and income by region.' } const report = generateReport( 'Exploratory Data Analysis', `Analysis of ${data.length} customer records.`, [...distributions, ...comparisons, correlation], [ 'Income is right-skewed with median $X', 'Region A shows significantly higher scores', 'Age and income show moderate positive correlation' ] ) writeFileSync('eda-report.md', report) ``` ## Tips 1. **Keep plots compact** - Use 16-20 lines height for readability 2. **Include interpretations** - Don't just show plots, explain them 3. **Save specs** - Always include PlotSpec JSON for reproducibility 4. **Use collapsible sections** - `
` tags keep reports clean 5. **Match audience** - Adjust technical depth to readers For report templates, see [templates/](templates/).