Skip to content

Visualization & HTML Reports

This document describes the system for visualizing profile results and generating HTML reports.

Overview

The visualization system implemented in src/truthound/profiler/visualization.py provides pure SVG-based chart rendering and HTML report generation.

ChartType

class ChartType(Enum):
    """Chart types"""

    BAR = "bar"                     # Bar chart
    HORIZONTAL_BAR = "horizontal_bar"  # Horizontal bar chart
    PIE = "pie"                     # Pie chart
    DONUT = "donut"                 # Donut chart
    LINE = "line"                   # Line chart
    AREA = "area"                   # Area chart
    SCATTER = "scatter"             # Scatter plot
    HISTOGRAM = "histogram"         # Histogram
    HEATMAP = "heatmap"             # Heatmap
    TABLE = "table"                 # Table
    GAUGE = "gauge"                 # Gauge chart
    SPARKLINE = "sparkline"         # Sparkline
    TREEMAP = "treemap"             # Treemap
    SANKEY = "sankey"               # Sankey diagram

ReportTheme

class ReportTheme(Enum):
    """Report themes"""

    LIGHT = "light"               # Light theme
    DARK = "dark"                 # Dark theme
    PROFESSIONAL = "professional" # Professional theme
    MINIMAL = "minimal"           # Minimal theme
    COLORFUL = "colorful"         # Colorful theme

SectionType

class SectionType(Enum):
    """Report section types"""

    OVERVIEW = "overview"               # Overview section
    COLUMN_DETAILS = "column_details"   # Column details
    DATA_QUALITY = "data_quality"       # Data quality
    STATISTICS = "statistics"           # Statistics information
    PATTERNS = "patterns"               # Pattern information
    ALERTS = "alerts"                   # Alerts
    RECOMMENDATIONS = "recommendations" # Recommendations
    CUSTOM = "custom"                   # Custom section

SVGChartRenderer

Renders charts as pure SVG without external dependencies. Uses ChartData and ChartConfig for a unified interface.

from truthound.profiler.visualization import (
    SVGChartRenderer, ChartData, ChartConfig, ChartType
)

renderer = SVGChartRenderer()

# Bar chart
bar_data = ChartData(
    labels=["A", "B", "C", "D", "E"],
    values=[10, 25, 15, 30, 20],
    title="Distribution",
)
bar_config = ChartConfig(chart_type=ChartType.BAR, width=400, height=300)
bar_svg = renderer.render(bar_data, bar_config)

# Pie chart
pie_data = ChartData(
    labels=["Cat A", "Cat B", "Cat C", "Cat D", "Cat E"],
    values=[30, 25, 20, 15, 10],
)
pie_config = ChartConfig(chart_type=ChartType.PIE, width=300, height=300)
pie_svg = renderer.render(pie_data, pie_config)

# Histogram
hist_data = ChartData(
    labels=["0-10", "10-20", "20-30", "30-40"],
    values=[5, 12, 8, 3],
    title="Value Distribution",
)
hist_config = ChartConfig(chart_type=ChartType.HISTOGRAM, width=400, height=300)
hist_svg = renderer.render(hist_data, hist_config)

# Gauge chart
gauge_data = ChartData(
    values=[85],  # Current value
    title="Completeness",
    metadata={"min": 0, "max": 100},
)
gauge_config = ChartConfig(chart_type=ChartType.GAUGE, width=250, height=180)
gauge_svg = renderer.render(gauge_data, gauge_config)

HTMLReportGenerator

Generates complete HTML reports. Accepts ProfileData objects or dicts as input.

from truthound.profiler.visualization import (
    HTMLReportGenerator, ReportConfig, ReportTheme, ProfileData
)

# Configuration
config = ReportConfig(
    title="Data Profile Report",
    subtitle="Generated by Truthound",
    theme=ReportTheme.PROFESSIONAL,
    include_toc=True,
    include_timestamp=True,
    include_summary=True,
    sections=[
        SectionType.OVERVIEW,
        SectionType.DATA_QUALITY,
        SectionType.COLUMN_DETAILS,
        SectionType.PATTERNS,
        SectionType.RECOMMENDATIONS,
    ],
)

# Generate report
generator = HTMLReportGenerator()
html = generator.generate(profile_data, config)

# Save to file
generator.save(profile_data, "report.html", config)

# Generate from dict
html = generator.generate_from_dict(profile_dict, config)

ReportConfig

@dataclass
class ReportConfig:
    """Report configuration"""

    title: str = "Data Profile Report"
    subtitle: str = ""
    theme: ReportTheme = ReportTheme.LIGHT
    logo_path: str | None = None        # Logo file path
    logo_base64: str | None = None      # Base64 encoded logo
    include_toc: bool = True            # Include table of contents
    include_timestamp: bool = True      # Include timestamp
    include_summary: bool = True        # Include summary
    sections: list[SectionType] = field(default_factory=lambda: [
        SectionType.OVERVIEW,
        SectionType.DATA_QUALITY,
        SectionType.COLUMN_DETAILS,
        SectionType.PATTERNS,
        SectionType.RECOMMENDATIONS,
    ])
    custom_css: str | None = None       # Custom CSS
    custom_js: str | None = None        # Custom JavaScript
    embed_resources: bool = True        # Embed resources
    language: str = "en"                # Language code

Section Renderers

Each section is generated by a separate renderer (implementing the SectionRenderer protocol). Renderers receive SectionContent, ChartRenderer, and ThemeConfig as input.

OverviewSectionRenderer

from truthound.profiler.visualization import (
    OverviewSectionRenderer, SectionContent, SectionType
)

renderer = OverviewSectionRenderer()
content = SectionContent(
    section_type=SectionType.OVERVIEW,
    title="Overview",
    text_blocks=["Table: users", "Rows: 10,000 | Columns: 5"],
    charts=[...],
    tables=[...],
)
html = renderer.render(content, chart_renderer, theme)

DataQualitySectionRenderer

from truthound.profiler.visualization import DataQualitySectionRenderer

renderer = DataQualitySectionRenderer()
# Included content:
# - Quality gauge chart
# - Alert/warning display
# - Per-column quality table

ColumnDetailsSectionRenderer

from truthound.profiler.visualization import ColumnDetailsSectionRenderer

renderer = ColumnDetailsSectionRenderer()
# For each column:
# - Value distribution chart (BAR or HISTOGRAM)
# - Column statistics table
# - Collapsible support (collapsible=True)

PatternsSectionRenderer

from truthound.profiler.visualization import PatternsSectionRenderer

renderer = PatternsSectionRenderer()
# Included content:
# - Pattern type pie chart
# - Pattern detail table

RecommendationsSectionRenderer

from truthound.profiler.visualization import RecommendationsSectionRenderer

renderer = RecommendationsSectionRenderer()
# Included content:
# - Recommendations list (text_blocks)
# - Additional information table

ReportExporter

Supports export to various formats. HTML and JSON formats are supported by default.

from truthound.profiler.visualization import ReportExporter, ProfileData

exporter = ReportExporter()

# HTML export
html_str = exporter.to_html(profile_data, config)

# JSON export
json_str = exporter.to_json(profile_data)

# Export to file
exporter.to_file(profile_data, "report.html", format="html")
exporter.to_file(profile_data, "profile.json", format="json")

Theme Customization

Custom themes can be created with ThemeConfig or registered in ThemeRegistry.

from truthound.profiler.visualization import ThemeConfig, theme_registry, HTMLReportGenerator

custom_theme = ThemeConfig(
    name="my_theme",
    primary_color="#3498db",
    secondary_color="#2ecc71",
    accent_color="#e74c3c",
    background_color="#ffffff",
    text_color="#333333",
    border_color="#e0e0e0",
    font_family="'Noto Sans KR', sans-serif",
    header_bg="#f8f9fa",
    card_bg="#ffffff",
    shadow="0 2px 4px rgba(0,0,0,0.1)",
    border_radius="8px",
)

# Register in registry
theme_registry.register("my_theme", custom_theme)

# Pass theme directly
generator = HTMLReportGenerator(theme=custom_theme)

Chart Rendering Methods

Output Format Chart Engine Characteristics
HTML ApexCharts Interactive, requires JS
PDF SVG (pure) No JS dependency, static
Markdown Text ASCII art charts
# Interactive charts for HTML
html_generator = HTMLReportGenerator(config)
html = html_generator.generate(profile)  # Uses ApexCharts

# Static SVG charts for PDF
pdf_exporter = ReportExporter()
pdf_exporter.export(profile, "report.pdf")  # Uses pure SVG

Quick Report Generation

from truthound.profiler.visualization import generate_report

# Convenience function
html = generate_report(profile)
with open("report.html", "w") as f:
    f.write(html)

# Specify theme
html = generate_report(profile, theme=ReportTheme.DARK)

Comparison Reports

Generate reports comparing multiple profiles.

from truthound.profiler.visualization import compare_profiles

# Compare multiple profiles
html = compare_profiles(
    profiles=[profile1, profile2, profile3],
    labels=["Before", "After", "Latest"],
    config=ReportConfig(title="Profile Comparison Report"),
)

# Included content:
# - Profile overview comparison table (table name, row count, column count)
# - Quality score comparison bar chart

CLI Usage

# Generate HTML report
th profile data.csv --output report.html --format html

# Specify theme
th profile data.csv --output report.html --theme dark

# Generate PDF report
th profile data.csv --output report.pdf --format pdf

# Comparison report
th compare-profiles profile1.json profile2.json --output comparison.html

Next Steps