Files
our-claude-skills/ga-agent-skills/docs/03-visualization-setup.md
Andrew Yim 236be6c580 directory changes and restructuring
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 02:01:41 +09:00

7.5 KiB

Visualization Tools Setup

Overview

For lightweight dashboards displaying GA4/BigQuery insights, we recommend:

Tool Best For Complexity
Streamlit Quick Python dashboards Low
Plotly Dash Interactive charts Medium
HTML + Chart.js Portable, no server Low

Install Dependencies

cd /path/to/ga-agent-project/visualization

# Create virtual environment
python -m venv venv
source venv/bin/activate

# Install packages
pip install streamlit pandas plotly google-cloud-bigquery google-analytics-data

Basic Dashboard Template

Create visualization/streamlit_dashboard.py:

import streamlit as st
import pandas as pd
import plotly.express as px
from google.cloud import bigquery
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import RunReportRequest

# Page config
st.set_page_config(
    page_title="GA4 Analytics Dashboard",
    page_icon="📊",
    layout="wide"
)

st.title("📊 GA4 Analytics Dashboard")

# Sidebar for configuration
with st.sidebar:
    st.header("Settings")
    property_id = st.text_input("GA4 Property ID", "YOUR_PROPERTY_ID")
    date_range = st.selectbox(
        "Date Range",
        ["Last 7 days", "Last 30 days", "Last 90 days"]
    )

# Date mapping
date_map = {
    "Last 7 days": "7daysAgo",
    "Last 30 days": "30daysAgo",
    "Last 90 days": "90daysAgo"
}

@st.cache_data(ttl=3600)
def fetch_ga4_data(property_id: str, start_date: str):
    """Fetch data from GA4 API"""
    client = BetaAnalyticsDataClient()

    request = RunReportRequest(
        property=f"properties/{property_id}",
        dimensions=[{"name": "date"}],
        metrics=[
            {"name": "activeUsers"},
            {"name": "sessions"},
            {"name": "screenPageViews"}
        ],
        date_ranges=[{"start_date": start_date, "end_date": "today"}]
    )

    response = client.run_report(request)

    data = []
    for row in response.rows:
        data.append({
            "date": row.dimension_values[0].value,
            "users": int(row.metric_values[0].value),
            "sessions": int(row.metric_values[1].value),
            "pageviews": int(row.metric_values[2].value)
        })

    return pd.DataFrame(data)

# Fetch and display data
try:
    df = fetch_ga4_data(property_id, date_map[date_range])

    # Metrics row
    col1, col2, col3 = st.columns(3)
    with col1:
        st.metric("Total Users", f"{df['users'].sum():,}")
    with col2:
        st.metric("Total Sessions", f"{df['sessions'].sum():,}")
    with col3:
        st.metric("Total Pageviews", f"{df['pageviews'].sum():,}")

    # Charts
    st.subheader("Traffic Over Time")
    fig = px.line(df, x="date", y=["users", "sessions"],
                  title="Users & Sessions")
    st.plotly_chart(fig, use_container_width=True)

    # Raw data
    with st.expander("View Raw Data"):
        st.dataframe(df)

except Exception as e:
    st.error(f"Error fetching data: {e}")
    st.info("Ensure GOOGLE_APPLICATION_CREDENTIALS is set")

Run Dashboard

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
streamlit run visualization/streamlit_dashboard.py

Option 2: Static HTML Dashboard

For portable reports without a server:

Create visualization/templates/report.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>GA4 Report</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body { font-family: -apple-system, sans-serif; margin: 40px; }
        .metrics { display: flex; gap: 20px; margin-bottom: 40px; }
        .metric-card {
            background: #f5f5f5;
            padding: 20px;
            border-radius: 8px;
            flex: 1;
        }
        .metric-value { font-size: 32px; font-weight: bold; }
        .metric-label { color: #666; }
        .chart-container { max-width: 800px; margin: 40px 0; }
    </style>
</head>
<body>
    <h1>📊 GA4 Analytics Report</h1>
    <p>Generated: <span id="date"></span></p>

    <div class="metrics">
        <div class="metric-card">
            <div class="metric-value" id="users">--</div>
            <div class="metric-label">Active Users</div>
        </div>
        <div class="metric-card">
            <div class="metric-value" id="sessions">--</div>
            <div class="metric-label">Sessions</div>
        </div>
        <div class="metric-card">
            <div class="metric-value" id="pageviews">--</div>
            <div class="metric-label">Page Views</div>
        </div>
    </div>

    <div class="chart-container">
        <canvas id="trafficChart"></canvas>
    </div>

    <script>
        // Data will be injected by Python script
        const reportData = {{ DATA_JSON }};

        document.getElementById('date').textContent = new Date().toLocaleDateString();
        document.getElementById('users').textContent = reportData.totals.users.toLocaleString();
        document.getElementById('sessions').textContent = reportData.totals.sessions.toLocaleString();
        document.getElementById('pageviews').textContent = reportData.totals.pageviews.toLocaleString();

        new Chart(document.getElementById('trafficChart'), {
            type: 'line',
            data: {
                labels: reportData.dates,
                datasets: [{
                    label: 'Users',
                    data: reportData.users,
                    borderColor: '#4285f4',
                    tension: 0.1
                }, {
                    label: 'Sessions',
                    data: reportData.sessions,
                    borderColor: '#34a853',
                    tension: 0.1
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: { display: true, text: 'Traffic Over Time' }
                }
            }
        });
    </script>
</body>
</html>

Option 3: Python Chart Generation

For generating standalone chart images:

# visualization/scripts/generate_charts.py
import pandas as pd
import plotly.express as px
import plotly.io as pio

def generate_traffic_chart(df: pd.DataFrame, output_path: str):
    """Generate traffic chart as HTML or PNG"""
    fig = px.line(
        df,
        x="date",
        y=["users", "sessions"],
        title="Traffic Overview",
        template="plotly_white"
    )

    fig.update_layout(
        xaxis_title="Date",
        yaxis_title="Count",
        legend_title="Metric"
    )

    # Save as interactive HTML
    fig.write_html(f"{output_path}/traffic_chart.html")

    # Save as static image (requires kaleido)
    # pip install kaleido
    fig.write_image(f"{output_path}/traffic_chart.png", scale=2)

    return fig

Integration with Claude Skill

The Claude Skill will use these visualization tools via Python scripts:

15-ourdigital-ga-agent/
├── SKILL.md
├── scripts/
│   ├── fetch_ga4_data.py      # Get data from GA4/BigQuery
│   ├── generate_report.py     # Create visualizations
│   └── streamlit_app.py       # Launch dashboard
├── templates/
│   └── report.html            # Static report template
└── assets/
    └── styles.css             # Dashboard styling

Requirements File

Create visualization/requirements.txt:

streamlit>=1.28.0
pandas>=2.0.0
plotly>=5.18.0
google-cloud-bigquery>=3.12.0
google-analytics-data>=0.18.0
kaleido>=0.2.1