@quarri/claude-data-tools 1.1.0 → 1.2.0
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/dist/index.js +238 -38
- package/dist/index.js.map +1 -1
- package/dist/tools/definitions.d.ts +6 -0
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +23 -106
- package/dist/tools/definitions.js.map +1 -1
- package/dist/ui/resources.d.ts +110 -0
- package/dist/ui/resources.d.ts.map +1 -0
- package/dist/ui/resources.js +263 -0
- package/dist/ui/resources.js.map +1 -0
- package/package.json +5 -3
- package/skills/quarri-chart/SKILL.md +194 -300
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Generate
|
|
2
|
+
description: Generate interactive Plotly charts rendered as MCP UI resources
|
|
3
3
|
globs:
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# /quarri-chart -
|
|
7
|
+
# /quarri-chart - Interactive Chart Generation
|
|
8
8
|
|
|
9
|
-
Generate data visualizations
|
|
9
|
+
Generate data visualizations as interactive Plotly charts using MCP UI resources.
|
|
10
10
|
|
|
11
11
|
## When to Use
|
|
12
12
|
|
|
@@ -14,73 +14,45 @@ Use `/quarri-chart` when users want visualizations:
|
|
|
14
14
|
- "Create a chart of revenue by month"
|
|
15
15
|
- "Visualize customer distribution"
|
|
16
16
|
- "Show me a graph of this data"
|
|
17
|
-
- "
|
|
17
|
+
- "Chart sales by category"
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Primary Workflow
|
|
20
20
|
|
|
21
|
-
### 1
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
https://quickchart.io/chart?c={encoded_config}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**Example**:
|
|
32
|
-
```
|
|
33
|
-
https://quickchart.io/chart?c={type:'bar',data:{labels:['Q1','Q2','Q3','Q4'],datasets:[{label:'Revenue',data:[120,150,180,200]}]}}
|
|
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
|
|
34
27
|
```
|
|
35
28
|
|
|
36
|
-
### 2
|
|
37
|
-
|
|
38
|
-
Generate Python code that creates and saves chart images.
|
|
39
|
-
|
|
40
|
-
**When to use**: Custom styling, publication-quality charts, local files
|
|
41
|
-
|
|
42
|
-
```python
|
|
43
|
-
import matplotlib.pyplot as plt
|
|
44
|
-
import pandas as pd
|
|
29
|
+
### Step 2: Return chart as MCP UI resource
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
categories = ['Q1', 'Q2', 'Q3', 'Q4']
|
|
48
|
-
values = [120, 150, 180, 200]
|
|
49
|
-
|
|
50
|
-
# Create figure
|
|
51
|
-
fig, ax = plt.subplots(figsize=(10, 6))
|
|
52
|
-
ax.bar(categories, values, color='#4F46E5')
|
|
53
|
-
|
|
54
|
-
# Styling
|
|
55
|
-
ax.set_xlabel('Quarter')
|
|
56
|
-
ax.set_ylabel('Revenue ($K)')
|
|
57
|
-
ax.set_title('Quarterly Revenue')
|
|
58
|
-
ax.spines['top'].set_visible(False)
|
|
59
|
-
ax.spines['right'].set_visible(False)
|
|
60
|
-
|
|
61
|
-
# Save
|
|
62
|
-
plt.tight_layout()
|
|
63
|
-
plt.savefig('revenue_chart.png', dpi=150)
|
|
64
|
-
plt.show()
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 3. ASCII Chart
|
|
68
|
-
|
|
69
|
-
Terminal-friendly text visualization for quick inspection.
|
|
70
|
-
|
|
71
|
-
**When to use**: Terminal environments, quick data review, no graphics support
|
|
31
|
+
After getting the data, construct a Plotly configuration and include it in your response. The chart will be rendered as an interactive UI component.
|
|
72
32
|
|
|
33
|
+
**Example Plotly config for bar chart:**
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"data": [{
|
|
37
|
+
"x": ["Category A", "Category B", "Category C"],
|
|
38
|
+
"y": [450000, 380000, 290000],
|
|
39
|
+
"type": "bar",
|
|
40
|
+
"marker": { "color": "#4F46E5" }
|
|
41
|
+
}],
|
|
42
|
+
"layout": {
|
|
43
|
+
"title": "Sales by Category",
|
|
44
|
+
"xaxis": { "title": "Category" },
|
|
45
|
+
"yaxis": { "title": "Sales ($)", "tickformat": "$,.0f" }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
73
48
|
```
|
|
74
|
-
Revenue by Quarter
|
|
75
49
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
0 100 200
|
|
81
|
-
```
|
|
50
|
+
The response should include this as a resource block with:
|
|
51
|
+
- URI: `ui://quarri/chart`
|
|
52
|
+
- MIME type: `application/vnd.quarri.chart+json`
|
|
53
|
+
- Content: JSON with `type: "chart"` and `plotly: { data, layout }`
|
|
82
54
|
|
|
83
|
-
## Chart Selection
|
|
55
|
+
## Chart Type Selection
|
|
84
56
|
|
|
85
57
|
### Decision Tree
|
|
86
58
|
|
|
@@ -96,315 +68,237 @@ START: What is the primary analysis goal?
|
|
|
96
68
|
└─→ 2-7 categories → VERTICAL BAR
|
|
97
69
|
└─→ 8-15 categories → HORIZONTAL BAR
|
|
98
70
|
└─→ 15+ categories → TOP N + "Other"
|
|
99
|
-
└─→ Multiple dimensions → GROUPED BAR
|
|
100
71
|
|
|
101
72
|
3. SHOWING DISTRIBUTION?
|
|
102
73
|
└─→ Continuous data → HISTOGRAM
|
|
103
74
|
└─→ Categorical → BAR (sorted)
|
|
104
|
-
└─→ Compare groups → BOX PLOT
|
|
105
75
|
|
|
106
76
|
4. PARTS OF A WHOLE?
|
|
107
77
|
└─→ 2-6 parts → PIE/DONUT
|
|
108
|
-
└─→ 7+ parts → STACKED BAR
|
|
78
|
+
└─→ 7+ parts → STACKED BAR
|
|
109
79
|
|
|
110
80
|
5. RELATIONSHIP BETWEEN VARIABLES?
|
|
111
81
|
└─→ Two numeric → SCATTER PLOT
|
|
112
|
-
└─→ With grouping → SCATTER with colors
|
|
113
|
-
|
|
114
|
-
DEFAULT: TABLE (when visualization unclear)
|
|
115
82
|
```
|
|
116
83
|
|
|
117
|
-
##
|
|
84
|
+
## Plotly Templates
|
|
118
85
|
|
|
119
86
|
### Bar Chart
|
|
120
87
|
```javascript
|
|
121
88
|
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
89
|
+
"data": [{
|
|
90
|
+
"x": ["Category A", "Category B", "Category C"],
|
|
91
|
+
"y": [450000, 380000, 290000],
|
|
92
|
+
"type": "bar",
|
|
93
|
+
"marker": {
|
|
94
|
+
"color": ["#4F46E5", "#7C3AED", "#A78BFA"]
|
|
95
|
+
},
|
|
96
|
+
"text": ["$450K", "$380K", "$290K"],
|
|
97
|
+
"textposition": "auto"
|
|
98
|
+
}],
|
|
99
|
+
"layout": {
|
|
100
|
+
"title": "Sales by Category",
|
|
101
|
+
"xaxis": { "title": "Category" },
|
|
102
|
+
"yaxis": { "title": "Sales ($)", "tickformat": "$,.0f" }
|
|
134
103
|
}
|
|
135
104
|
}
|
|
136
105
|
```
|
|
137
106
|
|
|
138
|
-
###
|
|
107
|
+
### Horizontal Bar (many categories)
|
|
139
108
|
```javascript
|
|
140
109
|
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
110
|
+
"data": [{
|
|
111
|
+
"y": ["Product A", "Product B", "Product C", "Product D", "Product E"],
|
|
112
|
+
"x": [85000, 72000, 65000, 58000, 45000],
|
|
113
|
+
"type": "bar",
|
|
114
|
+
"orientation": "h",
|
|
115
|
+
"marker": { "color": "#4F46E5" }
|
|
116
|
+
}],
|
|
117
|
+
"layout": {
|
|
118
|
+
"title": "Top Products by Revenue",
|
|
119
|
+
"xaxis": { "title": "Revenue ($)", "tickformat": "$,.0f" },
|
|
120
|
+
"margin": { "l": 120 }
|
|
150
121
|
}
|
|
151
122
|
}
|
|
152
123
|
```
|
|
153
124
|
|
|
154
|
-
###
|
|
125
|
+
### Line Chart (time series)
|
|
155
126
|
```javascript
|
|
156
127
|
{
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
128
|
+
"data": [{
|
|
129
|
+
"x": ["2024-01", "2024-02", "2024-03", "2024-04", "2024-05", "2024-06"],
|
|
130
|
+
"y": [120000, 135000, 128000, 145000, 160000, 175000],
|
|
131
|
+
"type": "scatter",
|
|
132
|
+
"mode": "lines+markers",
|
|
133
|
+
"line": { "color": "#4F46E5", "width": 3 },
|
|
134
|
+
"marker": { "size": 8 }
|
|
135
|
+
}],
|
|
136
|
+
"layout": {
|
|
137
|
+
"title": "Monthly Revenue Trend",
|
|
138
|
+
"xaxis": { "title": "Month" },
|
|
139
|
+
"yaxis": { "title": "Revenue ($)", "tickformat": "$,.0f" }
|
|
164
140
|
}
|
|
165
141
|
}
|
|
166
142
|
```
|
|
167
143
|
|
|
168
|
-
###
|
|
144
|
+
### Multi-Line Chart
|
|
169
145
|
```javascript
|
|
170
146
|
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
147
|
+
"data": [
|
|
148
|
+
{
|
|
149
|
+
"x": ["Jan", "Feb", "Mar", "Apr"],
|
|
150
|
+
"y": [100, 120, 115, 140],
|
|
151
|
+
"name": "Product A",
|
|
152
|
+
"type": "scatter",
|
|
153
|
+
"mode": "lines+markers"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"x": ["Jan", "Feb", "Mar", "Apr"],
|
|
157
|
+
"y": [80, 95, 110, 120],
|
|
158
|
+
"name": "Product B",
|
|
159
|
+
"type": "scatter",
|
|
160
|
+
"mode": "lines+markers"
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
"layout": {
|
|
164
|
+
"title": "Product Comparison",
|
|
165
|
+
"xaxis": { "title": "Month" },
|
|
166
|
+
"yaxis": { "title": "Sales" }
|
|
178
167
|
}
|
|
179
168
|
}
|
|
180
169
|
```
|
|
181
170
|
|
|
182
|
-
###
|
|
171
|
+
### Pie/Donut Chart
|
|
183
172
|
```javascript
|
|
184
173
|
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
174
|
+
"data": [{
|
|
175
|
+
"labels": ["Technology", "Furniture", "Office Supplies"],
|
|
176
|
+
"values": [5471124, 4730801, 4144724],
|
|
177
|
+
"type": "pie",
|
|
178
|
+
"hole": 0.4,
|
|
179
|
+
"marker": {
|
|
180
|
+
"colors": ["#4F46E5", "#10B981", "#F59E0B"]
|
|
181
|
+
},
|
|
182
|
+
"textinfo": "label+percent"
|
|
183
|
+
}],
|
|
184
|
+
"layout": {
|
|
185
|
+
"title": "Sales Distribution by Category"
|
|
192
186
|
}
|
|
193
187
|
}
|
|
194
188
|
```
|
|
195
189
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
190
|
+
### Scatter Plot
|
|
191
|
+
```javascript
|
|
192
|
+
{
|
|
193
|
+
"data": [{
|
|
194
|
+
"x": [/* x values */],
|
|
195
|
+
"y": [/* y values */],
|
|
196
|
+
"mode": "markers",
|
|
197
|
+
"type": "scatter",
|
|
198
|
+
"marker": {
|
|
199
|
+
"size": 10,
|
|
200
|
+
"color": "#4F46E5",
|
|
201
|
+
"opacity": 0.7
|
|
202
|
+
}
|
|
203
|
+
}],
|
|
204
|
+
"layout": {
|
|
205
|
+
"title": "Correlation Analysis",
|
|
206
|
+
"xaxis": { "title": "Variable X" },
|
|
207
|
+
"yaxis": { "title": "Variable Y" }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
216
210
|
```
|
|
217
211
|
|
|
218
|
-
###
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
212
|
+
### Grouped Bar Chart
|
|
213
|
+
```javascript
|
|
214
|
+
{
|
|
215
|
+
"data": [
|
|
216
|
+
{
|
|
217
|
+
"x": ["Q1", "Q2", "Q3", "Q4"],
|
|
218
|
+
"y": [120, 150, 180, 200],
|
|
219
|
+
"name": "2023",
|
|
220
|
+
"type": "bar"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"x": ["Q1", "Q2", "Q3", "Q4"],
|
|
224
|
+
"y": [140, 165, 195, 220],
|
|
225
|
+
"name": "2024",
|
|
226
|
+
"type": "bar"
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"layout": {
|
|
230
|
+
"title": "Year over Year Comparison",
|
|
231
|
+
"barmode": "group"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
238
234
|
```
|
|
239
235
|
|
|
240
|
-
|
|
241
|
-
```python
|
|
242
|
-
import matplotlib.pyplot as plt
|
|
236
|
+
## Color Palettes
|
|
243
237
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
238
|
+
```javascript
|
|
239
|
+
// Primary (single series)
|
|
240
|
+
const PRIMARY = '#4F46E5';
|
|
247
241
|
|
|
248
|
-
|
|
249
|
-
|
|
242
|
+
// Categorical (multiple series)
|
|
243
|
+
const CATEGORICAL = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16'];
|
|
250
244
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
ax.invert_yaxis() # Largest at top
|
|
254
|
-
ax.spines['top'].set_visible(False)
|
|
255
|
-
ax.spines['right'].set_visible(False)
|
|
245
|
+
// Sequential (gradient)
|
|
246
|
+
const SEQUENTIAL = ['#E0E7FF', '#A5B4FC', '#818CF8', '#6366F1', '#4F46E5', '#4338CA', '#3730A3'];
|
|
256
247
|
|
|
257
|
-
|
|
258
|
-
|
|
248
|
+
// Diverging (positive/negative)
|
|
249
|
+
const DIVERGING_NEG = '#EF4444';
|
|
250
|
+
const DIVERGING_POS = '#10B981';
|
|
259
251
|
```
|
|
260
252
|
|
|
261
|
-
##
|
|
262
|
-
|
|
263
|
-
### Horizontal Bar (ASCII)
|
|
264
|
-
```
|
|
265
|
-
def ascii_bar_chart(data, title, max_width=40):
|
|
266
|
-
"""Generate ASCII horizontal bar chart"""
|
|
267
|
-
print(f"\n{title}\n")
|
|
268
|
-
max_val = max(data.values())
|
|
253
|
+
## Number Formatting
|
|
269
254
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
255
|
+
```javascript
|
|
256
|
+
// Currency
|
|
257
|
+
tickformat: '$,.0f' // $1,234,567
|
|
258
|
+
tickformat: '$,.2f' // $1,234,567.89
|
|
259
|
+
tickformat: '$~s' // $1.2M
|
|
274
260
|
|
|
275
|
-
|
|
261
|
+
// Percentages
|
|
262
|
+
tickformat: '.1%' // 45.2%
|
|
276
263
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
ascii_bar_chart(data, "Revenue by Category")
|
|
264
|
+
// Large numbers
|
|
265
|
+
tickformat: '~s' // 1.2M, 3.4K
|
|
280
266
|
```
|
|
281
267
|
|
|
282
|
-
|
|
283
|
-
```
|
|
284
|
-
Revenue by Category
|
|
268
|
+
## MCP UI Resource Format
|
|
285
269
|
|
|
286
|
-
|
|
287
|
-
Clothing |████████████████████████████ 32,000
|
|
288
|
-
Home |████████████████████████ 28,000
|
|
289
|
-
────────────────────────────────────────
|
|
290
|
-
```
|
|
270
|
+
The chart should be returned as an MCP UI resource with the following structure:
|
|
291
271
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
for value in data.values():
|
|
302
|
-
threshold = (row / height) * max_val
|
|
303
|
-
line += " █ " if value >= threshold else " "
|
|
304
|
-
print(f"{int(max_val * row / height):>6} |{line}")
|
|
305
|
-
|
|
306
|
-
print(f"{'':>6} +{'─────' * len(data)}")
|
|
307
|
-
labels = "".join(f"{k:^5}" for k in data.keys())
|
|
308
|
-
print(f"{'':>8}{labels}")
|
|
309
|
-
|
|
310
|
-
# Example
|
|
311
|
-
data = {'Q1': 120, 'Q2': 150, 'Q3': 180, 'Q4': 200}
|
|
312
|
-
ascii_vertical_bar(data, "Quarterly Revenue")
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Sparkline (ASCII)
|
|
316
|
-
```
|
|
317
|
-
def ascii_sparkline(values, width=30):
|
|
318
|
-
"""Generate inline ASCII sparkline"""
|
|
319
|
-
chars = '▁▂▃▄▅▆▇█'
|
|
320
|
-
min_val, max_val = min(values), max(values)
|
|
321
|
-
range_val = max_val - min_val or 1
|
|
322
|
-
|
|
323
|
-
line = ""
|
|
324
|
-
for v in values:
|
|
325
|
-
idx = int((v - min_val) / range_val * (len(chars) - 1))
|
|
326
|
-
line += chars[idx]
|
|
327
|
-
|
|
328
|
-
return f"[{line}] {values[0]:,.0f} → {values[-1]:,.0f}"
|
|
329
|
-
|
|
330
|
-
# Example
|
|
331
|
-
monthly = [100, 105, 98, 112, 120, 118, 125, 130, 128, 140, 145, 155]
|
|
332
|
-
print(f"Revenue trend: {ascii_sparkline(monthly)}")
|
|
333
|
-
# Output: Revenue trend: [▁▂▁▃▄▄▅▆▅▇▇█] 100 → 155
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"type": "chart",
|
|
275
|
+
"title": "Chart Title",
|
|
276
|
+
"plotly": {
|
|
277
|
+
"data": [/* Plotly data traces */],
|
|
278
|
+
"layout": {/* Plotly layout config */}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
334
281
|
```
|
|
335
282
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
1. **Analyze data shape**:
|
|
339
|
-
- Count rows and columns
|
|
340
|
-
- Identify column types (numeric, categorical, date)
|
|
341
|
-
- Check value distributions
|
|
342
|
-
|
|
343
|
-
2. **Determine visualization goal**:
|
|
344
|
-
- Parse user question for intent
|
|
345
|
-
- Consider data characteristics
|
|
346
|
-
|
|
347
|
-
3. **Select chart type**:
|
|
348
|
-
- Apply decision tree
|
|
349
|
-
- Consider data density and readability
|
|
350
|
-
|
|
351
|
-
4. **Choose output format**:
|
|
352
|
-
- Default: QuickChart URL (instant rendering)
|
|
353
|
-
- If user needs customization: matplotlib code
|
|
354
|
-
- If terminal-only: ASCII chart
|
|
355
|
-
|
|
356
|
-
5. **Generate and present**:
|
|
357
|
-
- Show chart or URL
|
|
358
|
-
- Include rationale
|
|
359
|
-
- Suggest alternatives
|
|
360
|
-
|
|
361
|
-
## Output Format
|
|
362
|
-
|
|
363
|
-
```markdown
|
|
364
|
-
## Visualization: [Data Description]
|
|
365
|
-
|
|
366
|
-
### Analysis
|
|
367
|
-
- Data: [rows] rows, [columns] columns
|
|
368
|
-
- Question type: [trend/comparison/distribution/etc.]
|
|
369
|
-
- Key columns: [list]
|
|
283
|
+
This is automatically rendered by Claude Code when you include the resource block in your response.
|
|
370
284
|
|
|
371
|
-
|
|
372
|
-
**Why**: [Brief rationale]
|
|
285
|
+
## Alternative Outputs
|
|
373
286
|
|
|
374
|
-
###
|
|
375
|
-
|
|
376
|
-
**QuickChart URL** (click to view):
|
|
377
|
-
[URL]
|
|
378
|
-
|
|
379
|
-
**Alternative: Matplotlib Code**
|
|
380
|
-
```python
|
|
381
|
-
[Code block]
|
|
287
|
+
### QuickChart URL (for sharing/embedding)
|
|
288
|
+
When user specifically needs a URL:
|
|
382
289
|
```
|
|
383
|
-
|
|
384
|
-
**Alternative: ASCII Preview**
|
|
385
|
-
```
|
|
386
|
-
[ASCII chart]
|
|
290
|
+
https://quickchart.io/chart?c={type:'bar',data:{labels:['A','B','C'],datasets:[{data:[10,20,15]}]}}
|
|
387
291
|
```
|
|
388
292
|
|
|
389
|
-
###
|
|
390
|
-
|
|
391
|
-
- [Alternative chart 2]: [When it might be better]
|
|
293
|
+
### ASCII Chart (terminal only)
|
|
294
|
+
When user is in a terminal-only environment:
|
|
392
295
|
```
|
|
296
|
+
Sales by Category
|
|
393
297
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
PRIMARY = '#4F46E5' # Indigo
|
|
399
|
-
|
|
400
|
-
# Categorical (multiple series)
|
|
401
|
-
CATEGORICAL = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899']
|
|
402
|
-
|
|
403
|
-
# Sequential (single metric, gradient)
|
|
404
|
-
SEQUENTIAL = ['#E0E7FF', '#A5B4FC', '#818CF8', '#6366F1', '#4F46E5']
|
|
405
|
-
|
|
406
|
-
# Diverging (positive/negative)
|
|
407
|
-
DIVERGING = ['#EF4444', '#FCA5A5', '#E5E7EB', '#86EFAC', '#22C55E']
|
|
298
|
+
Technology |████████████████████████████████████████ $5.47M
|
|
299
|
+
Furniture |██████████████████████████████████ $4.73M
|
|
300
|
+
Office Supplies |██████████████████████████████ $4.14M
|
|
301
|
+
0 $3M $6M
|
|
408
302
|
```
|
|
409
303
|
|
|
410
304
|
## Integration
|