svgraph is a pure Duso module for generating scalable vector graphics (SVG) charts. Create beautiful, publication-quality charts directly from Duso scripts without external dependencies. Charts render to standalone SVG files that work in any browser or editor.
sg = require("svgraph")
// Generate a line chart
svg = sg.render({
type = "line",
title = "Temperature Over Week",
axis = ["Days", "Temperature (°F)"],
data = [65, 68, 72, 70, 75, 78, 76]
})
save("chart.svg", svg)
All charts are created with a single function: render(spec). The function takes a specification object and returns SVG markup as a string.
The spec parameter is an object with the following fields:
| Field | Required | Type | Description |
|---|---|---|---|
type |
Yes | string | Chart type: "line", "bar", "hbar", "scatter", "bubble", "area", "multi", or "donut" |
data |
Yes | array | Chart data (format depends on type) |
title |
No | string | Chart title displayed at top |
axis |
No | array | Axis labels [x_label, y_label] |
Plot values as a continuous line with markers at each point.
Data Format: Array of numbers
Use Cases: Time series, trends, continuous measurements
sg = require("svgraph")
line_chart = sg.render({
type = "line",
title = "Stock Price",
axis = ["Week", "Price ($)"],
data = [100, 105, 102, 110, 115, 120, 118]
})
save("stock.svg", line_chart)
Tips:
Display categorical data as vertical bars.
Data Format: Alternating label-value pairs: [label1, value1, label2, value2, ...]
Use Cases: Category comparisons, sales by quarter, discrete measurements
bar_chart = sg.render({
type = "bar",
title = "Sales by Quarter",
axis = ["Quarter", "Sales ($)"],
data = ["Q1", 100000, "Q2", 150000, "Q3", 120000, "Q4", 180000]
})
save("sales.svg", bar_chart)
Features:
Display categorical data as horizontal bars (useful for many categories or long labels).
Data Format: Alternating label-value pairs: [label1, value1, label2, value2, ...]
Use Cases: Project progress, survey results, rankings
hbar_chart = sg.render({
type = "hbar",
title = "Project Progress",
axis = ["Project", "% Complete"],
data = ["Frontend", 85, "Backend", 75, "Database", 90, "Testing", 60, "Docs", 45]
})
save("progress.svg", hbar_chart)
Display individual (x, y) points to reveal correlations and distributions.
Data Format: Alternating x-y pairs: [x1, y1, x2, y2, x3, y3, ...]
Use Cases: Correlation analysis, outlier detection, bivariate relationships
scatter = sg.render({
type = "scatter",
title = "Study Hours vs Grade",
axis = ["Hours Studied", "Grade (%)"],
data = [2, 55, 3, 60, 5, 75, 6, 85, 7, 82, 8, 90, 10, 95]
})
save("correlation.svg", scatter)
Features:
Like a line chart, but with the area under the line filled in.
Data Format: Array of numbers (same as line chart)
Use Cases: Cumulative values, stacked measurements, total amount over time
area_chart = sg.render({
type = "area",
title = "Cumulative Revenue",
axis = ["Month", "Total Revenue ($)"],
data = [10000, 25000, 18000, 35000, 42000]
})
save("revenue.svg", area_chart)
Features:
Scatter plot where bubble size represents a third dimension.
Data Format: Triplets of x, y, size: [x1, y1, size1, x2, y2, size2, ...]
Use Cases: Market analysis (price vs rating vs volume), portfolio analysis, multidimensional comparisons
bubble = sg.render({
type = "bubble",
title = "Product Market Analysis",
axis = ["Price ($)", "Customer Rating"],
data = [
10, 3.5, 100, // Product A: $10, 3.5 stars, 100 units
25, 4.2, 250, // Product B: $25, 4.2 stars, 250 units
15, 3.8, 180, // Product C: $15, 3.8 stars, 180 units
40, 4.7, 320 // Product D: $40, 4.7 stars, 320 units
]
})
save("products.svg", bubble)
Features:
Plot multiple series on the same chart for comparison.
Data Format: Array of arrays (one per series): [[series1_val1, series1_val2, ...], [series2_val1, ...], ...]
Use Cases: Multi-stock comparison, resource usage over time, multiple metrics
multi = sg.render({
type = "multi",
title = "Stock Price Comparison",
axis = ["Week", "Price ($)"],
data = [
[100, 105, 102, 110, 115, 120, 118], // Company A
[50, 52, 51, 55, 58, 62, 60], // Company B
[200, 198, 205, 210, 208, 215, 220] // Company C
]
})
save("stocks.svg", multi)
Requirements:
Color Scheme:
Pie-like chart showing proportions of a whole.
Data Format: Alternating label-value pairs: [label1, value1, label2, value2, ...]
Use Cases: Market share, budget allocation, traffic sources, composition analysis
donut = sg.render({
type = "donut",
title = "Market Share by Competitor",
data = [
"Company A", 35,
"Company B", 28,
"Company C", 22,
"Company D", 10,
"Others", 5
]
})
save("market.svg", donut)
Features:
svgraph works seamlessly with generated and transformed data:
sg = require("svgraph")
// Generate Fibonacci sequence
fib = []
a = 1
b = 1
for i = 1, 10 do
push(fib, a)
temp = a + b
a = b
b = temp
end
// Chart the generated data
chart = sg.render({
type = "line",
title = "Fibonacci Sequence",
axis = ["Position", "Value"],
data = fib
})
save("fibonacci.svg", chart)
Transform structured data into chart format:
sg = require("svgraph")
// Structured data
sales_data = [
{month = "Jan", revenue = 50000},
{month = "Feb", revenue = 65000},
{month = "Mar", revenue = 58000},
{month = "Apr", revenue = 75000},
{month = "May", revenue = 82000}
]
// Transform to flat array for bar chart
flat_data = []
for data_point in sales_data do
push(flat_data, data_point.month)
push(flat_data, data_point.revenue)
end
chart = sg.render({
type = "bar",
title = "Monthly Revenue",
axis = ["Month", "Revenue ($)"],
data = flat_data
})
save("revenue.svg", chart)
Generate multiple charts in a loop:
sg = require("svgraph")
periods = [
{name = "Q1", values = [10, 15, 12]},
{name = "Q2", values = [18, 22, 19]},
{name = "Q3", values = [25, 28, 24]},
{name = "Q4", values = [32, 35, 30]}
]
for period in periods do
chart = sg.render({
type = "line",
title = "Performance: " + period.name,
axis = ["Week", "Score"],
data = period.values
})
save("period_" + lower(period.name) + ".svg", chart)
print("Created: period_" + lower(period.name) + ".svg")
end
svgraph handles edge cases gracefully:
sg = require("svgraph")
// Single data point
single = sg.render({
type = "line",
title = "Single Value",
data = [42]
})
// Constant values (flat line)
flat = sg.render({
type = "line",
title = "Constant",
data = [50, 50, 50, 50, 50]
})
// Large numbers (auto-scales axes)
large = sg.render({
type = "bar",
title = "Large Numbers",
data = ["A", 1000000, "B", 2500000, "C", 1800000]
})
// Very small decimal numbers
small = sg.render({
type = "scatter",
title = "Precision",
axis = ["X", "Y"],
data = [0.001, 0.002, 0.003, 0.001, 0.005, 0.003]
})
All edge cases render correctly without special handling needed.
The render() function returns valid SVG markup. Save it directly to a file:
sg = require("svgraph")
svg = sg.render({type = "line", data = [1, 2, 3, 4, 5]})
save("chart.svg", svg)
SVG files are:
Default chart dimensions: 1200 × 800 pixels
The module is designed for standard web/print dimensions. Charts render with:
The module includes built-in styling with:
Current styling is fixed per chart type. For custom colors or dimensions, edit the source SVG after rendering or modify the module directly.
The module validates data and throws clear errors:
try
// Missing data field
sg.render({type = "line"})
catch (e)
print("Error: " + e) // "Error: Need: line|bar|..."
end
try
// Wrong data format for bar chart
sg.render({type = "bar", data = [1, 2, 3]})
catch (e)
print("Error: " + e) // "Error: Need label,value pairs"
end
try
// Bubble chart needs triplets
sg.render({type = "bubble", data = [1, 2, 3, 4]})
catch (e)
print("Error: " + e) // "Error: Need x,y,size triplets"
end
svgraph generates charts efficiently:
See the contrib/svgraph/examples/ directory for complete, runnable examples:
Run any example:
duso contrib/svgraph/examples/basic.du
Use svgraph in Claude-powered workflows to automatically visualize AI analysis:
claude = require("claude")
sg = require("svgraph")
// Claude analyzes data and returns numeric results
response = claude.prompt("Analyze these sales numbers...")
data = parse_json(response)
// Visualize the results
chart = sg.render({
type = "bar",
title = "Analysis Results",
data = data
})
save("analysis.svg", chart)
print("Visualization saved to analysis.svg")
Q: Can I customize colors and fonts?
A: The module uses fixed styling for simplicity. Modify contrib/svgraph/svgraph.du to customize the style() function.
Q: How many data points can I chart? A: Thousands of points work fine. For millions of points, consider aggregation.
Q: Can I embed the SVG in HTML?
A: Yes! Either embed the SVG directly or reference it: <img src="chart.svg"> or <embed src="chart.svg">
Q: What if my data has missing values? A: Pass valid numbers only. Use Claude or Duso functions to preprocess data and handle missing values before charting.
Q: Can I animate SVG charts?
A: SVG supports CSS animations. Edit the output SVG to add <style> tags with keyframes.