Datastoria visualization
Rules for charts and visualization. Use when the user asks for charts, graphs, plots, or visual representations (line, bar, pie, timeseries).
install
source · Clone the upstream repo
git clone https://github.com/FrankChen021/datastoria
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/FrankChen021/datastoria "$T" && mkdir -p ~/.claude/skills && cp -r "$T/resources/skills/visualization" ~/.claude/skills/frankchen021-datastoria-visualization && rm -rf "$T"
manifest:
resources/skills/visualization/SKILL.mdsource content
WORKFLOW (MANDATORY ORDER)
a) Generate or obtain SQL:
- CHECK CONTEXT FIRST: If valid SQL exists in the context (explicitly provided by the user or from a previous message), USE IT DIRECTLY and skip to step (b).
- IF NO SQL FOUND: You must generate it.
- Dependency: Valid SQL generation REQUIRES the
skill.sql-expert - Action: Check if
skill is loaded.sql-expert- If NOT loaded: Call the
tool withskill
IMMEDIATELY. Do not proceed to generate SQL until the skill is loaded.['sql-expert'] - If ALREADY loaded: Generate the SQL strictly following the rules in the
skill (including Schema Discovery, Schema Fidelity, ProfileEvents handling, and Performance Optimization).sql-expert
- If NOT loaded: Call the
- Dependency: Valid SQL generation REQUIRES the
- For
visualization requests: Do NOT callsystem.query_log
. Load thesearch_query_log
skill, then loadclickhouse-system-queries
viareferences/system-query-log.md
, generate the SQL, and validate it.skill_resource
b) VALIDATION (MANDATORY):
- ALWAYS call
with the SQL before including the chart spec in your response.validate_sql - RETRY LOGIC: If validation fails, retry up to 3 times by fixing the SQL (referring to
skill rules) and validating again.sql-expert - Only proceed to step (c) if validation returns success: true.
c) After validation passes:
- Include the full chart spec in your response using a markdown code block with language
. The content must be valid JSON matching the OUTPUT FORMAT below, and must includechart-spec
. Derive type, titleOption, legendOption, etc. from the CHART TYPE RULES and OUTPUT FORMAT above. Do not call any tool for this—put the complete spec in your reply.datasource: { "sql": "<the validated SQL>" }
d) Execution:
- PROHIBITED: Do NOT call
. The chart component in the client will automatically execute the query found in theexecute_sql
. Calling it here wastes tokens and causes duplicate execution.chart-spec
CHART TYPE RULES
STEP 1: CHECK USER'S EXPLICIT CHART REQUEST (HIGHEST PRIORITY)
If user question contains ANY of these keywords, use the corresponding chart type:
- "line chart" → type: "line" (MANDATORY)
- "bar chart" → type: "bar" (MANDATORY)
- "pie chart" → type: "pie" (MANDATORY)
- "timeseries" or "time series" → type: "line" (MANDATORY)
- "trend" → type: "line" (MANDATORY)
STEP 2: ANALYZE SQL (Only if no explicit chart request in Step 1)
- "line" - Time-based data with trends (DateTime/Date + GROUP BY time dimension; "over time", "by day/month/hour").
- "bar" - Categorical comparisons (GROUP BY categories; "compare", "by category").
- "pie" - Categorical distribution, proportions (single categorical dimension; "distribution", "breakdown", "proportion"; 2 columns: category + numeric value; best for 3-15 categories).
- "table" - Raw data listing (LAST RESORT): user asks for "table" or "list" with NO chart keywords; no numeric aggregations.
CRITICAL RULES
- When legendOption.placement is "bottom" or "right", you MUST include a "values" array: base ["min", "max"]; add "sum"/"count" if SQL uses SUM/COUNT; add "avg" if SQL uses AVG.
- Line/Bar: Use "bottom" for GROUP BY with non-time dimensions, "none" for single metric.
- Pie: legendOption.placement "right"|"bottom"|"inside" (no "none"); omit legendOption.values; use labelOption (show, format) and valueFormat as needed.
OUTPUT FORMAT (include in your response as a chart-spec
code block)
chart-specPut the full chart spec in a markdown code block with language chart-spec. The JSON must include
datasource.sql (the validated SQL). The client parses this block to render the chart.
Line/Bar Chart example:
{ "type": "line", "titleOption": { "title": "Descriptive chart title", "align": "center" }, "width": 6, "legendOption": { "placement": "bottom", "values": ["min", "max", "sum"] }, "datasource": { "sql": "SELECT ..." } }
Pie Chart example:
{ "type": "pie", "titleOption": { "title": "Distribution by Category", "align": "center" }, "width": 6, "legendOption": { "placement": "right" }, "labelOption": { "show": true, "format": "name-percent" }, "valueFormat": "short_number", "datasource": { "sql": "SELECT ..." } }
- ❌ NEVER include a chart spec before validate_sql has succeeded.
- ❌ NEVER skip SQL generation if no SQL exists in context.
- ❌ NEVER write SQL in your text response—ALWAYS use the instructions in
skill.sql-expert - ✅ ALWAYS follow: Check for SQL → If missing, Load
Skill → Validation → Include chart spec in response.sql-expert - ✅ If validation fails, retry up to 3 times.