Token导航 LogoToken导航

Agent Skill · 前端设计

interactive-report-generator(交互式报告生成器)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

interactive-report-generator 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 5,915。

总安装 582周安装 24GitHub Stars 8下载 190核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:interactive-report-generator(交互式报告生成器)
来源仓库:https://github.com/vamseeachanta/workspace-hub
仓库路径:skills/interactive-report-generator
安装命令:
npx skills add https://github.com/vamseeachanta/workspace-hub --skill interactive-report-generator
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/vamseeachanta/workspace-hub --skill interactive-report-generator

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。适合生成或审查 React、Next.js、Vue、Tailwind、CSS 等代码,整理组件结构或定位布局问题。需结合项目现有设计系统、路由和构建方式,避免生成孤立片段;涉及页面改动时应配合本地预览检查视觉效果。

安装命令:npx skills add https://github.com/vamseeachanta/workspace-hub --skill interactive-report-generator。建议确认权限范围和维护状态,避免触发不必要的联网或文件读写操作。

来源仓库内路径:skills/interactive-report-generator

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/vamseeachanta/workspace-hub --skill interactiv…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

interactive-report-generator 怎么安装?

在终端执行 npx skills add https://github.com/vamseeachanta/workspace-hub --skill interactive-report-g…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

interactive-report-generator 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

interactive-report-generator 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

interactive-report-generator 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

interactive-report-generator 用的人多吗?

公开数据是累计安装 582 次,近一周安装 24 次,下载 190 次,GitHub 8 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

interactive-report-generator 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
interactive-report-generator

交互式报告生成器 · 本页

5828需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Interactive Report Generator

Create professional, interactive HTML reports with Plotly visualizations.

Quick Start

# Generate report from data
/interactive-report-generator --data results.csv --output report.html

# Create dashboard
/interactive-report-generator --type dashboard --config dashboard.yaml

# Generate from analysis results
/interactive-report-generator --source analysis_output/

When to Use

USE when:

  • Creating analysis reports
  • Generating data visualizations
  • Building dashboards
  • Presenting results to stakeholders

DON'T USE when:

  • Static images are required
  • PDF export is primary format
  • Real-time streaming data

Prerequisites

  • Python 3.9+
  • plotly>=5.15.0
  • pandas>=2.0.0
  • Data in CSV/DataFrame format

Overview

Generates interactive HTML reports compliant with workspace-hub HTML_REPORTING_STANDARDS.md:

  1. Interactive plots only - No static matplotlib
  2. CSV data import - Relative paths
  3. Responsive design - Works on all devices
  4. Professional styling - Consistent theming
  5. Export options - PNG, SVG from plots

Core Templates

1. Basic Report Template

"""
ABOUTME: Interactive HTML report generator
ABOUTME: Creates Plotly-based reports from analysis data
"""

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional

def generate_report(
    data: pd.DataFrame,
    output_path: Path,
    title: str = "Analysis Report",
    config: Optional[Dict[str, Any]] = None
) -> Path:
    """
    Generate interactive HTML report from data.

    Args:
        data: DataFrame with analysis results
        output_path: Path to save HTML report
        title: Report title
        config: Optional configuration dictionary

    Returns:
        Path to generated report
    """
    config = config or {}

    # Create HTML structure
    html_content = f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <style>
        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            background-color: #f5f5f5;
            color: #333;
            line-height: 1.6;
        }}
        .report-header {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 40px;
            text-align: center;
        }}
        .report-header h1 {{
            font-size: 2.5em;
            margin-bottom: 10px;
        }}
        .report-header .metadata {{
            opacity: 0.9;
            font-size: 0.9em;
        }}
        .container {{
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
        }}
        .summary-cards {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin: 30px 0;
        }}
        .card {{
            background: white;
            border-radius: 12px;
            padding: 25px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            text-align: center;
        }}
        .card .label {{
            font-size: 0.85em;
            color: #666;
            text-transform: uppercase;
            letter-spacing: 1px;
        }}
        .card .value {{
            font-size: 2.5em;
            font-weight: bold;
            color: #667eea;
            margin: 10px 0;
        }}
        .plot-container {{
            background: white;
            border-radius: 12px;
            padding: 25px;
            margin: 20px 0;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }}
        .plot-container h2 {{
            margin-bottom: 20px;
            color: #333;
            border-bottom: 2px solid #667eea;
            padding-bottom: 10px;
        }}
        .footer {{
            text-align: center;
            padding: 30px;
            color: #666;
            font-size: 0.85em;
        }}
        @media (max-width: 768px) {{
            .report-header h1 {{
                font-size: 1.8em;
            }}
            .card .value {{
                font-size: 2em;
            }}
        }}
    </style>
</head>
<body>
    <div class="report-header">
        <h1>{title}</h1>
        <div class="metadata">
            Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} |
            Records: {len(data):,}
        </div>
    </div>

    <div class="container">
        <!-- Summary Cards -->
        <div class="summary-cards" id="summary-cards">
            <!-- Generated by JavaScript -->
        </div>

        <!-- Plots -->
        <div id="plots-container">
            <!-- Generated dynamically -->
        </div>
    </div>

    <div class="footer">
        Generated with Interactive Report Generator | workspace-hub
    </div>
</body>
</html>
"""

    # Write HTML
    output_path.parent.mkdir(parents=True, exist_ok=True)
    output_path.write_text(html_content)

    return output_path

def create_time_series_plot(
    data: pd.DataFrame,
    x_col: str,
    y_cols: List[str],
    title: str = "Time Series"
) -> go.Figure:
    """
    Create interactive time series plot.

    Args:
        data: DataFrame with time series data
        x_col: Column for x-axis (typically datetime)
        y_cols: Columns for y-axis values
        title: Plot title

    Returns:
        Plotly Figure object
    """
    fig = go.Figure()

    for col in y_cols:
        fig.add_trace(go.Scatter(
            x=data[x_col],
            y=data[col],
            mode='lines+markers',
            name=col,
            hovertemplate='%{x}<br>%{y:.2f}<extra></extra>'
        ))

    fig.update_layout(
        title=title,
        xaxis_title=x_col,
        yaxis_title="Value",
        hovermode='x unified',
        template='plotly_white',
        height=500
    )

    return fig

def create_distribution_plot(
    data: pd.DataFrame,
    column: str,
    title: str = "Distribution"
) -> go.Figure:
    """
    Create interactive histogram/distribution plot.

    Args:
        data: DataFrame with data
        column: Column to plot distribution
        title: Plot title

    Returns:
        Plotly Figure object
    """
    fig = px.histogram(
        data,
        x=column,
        title=title,
        template='plotly_white',
        nbins=50
    )

    fig.update_layout(
        xaxis_title=column,
        yaxis_title="Count",
        height=400
    )

    return fig

def create_correlation_heatmap(
    data: pd.DataFrame,
    columns: Optional[List[str]] = None,
    title: str = "Correlation Matrix"
) -> go.Figure:
    """
    Create interactive correlation heatmap.

    Args:
        data: DataFrame with numeric data
        columns: Optional list of columns to include
        title: Plot title

    Returns:
        Plotly Figure object
    """
    if columns:
        corr_data = data[columns].corr()
    else:
        corr_data = data.select_dtypes(include='number').corr()

    fig = px.imshow(
        corr_data,
        title=title,
        template='plotly_white',
        color_continuous_scale='RdBu_r',
        zmin=-1,
        zmax=1
    )

    fig.update_layout(height=500)

    return fig

def create_dashboard(
    data: pd.DataFrame,
    output_path: Path,
    config: Dict[str, Any]
) -> Path:
    """
    Create multi-panel dashboard.

    Args:
        data: DataFrame with analysis data
        output_path: Path to save dashboard HTML
        config: Dashboard configuration

    Returns:
        Path to generated dashboard
    """
    # Create subplots
    fig = make_subplots(
        rows=2, cols=2,
        subplot_titles=(
            "Time Series",
            "Distribution",
            "Scatter Plot",
            "Summary Statistics"
        ),
        specs=[
            [{"type": "scatter"}, {"type": "histogram"}],
            [{"type": "scatter"}, {"type": "table"}]
        ]
    )

    # Add plots based on config
    numeric_cols = data.select_dtypes(include='number').columns.tolist()

    if len(numeric_cols) >= 2:
        # Time series or line plot
        fig.add_trace(
            go.Scatter(
                x=data.index,
                y=data[numeric_cols[0]],
                mode='lines',
                name=numeric_cols[0]
            ),
            row=1, col=1
        )

        # Distribution
        fig.add_trace(
            go.Histogram(x=data[numeric_cols[0]], name="Distribution"),
            row=1, col=2
        )

        # Scatter
        fig.add_trace(
            go.Scatter(
                x=data[numeric_cols[0]],
                y=data[numeric_cols[1]],
                mode='markers',
                name="Correlation"
            ),
            row=2, col=1
        )

    # Summary statistics table
    stats = data.describe().reset_index()
    fig.add_trace(
        go.Table(
            header=dict(values=list(stats.columns)),
            cells=dict(values=[stats[col].round(2) for col in stats.columns])
        ),
        row=2, col=2
    )

    fig.update_layout(
        height=800,
        showlegend=True,
        title_text="Analysis Dashboard"
    )

    # Save
    fig.write_html(output_path, include_plotlyjs='cdn')

    return output_path

2. Report Generator Class

"""
ABOUTME: Full-featured report generator class
ABOUTME: Supports multiple plot types and configurations
"""

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from pathlib import Path
from typing import Dict, List, Any, Optional
from datetime import datetime
import json

class InteractiveReportGenerator:
    """Generate interactive HTML reports with Plotly."""

    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """
        Initialize report generator.

        Args:
            config: Optional configuration dictionary
        """
        self.config = config or {}
        self.plots: List[go.Figure] = []
        self.summary_stats: Dict[str, Any] = {}

        # Default styling
        self.theme = self.config.get('theme', {
            'primary_color': '#667eea',
            'secondary_color': '#764ba2',
            'background': '#f5f5f5',
            'card_bg': '#ffffff',
            'text_color': '#333333'
        })

    def add_data(self, data: pd.DataFrame, name: str = "data"):
        """Add data source to report."""
        self.data = data
        self.data_name = name
        self._calculate_summary()

    def _calculate_summary(self):
        """Calculate summary statistics."""
        if hasattr(self, 'data'):
            self.summary_stats = {
                'total_records': len(self.data),
                'columns': len(self.data.columns),
                'numeric_cols': len(self.data.select_dtypes(include='number').columns),
                'missing_values': self.data.isnull().sum().sum()
            }

    def add_time_series(
        self,
        x_col: str,
        y_cols: List[str],
        title: str = "Time Series Analysis"
    ):
        """Add time series plot."""
        fig = go.Figure()

        for col in y_cols:
            fig.add_trace(go.Scatter(
                x=self.data[x_col],
                y=self.data[col],
                mode='lines+markers',
                name=col
            ))

        fig.update_layout(
            title=title,
            template='plotly_white',
            height=500
        )

        self.plots.append(('time_series', fig, title))

    def add_bar_chart(
        self,
        x_col: str,
        y_col: str,
        title: str = "Bar Chart"
    ):
        """Add bar chart."""
        fig = px.bar(
            self.data,
            x=x_col,
            y=y_col,
            title=title,
            template='plotly_white'
        )

        self.plots.append(('bar', fig, title))

    def add_scatter_plot(
        self,
        x_col: str,
        y_col: str,
        color_col: Optional[str] = None,
        title: str = "Scatter Plot"
    ):
        """Add scatter plot."""
        fig = px.scatter(
            self.data,
            x=x_col,
            y=y_col,
            color=color_col,
            title=title,
            template='plotly_white'
        )

        self.plots.append(('scatter', fig, title))

    def add_histogram(
        self,
        column: str,
        title: str = "Distribution"
    ):
        """Add histogram."""
        fig = px.histogram(
            self.data,
            x=column,
            title=title,
            template='plotly_white'
        )

        self.plots.append(('histogram', fig, title))

    def add_heatmap(
        self,
        columns: Optional[List[str]] = None,
        title: str = "Correlation Heatmap"
    ):
        """Add correlation heatmap."""
        if columns:
            corr = self.data[columns].corr()
        else:
            corr = self.data.select_dtypes(include='number').corr()

        fig = px.imshow(
            corr,
            title=title,
            template='plotly_white',
            color_continuous_scale='RdBu_r'
        )

        self.plots.append(('heatmap', fig, title))

    def generate(
        self,
        output_path: Path,
        title: str = "Analysis Report"
    ) -> Path:
        """
        Generate the HTML report.

        Args:
            output_path: Path to save report
            title: Report title

        Returns:
            Path to generated report
        """
        # Build HTML
        html_parts = [self._generate_header(title)]
        html_parts.append(self._generate_summary_cards())

        for plot_type, fig, plot_title in self.plots:
            html_parts.append(self._wrap_plot(fig, plot_title))

        html_parts.append(self._generate_footer())

        # Combine and save
        html_content = self._get_html_template(
            title,
            '\n'.join(html_parts)
        )

        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(html_content)

        return output_path

    def _get_html_template(self, title: str, body: str) -> str:
        """Get complete HTML template."""
        return f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <style>
        {self._get_styles()}
    </style>
</head>
<body>
    {body}
</body>
</html>"""

    def _get_styles(self) -> str:
        """Get CSS styles."""
        return """
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #f5f5f5;
            color: #333;
        }
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 40px;
            text-align: center;
        }
        .container { max-width: 1400px; margin: 0 auto; padding: 20px; }
        .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 30px 0; }
        .card { background: white; border-radius: 12px; padding: 25px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); text-align: center; }
        .card-value { font-size: 2.5em; font-weight: bold; color: #667eea; }
        .card-label { color: #666; text-transform: uppercase; font-size: 0.85em; }
        .plot-section { background: white; border-radius: 12px; padding: 25px; margin: 20px 0; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
        .footer { text-align: center; padding: 30px; color: #666; }
        """

    def _generate_header(self, title: str) -> str:
        """Generate header HTML."""
        return f"""
        <div class="header">
            <h1>{title}</h1>
            <p>Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        </div>
        <div class="container">
        """

    def _generate_summary_cards(self) -> str:
        """Generate summary cards HTML."""
        cards = ""
        for key, value in self.summary_stats.items():
            label = key.replace('_', ' ').title()
            cards += f"""
            <div class="card">
                <div class="card-value">{value:,}</div>
                <div class="card-label">{label}</div>
            </div>
            """

        return f'<div class="cards">{cards}</div>'

    def _wrap_plot(self, fig: go.Figure, title: str) -> str:
        """Wrap plot in HTML container."""
        plot_html = fig.to_html(full_html=False, include_plotlyjs=False)
        return f"""
        <div class="plot-section">
            <h2>{title}</h2>
            {plot_html}
        </div>
        """

    def _generate_footer(self) -> str:
        """Generate footer HTML."""
        return """
        </div>
        <div class="footer">
            Generated with Interactive Report Generator | workspace-hub
        </div>
        """

Usage Examples

Example 1: Simple Report

import pandas as pd
from pathlib import Path
from report_generator import InteractiveReportGenerator

# Load data
df = pd.read_csv('data/analysis_results.csv')

# Create report
report = InteractiveReportGenerator()
report.add_data(df)
report.add_time_series('date', ['value1', 'value2'])
report.add_histogram('value1')
report.add_heatmap()

# Generate
output = report.generate(
    Path('reports/analysis_report.html'),
    title='Analysis Results'
)
print(f"Report saved: {output}")

Example 2: Dashboard Creation

# Create dashboard with multiple views
report = InteractiveReportGenerator()
report.add_data(df)

# Add various plots
report.add_time_series('timestamp', ['metric_a', 'metric_b'])
report.add_scatter_plot('x_value', 'y_value', color_col='category')
report.add_bar_chart('category', 'total')
report.add_histogram('distribution_col')

# Generate dashboard
report.generate(
    Path('reports/dashboard.html'),
    title='Project Dashboard'
)

Example 3: From CLI

# Generate report from command line
python -m report_generator \
    --data results.csv \
    --output report.html \
    --title "Analysis Results" \
    --plots time_series histogram heatmap

Execution Checklist

Data Preparation:

  • Data loaded as DataFrame
  • Column names are clean
  • Date columns parsed
  • Missing values handled

Report Creation:

  • Add data to generator
  • Select appropriate plot types
  • Configure titles and labels
  • Generate HTML output

Validation:

  • Open report in browser
  • Verify interactivity works
  • Check responsive design
  • Test export options

Best Practices

  1. Use descriptive titles - Help users understand each visualization
  2. Limit plots per page - 5-7 plots maximum for clarity
  3. Use consistent colors - Match organizational branding
  4. Include summary stats - Provide context for data
  5. Test on mobile - Verify responsive design works

Error Handling

Missing Columns

Error: Column 'value' not found in data

Check:
1. Column names in DataFrame
2. Spelling and case sensitivity
3. Data was loaded correctly

Empty Data

Error: No data to plot

Check:
1. DataFrame is not empty
2. Filters not too restrictive
3. Data loading succeeded

Related Skills

References


Version History

  • 1.0.0 (2026-01-14): Initial release - Plotly-based interactive HTML report generator with dashboards, multiple plot types, and responsive design

平台分布

Claude Code

31.19%
按下载量换算59

trae

24.65%
按下载量换算47

OpenCode

17.09%
按下载量换算32

Gemini CLI

13.89%
按下载量换算26

windsurf

8.63%
按下载量换算16

cline

3.52%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills