@quarri/claude-data-tools 1.0.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +12 -1
- package/dist/api/client.d.ts +36 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +58 -2
- package/dist/api/client.js.map +1 -1
- package/dist/auth-cli.d.ts +7 -0
- package/dist/auth-cli.d.ts.map +1 -0
- package/dist/auth-cli.js +361 -0
- package/dist/auth-cli.js.map +1 -0
- package/dist/index.js +227 -17
- package/dist/index.js.map +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +199 -283
- package/dist/tools/definitions.js.map +1 -1
- package/package.json +8 -2
- package/skills/SKILL_CHAINING_DEMO.md +335 -0
- package/skills/TEST_SCENARIOS.md +189 -0
- package/skills/quarri-analyze/SKILL.md +274 -0
- package/skills/quarri-chart/SKILL.md +374 -0
- package/skills/quarri-debug-connector/SKILL.md +338 -0
- package/skills/quarri-diagnose/SKILL.md +372 -0
- package/skills/quarri-explain/SKILL.md +184 -0
- package/skills/quarri-extract/SKILL.md +353 -0
- package/skills/quarri-insights/SKILL.md +328 -0
- package/skills/quarri-metric/SKILL.md +400 -0
- package/skills/quarri-query/SKILL.md +159 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run complete data analysis pipeline orchestrating query, insights, and charts
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /quarri-analyze - Full Analysis Pipeline
|
|
8
|
+
|
|
9
|
+
Orchestrate a complete data analysis pipeline by coordinating query generation, statistical analysis, business insights, and visualization.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
Use `/quarri-analyze` when users want comprehensive analysis:
|
|
14
|
+
- "Analyze our sales trends"
|
|
15
|
+
- "What's driving customer churn?"
|
|
16
|
+
- "Give me insights on revenue performance"
|
|
17
|
+
- "Help me understand our order patterns"
|
|
18
|
+
|
|
19
|
+
This is more powerful than `/quarri-query` as it provides statistics, visualizations, and actionable insights.
|
|
20
|
+
|
|
21
|
+
## Orchestration Flow
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
/quarri-analyze
|
|
25
|
+
│
|
|
26
|
+
├── 1. /quarri-query
|
|
27
|
+
│ └── Generate SQL, fetch schema, execute query
|
|
28
|
+
│
|
|
29
|
+
├── 2. /quarri-insights
|
|
30
|
+
│ └── Statistical analysis + business interpretation
|
|
31
|
+
│
|
|
32
|
+
└── 3. /quarri-chart (if visualization warranted)
|
|
33
|
+
└── Chart recommendation + configuration
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Stage 1: Query (via /quarri-query)
|
|
37
|
+
|
|
38
|
+
Generate and execute SQL for the analysis question:
|
|
39
|
+
1. Fetch schema using `quarri_get_schema`
|
|
40
|
+
2. Search for relevant metrics using `quarri_search_metrics`
|
|
41
|
+
3. Generate SQL following star schema patterns
|
|
42
|
+
4. Execute using `quarri_execute_sql`
|
|
43
|
+
|
|
44
|
+
### Stage 2: Insights (via /quarri-insights)
|
|
45
|
+
|
|
46
|
+
Analyze the query results:
|
|
47
|
+
- Descriptive statistics for numeric columns
|
|
48
|
+
- Distribution and outlier analysis
|
|
49
|
+
- Correlation between variables
|
|
50
|
+
- Time series trends if applicable
|
|
51
|
+
- Business interpretation and recommendations
|
|
52
|
+
|
|
53
|
+
### Stage 3: Chart (via /quarri-chart)
|
|
54
|
+
|
|
55
|
+
If data warrants visualization:
|
|
56
|
+
- Apply chart decision tree
|
|
57
|
+
- Generate appropriate chart configuration
|
|
58
|
+
- Recommend alternatives if applicable
|
|
59
|
+
|
|
60
|
+
## MECE Framework for Complex Analysis
|
|
61
|
+
|
|
62
|
+
When analyzing complex business questions, structure the breakdown using the MECE principle:
|
|
63
|
+
- **Mutually Exclusive**: Categories don't overlap
|
|
64
|
+
- **Collectively Exhaustive**: All possibilities covered
|
|
65
|
+
|
|
66
|
+
### MECE Application Examples
|
|
67
|
+
|
|
68
|
+
#### Revenue Analysis
|
|
69
|
+
"Why is revenue changing?"
|
|
70
|
+
```
|
|
71
|
+
Revenue Drivers (MECE Breakdown)
|
|
72
|
+
├── Volume Drivers
|
|
73
|
+
│ ├── Customer count
|
|
74
|
+
│ ├── Order frequency per customer
|
|
75
|
+
│ └── Units per order
|
|
76
|
+
├── Price Drivers
|
|
77
|
+
│ ├── Unit price
|
|
78
|
+
│ ├── Product mix shift
|
|
79
|
+
│ └── Discount rates
|
|
80
|
+
└── External Factors
|
|
81
|
+
├── Seasonality
|
|
82
|
+
├── Market conditions
|
|
83
|
+
└── Competition
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Customer Churn Analysis
|
|
87
|
+
"What's causing churn?"
|
|
88
|
+
```
|
|
89
|
+
Churn Factors (MECE Breakdown)
|
|
90
|
+
├── Product Issues
|
|
91
|
+
│ ├── Quality problems
|
|
92
|
+
│ ├── Feature gaps
|
|
93
|
+
│ └── Performance issues
|
|
94
|
+
├── Service Issues
|
|
95
|
+
│ ├── Support quality
|
|
96
|
+
│ ├── Response time
|
|
97
|
+
│ └── Resolution rate
|
|
98
|
+
├── Price Issues
|
|
99
|
+
│ ├── Absolute cost
|
|
100
|
+
│ ├── Perceived value
|
|
101
|
+
│ └── Competitor pricing
|
|
102
|
+
└── External Factors
|
|
103
|
+
├── Business closure
|
|
104
|
+
├── Changed needs
|
|
105
|
+
└── Market exit
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Sales Performance
|
|
109
|
+
"Why are sales underperforming?"
|
|
110
|
+
```
|
|
111
|
+
Sales Performance (MECE Breakdown)
|
|
112
|
+
├── Lead Generation
|
|
113
|
+
│ ├── Marketing qualified leads
|
|
114
|
+
│ ├── Inbound inquiries
|
|
115
|
+
│ └── Outbound prospecting
|
|
116
|
+
├── Conversion Rate
|
|
117
|
+
│ ├── Lead to opportunity
|
|
118
|
+
│ ├── Opportunity to proposal
|
|
119
|
+
│ └── Proposal to close
|
|
120
|
+
└── Deal Size
|
|
121
|
+
├── Initial contract value
|
|
122
|
+
├── Upsell/cross-sell
|
|
123
|
+
└── Discounting
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### When to Apply MECE
|
|
127
|
+
|
|
128
|
+
Apply MECE structuring when:
|
|
129
|
+
1. Question involves "why" (root cause analysis)
|
|
130
|
+
2. Multiple factors could explain the outcome
|
|
131
|
+
3. User needs comprehensive coverage
|
|
132
|
+
4. Decision-making requires evaluating alternatives
|
|
133
|
+
|
|
134
|
+
For simple queries ("show revenue by region"), skip MECE and provide direct analysis.
|
|
135
|
+
|
|
136
|
+
## Workflow
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
1. Parse the analysis question
|
|
140
|
+
- Identify primary metric/measure
|
|
141
|
+
- Identify dimensions/breakdowns
|
|
142
|
+
- Determine time scope
|
|
143
|
+
|
|
144
|
+
2. Execute /quarri-query
|
|
145
|
+
- Generate appropriate SQL
|
|
146
|
+
- Execute and retrieve data
|
|
147
|
+
- Validate results
|
|
148
|
+
|
|
149
|
+
3. Execute /quarri-insights
|
|
150
|
+
- Run statistical analysis
|
|
151
|
+
- Identify patterns
|
|
152
|
+
- Generate business insights
|
|
153
|
+
|
|
154
|
+
4. Determine if visualization needed
|
|
155
|
+
- Data has clear visual pattern?
|
|
156
|
+
- More than 3 data points?
|
|
157
|
+
- User explicitly requested chart?
|
|
158
|
+
|
|
159
|
+
5. If yes, execute /quarri-chart
|
|
160
|
+
- Select appropriate chart type
|
|
161
|
+
- Generate configuration
|
|
162
|
+
|
|
163
|
+
6. Synthesize comprehensive report
|
|
164
|
+
- Combine all findings
|
|
165
|
+
- Apply MECE structure if complex question
|
|
166
|
+
- Prioritize actionable recommendations
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Output Format
|
|
170
|
+
|
|
171
|
+
```markdown
|
|
172
|
+
## Analysis: [Question Summary]
|
|
173
|
+
|
|
174
|
+
### Query
|
|
175
|
+
```sql
|
|
176
|
+
[SQL generated by /quarri-query]
|
|
177
|
+
```
|
|
178
|
+
[Brief explanation of what the query retrieves]
|
|
179
|
+
|
|
180
|
+
### Data Summary
|
|
181
|
+
- **Rows**: [count]
|
|
182
|
+
- **Date range**: [range]
|
|
183
|
+
- **Key dimensions**: [list]
|
|
184
|
+
|
|
185
|
+
### Statistical Findings
|
|
186
|
+
[From /quarri-insights]
|
|
187
|
+
- [Key statistic 1]
|
|
188
|
+
- [Key statistic 2]
|
|
189
|
+
- [Key statistic 3]
|
|
190
|
+
|
|
191
|
+
### MECE Breakdown (if applicable)
|
|
192
|
+
[Structured analysis of drivers/factors]
|
|
193
|
+
|
|
194
|
+
### Business Insights
|
|
195
|
+
|
|
196
|
+
#### Key Finding
|
|
197
|
+
**[Most important takeaway with specific numbers]**
|
|
198
|
+
|
|
199
|
+
#### Additional Insights
|
|
200
|
+
1. **[Insight type]**: [Specific finding]
|
|
201
|
+
- Implication: [What it means]
|
|
202
|
+
- Action: [What to do]
|
|
203
|
+
|
|
204
|
+
2. **[Insight type]**: [Specific finding]
|
|
205
|
+
- Implication: [What it means]
|
|
206
|
+
- Action: [What to do]
|
|
207
|
+
|
|
208
|
+
### Visualization
|
|
209
|
+
[From /quarri-chart if applicable]
|
|
210
|
+
[Chart type recommendation with rationale]
|
|
211
|
+
[Configuration or URL]
|
|
212
|
+
|
|
213
|
+
### Recommended Next Steps
|
|
214
|
+
1. [Immediate action]
|
|
215
|
+
2. [Follow-up analysis]
|
|
216
|
+
3. [Deeper investigation if warranted]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Example: Full Analysis
|
|
220
|
+
|
|
221
|
+
**User**: "Analyze why revenue dropped last month"
|
|
222
|
+
|
|
223
|
+
**Analysis Output**:
|
|
224
|
+
|
|
225
|
+
### Query
|
|
226
|
+
```sql
|
|
227
|
+
SELECT
|
|
228
|
+
DATE_TRUNC('week', order_date) as week,
|
|
229
|
+
product_category,
|
|
230
|
+
COUNT(*) as order_count,
|
|
231
|
+
COUNT(DISTINCT customer_id) as customers,
|
|
232
|
+
SUM(revenue) as revenue,
|
|
233
|
+
AVG(order_value) as avg_order_value
|
|
234
|
+
FROM quarri.bridge
|
|
235
|
+
WHERE order_date >= DATE '2024-11-01'
|
|
236
|
+
GROUP BY week, product_category
|
|
237
|
+
ORDER BY week, product_category
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### MECE Breakdown: Revenue Decline Drivers
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
Revenue = Customers × Orders/Customer × Revenue/Order
|
|
244
|
+
|
|
245
|
+
Analysis by Driver:
|
|
246
|
+
├── Customer Count: -8% (from 1,245 to 1,146)
|
|
247
|
+
│ └── PRIMARY DRIVER: New customer acquisition dropped
|
|
248
|
+
├── Order Frequency: -2% (from 2.3 to 2.25 orders/customer)
|
|
249
|
+
│ └── Minor decline, within normal range
|
|
250
|
+
└── Revenue per Order: +1% (from $89 to $90)
|
|
251
|
+
└── Stable, slight increase
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Key Finding
|
|
255
|
+
**Customer acquisition dropped 8%, accounting for 75% of the revenue decline. New customer count fell from 312 to 198 (-37%).**
|
|
256
|
+
|
|
257
|
+
### Recommended Actions
|
|
258
|
+
1. **Immediate**: Review marketing spend and campaign performance from last month
|
|
259
|
+
2. **This week**: Analyze acquisition channel performance (paid vs organic)
|
|
260
|
+
3. **Follow-up**: Compare conversion rates by channel to identify where leads are dropping
|
|
261
|
+
|
|
262
|
+
## Error Handling
|
|
263
|
+
|
|
264
|
+
- If query returns no data, suggest adjusting filters or date range
|
|
265
|
+
- If statistical analysis fails, report data quality issues
|
|
266
|
+
- If MECE breakdown unclear, ask clarifying questions
|
|
267
|
+
- Always provide partial results if some stages succeed
|
|
268
|
+
|
|
269
|
+
## Integration
|
|
270
|
+
|
|
271
|
+
This skill orchestrates:
|
|
272
|
+
- `/quarri-query` for data retrieval
|
|
273
|
+
- `/quarri-insights` for statistical analysis and business interpretation
|
|
274
|
+
- `/quarri-chart` for visualization recommendations
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate interactive Plotly charts and open them in the browser
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /quarri-chart - Interactive Chart Generation
|
|
8
|
+
|
|
9
|
+
Generate data visualizations as interactive HTML files and open them in the default browser.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
Use `/quarri-chart` when users want visualizations:
|
|
14
|
+
- "Create a chart of revenue by month"
|
|
15
|
+
- "Visualize customer distribution"
|
|
16
|
+
- "Show me a graph of this data"
|
|
17
|
+
- "Chart sales by category"
|
|
18
|
+
|
|
19
|
+
## Primary Workflow (DEFAULT)
|
|
20
|
+
|
|
21
|
+
### Step 1: Query the data
|
|
22
|
+
```sql
|
|
23
|
+
SELECT category, SUM(sales) as total_sales
|
|
24
|
+
FROM orders
|
|
25
|
+
GROUP BY category
|
|
26
|
+
ORDER BY total_sales DESC
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Step 2: Generate HTML with Plotly
|
|
30
|
+
Write an HTML file to `/tmp/quarri_chart.html`:
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<!DOCTYPE html>
|
|
34
|
+
<html>
|
|
35
|
+
<head>
|
|
36
|
+
<title>[Chart Title]</title>
|
|
37
|
+
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
|
|
38
|
+
<style>
|
|
39
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; background: #f5f5f5; }
|
|
40
|
+
h1 { color: #1a1a2e; text-align: center; margin-bottom: 10px; }
|
|
41
|
+
.subtitle { color: #666; text-align: center; margin-bottom: 30px; }
|
|
42
|
+
#chart { width: 100%; max-width: 900px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); padding: 20px; }
|
|
43
|
+
</style>
|
|
44
|
+
</head>
|
|
45
|
+
<body>
|
|
46
|
+
<h1>[Chart Title]</h1>
|
|
47
|
+
<p class="subtitle">Data from [database_name]</p>
|
|
48
|
+
<div id="chart"></div>
|
|
49
|
+
<script>
|
|
50
|
+
var data = [{
|
|
51
|
+
x: [/* labels */],
|
|
52
|
+
y: [/* values */],
|
|
53
|
+
type: 'bar',
|
|
54
|
+
marker: { color: '#4F46E5' }
|
|
55
|
+
}];
|
|
56
|
+
|
|
57
|
+
var layout = {
|
|
58
|
+
title: '',
|
|
59
|
+
xaxis: { title: '[X Label]' },
|
|
60
|
+
yaxis: { title: '[Y Label]', tickformat: '$,.0f' },
|
|
61
|
+
margin: { t: 40, b: 60, l: 80, r: 40 }
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
var config = { responsive: true, displayModeBar: true };
|
|
65
|
+
Plotly.newPlot('chart', data, layout, config);
|
|
66
|
+
</script>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Step 3: Open in browser
|
|
72
|
+
```bash
|
|
73
|
+
open /tmp/quarri_chart.html
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
On different platforms:
|
|
77
|
+
- **macOS**: `open /tmp/quarri_chart.html`
|
|
78
|
+
- **Linux**: `xdg-open /tmp/quarri_chart.html`
|
|
79
|
+
- **Windows**: `start /tmp/quarri_chart.html`
|
|
80
|
+
|
|
81
|
+
## Chart Type Selection
|
|
82
|
+
|
|
83
|
+
### Decision Tree
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
START: What is the primary analysis goal?
|
|
87
|
+
|
|
88
|
+
1. TRENDS OVER TIME?
|
|
89
|
+
└─→ Single series? → LINE CHART
|
|
90
|
+
└─→ Multiple series? → MULTI-LINE
|
|
91
|
+
└─→ Cumulative? → AREA CHART
|
|
92
|
+
|
|
93
|
+
2. COMPARING CATEGORIES?
|
|
94
|
+
└─→ 2-7 categories → VERTICAL BAR
|
|
95
|
+
└─→ 8-15 categories → HORIZONTAL BAR
|
|
96
|
+
└─→ 15+ categories → TOP N + "Other"
|
|
97
|
+
|
|
98
|
+
3. SHOWING DISTRIBUTION?
|
|
99
|
+
└─→ Continuous data → HISTOGRAM
|
|
100
|
+
└─→ Categorical → BAR (sorted)
|
|
101
|
+
|
|
102
|
+
4. PARTS OF A WHOLE?
|
|
103
|
+
└─→ 2-6 parts → PIE/DONUT
|
|
104
|
+
└─→ 7+ parts → STACKED BAR
|
|
105
|
+
|
|
106
|
+
5. RELATIONSHIP BETWEEN VARIABLES?
|
|
107
|
+
└─→ Two numeric → SCATTER PLOT
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Plotly Templates
|
|
111
|
+
|
|
112
|
+
### Bar Chart
|
|
113
|
+
```javascript
|
|
114
|
+
var data = [{
|
|
115
|
+
x: ['Category A', 'Category B', 'Category C'],
|
|
116
|
+
y: [450000, 380000, 290000],
|
|
117
|
+
type: 'bar',
|
|
118
|
+
marker: {
|
|
119
|
+
color: ['#4F46E5', '#7C3AED', '#A78BFA']
|
|
120
|
+
},
|
|
121
|
+
text: ['$450K', '$380K', '$290K'],
|
|
122
|
+
textposition: 'auto'
|
|
123
|
+
}];
|
|
124
|
+
|
|
125
|
+
var layout = {
|
|
126
|
+
title: 'Sales by Category',
|
|
127
|
+
xaxis: { title: 'Category' },
|
|
128
|
+
yaxis: { title: 'Sales ($)', tickformat: '$,.0f' }
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Horizontal Bar (many categories)
|
|
133
|
+
```javascript
|
|
134
|
+
var data = [{
|
|
135
|
+
y: ['Product A', 'Product B', 'Product C', 'Product D', 'Product E'],
|
|
136
|
+
x: [85000, 72000, 65000, 58000, 45000],
|
|
137
|
+
type: 'bar',
|
|
138
|
+
orientation: 'h',
|
|
139
|
+
marker: { color: '#4F46E5' }
|
|
140
|
+
}];
|
|
141
|
+
|
|
142
|
+
var layout = {
|
|
143
|
+
title: 'Top Products by Revenue',
|
|
144
|
+
xaxis: { title: 'Revenue ($)', tickformat: '$,.0f' },
|
|
145
|
+
margin: { l: 120 }
|
|
146
|
+
};
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Line Chart (time series)
|
|
150
|
+
```javascript
|
|
151
|
+
var data = [{
|
|
152
|
+
x: ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06'],
|
|
153
|
+
y: [120000, 135000, 128000, 145000, 160000, 175000],
|
|
154
|
+
type: 'scatter',
|
|
155
|
+
mode: 'lines+markers',
|
|
156
|
+
line: { color: '#4F46E5', width: 3 },
|
|
157
|
+
marker: { size: 8 }
|
|
158
|
+
}];
|
|
159
|
+
|
|
160
|
+
var layout = {
|
|
161
|
+
title: 'Monthly Revenue Trend',
|
|
162
|
+
xaxis: { title: 'Month' },
|
|
163
|
+
yaxis: { title: 'Revenue ($)', tickformat: '$,.0f' }
|
|
164
|
+
};
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Multi-Line Chart
|
|
168
|
+
```javascript
|
|
169
|
+
var data = [
|
|
170
|
+
{
|
|
171
|
+
x: ['Jan', 'Feb', 'Mar', 'Apr'],
|
|
172
|
+
y: [100, 120, 115, 140],
|
|
173
|
+
name: 'Product A',
|
|
174
|
+
type: 'scatter',
|
|
175
|
+
mode: 'lines+markers'
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
x: ['Jan', 'Feb', 'Mar', 'Apr'],
|
|
179
|
+
y: [80, 95, 110, 120],
|
|
180
|
+
name: 'Product B',
|
|
181
|
+
type: 'scatter',
|
|
182
|
+
mode: 'lines+markers'
|
|
183
|
+
}
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
var layout = {
|
|
187
|
+
title: 'Product Comparison',
|
|
188
|
+
xaxis: { title: 'Month' },
|
|
189
|
+
yaxis: { title: 'Sales' }
|
|
190
|
+
};
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Pie/Donut Chart
|
|
194
|
+
```javascript
|
|
195
|
+
var data = [{
|
|
196
|
+
labels: ['Technology', 'Furniture', 'Office Supplies'],
|
|
197
|
+
values: [5471124, 4730801, 4144724],
|
|
198
|
+
type: 'pie',
|
|
199
|
+
hole: 0.4, // Remove for regular pie
|
|
200
|
+
marker: {
|
|
201
|
+
colors: ['#4F46E5', '#10B981', '#F59E0B']
|
|
202
|
+
},
|
|
203
|
+
textinfo: 'label+percent'
|
|
204
|
+
}];
|
|
205
|
+
|
|
206
|
+
var layout = {
|
|
207
|
+
title: 'Sales Distribution by Category'
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Scatter Plot
|
|
212
|
+
```javascript
|
|
213
|
+
var data = [{
|
|
214
|
+
x: [/* x values */],
|
|
215
|
+
y: [/* y values */],
|
|
216
|
+
mode: 'markers',
|
|
217
|
+
type: 'scatter',
|
|
218
|
+
marker: {
|
|
219
|
+
size: 10,
|
|
220
|
+
color: '#4F46E5',
|
|
221
|
+
opacity: 0.7
|
|
222
|
+
}
|
|
223
|
+
}];
|
|
224
|
+
|
|
225
|
+
var layout = {
|
|
226
|
+
title: 'Correlation Analysis',
|
|
227
|
+
xaxis: { title: 'Variable X' },
|
|
228
|
+
yaxis: { title: 'Variable Y' }
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Grouped Bar Chart
|
|
233
|
+
```javascript
|
|
234
|
+
var data = [
|
|
235
|
+
{
|
|
236
|
+
x: ['Q1', 'Q2', 'Q3', 'Q4'],
|
|
237
|
+
y: [120, 150, 180, 200],
|
|
238
|
+
name: '2023',
|
|
239
|
+
type: 'bar'
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
x: ['Q1', 'Q2', 'Q3', 'Q4'],
|
|
243
|
+
y: [140, 165, 195, 220],
|
|
244
|
+
name: '2024',
|
|
245
|
+
type: 'bar'
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
var layout = {
|
|
250
|
+
title: 'Year over Year Comparison',
|
|
251
|
+
barmode: 'group'
|
|
252
|
+
};
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Color Palettes
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
// Primary (single series)
|
|
259
|
+
const PRIMARY = '#4F46E5';
|
|
260
|
+
|
|
261
|
+
// Categorical (multiple series)
|
|
262
|
+
const CATEGORICAL = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16'];
|
|
263
|
+
|
|
264
|
+
// Sequential (gradient)
|
|
265
|
+
const SEQUENTIAL = ['#E0E7FF', '#A5B4FC', '#818CF8', '#6366F1', '#4F46E5', '#4338CA', '#3730A3'];
|
|
266
|
+
|
|
267
|
+
// Diverging (positive/negative)
|
|
268
|
+
const DIVERGING_NEG = '#EF4444';
|
|
269
|
+
const DIVERGING_POS = '#10B981';
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Number Formatting
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
// Currency
|
|
276
|
+
tickformat: '$,.0f' // $1,234,567
|
|
277
|
+
tickformat: '$,.2f' // $1,234,567.89
|
|
278
|
+
tickformat: '$~s' // $1.2M
|
|
279
|
+
|
|
280
|
+
// Percentages
|
|
281
|
+
tickformat: '.1%' // 45.2%
|
|
282
|
+
|
|
283
|
+
// Large numbers
|
|
284
|
+
tickformat: '~s' // 1.2M, 3.4K
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Complete Example
|
|
288
|
+
|
|
289
|
+
For "Show me sales by category":
|
|
290
|
+
|
|
291
|
+
```html
|
|
292
|
+
<!DOCTYPE html>
|
|
293
|
+
<html>
|
|
294
|
+
<head>
|
|
295
|
+
<title>Sales by Category</title>
|
|
296
|
+
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
|
|
297
|
+
<style>
|
|
298
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; background: #f5f5f5; }
|
|
299
|
+
h1 { color: #1a1a2e; text-align: center; margin-bottom: 10px; }
|
|
300
|
+
.subtitle { color: #666; text-align: center; margin-bottom: 30px; font-size: 14px; }
|
|
301
|
+
#chart { width: 100%; max-width: 900px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); padding: 20px; }
|
|
302
|
+
</style>
|
|
303
|
+
</head>
|
|
304
|
+
<body>
|
|
305
|
+
<h1>Superstore Sales by Category</h1>
|
|
306
|
+
<p class="subtitle">Total: $14.3M across 51,290 orders</p>
|
|
307
|
+
<div id="chart"></div>
|
|
308
|
+
<script>
|
|
309
|
+
var data = [{
|
|
310
|
+
x: ['Technology', 'Furniture', 'Office Supplies'],
|
|
311
|
+
y: [5471124.24, 4730801.23, 4144724.04],
|
|
312
|
+
type: 'bar',
|
|
313
|
+
marker: {
|
|
314
|
+
color: ['#4F46E5', '#7C3AED', '#A78BFA']
|
|
315
|
+
},
|
|
316
|
+
text: ['$5.47M', '$4.73M', '$4.14M'],
|
|
317
|
+
textposition: 'outside',
|
|
318
|
+
textfont: { size: 14, color: '#374151' }
|
|
319
|
+
}];
|
|
320
|
+
|
|
321
|
+
var layout = {
|
|
322
|
+
xaxis: { title: 'Category', tickfont: { size: 12 } },
|
|
323
|
+
yaxis: {
|
|
324
|
+
title: 'Sales ($)',
|
|
325
|
+
tickformat: '$,.0f',
|
|
326
|
+
tickfont: { size: 11 }
|
|
327
|
+
},
|
|
328
|
+
margin: { t: 40, b: 80, l: 100, r: 40 },
|
|
329
|
+
plot_bgcolor: 'white',
|
|
330
|
+
paper_bgcolor: 'white'
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
var config = {
|
|
334
|
+
responsive: true,
|
|
335
|
+
displayModeBar: true,
|
|
336
|
+
modeBarButtonsToRemove: ['lasso2d', 'select2d']
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
Plotly.newPlot('chart', data, layout, config);
|
|
340
|
+
</script>
|
|
341
|
+
</body>
|
|
342
|
+
</html>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Then run:
|
|
346
|
+
```bash
|
|
347
|
+
open /tmp/quarri_chart.html
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Alternative Outputs
|
|
351
|
+
|
|
352
|
+
### QuickChart URL (for sharing/embedding)
|
|
353
|
+
When user specifically needs a URL:
|
|
354
|
+
```
|
|
355
|
+
https://quickchart.io/chart?c={type:'bar',data:{labels:['A','B','C'],datasets:[{data:[10,20,15]}]}}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### ASCII Chart (terminal only)
|
|
359
|
+
When user is in a terminal-only environment:
|
|
360
|
+
```
|
|
361
|
+
Sales by Category
|
|
362
|
+
|
|
363
|
+
Technology |████████████████████████████████████████ $5.47M
|
|
364
|
+
Furniture |██████████████████████████████████ $4.73M
|
|
365
|
+
Office Supplies |██████████████████████████████ $4.14M
|
|
366
|
+
0 $3M $6M
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Integration
|
|
370
|
+
|
|
371
|
+
Charts work best when combined with:
|
|
372
|
+
- `/quarri-query`: Get data first, then visualize
|
|
373
|
+
- `/quarri-analyze`: Called as part of full analysis pipeline
|
|
374
|
+
- `/quarri-insights`: Visual support for statistical findings
|