| Crates.io | chartjs_image |
| lib.rs | chartjs_image |
| version | 6.1.13 |
| created_at | 2025-12-29 15:09:48.353663+00 |
| updated_at | 2026-01-19 11:43:42.430504+00 |
| description | Render Chart.JS as Image (or URL of Image) |
| homepage | https://www.image-charts.com/ |
| repository | https://github.com/image-charts/chartjs-image-rust |
| max_upload_size | |
| id | 2010724 |
| size | 177,551 |
Generate Chart.JS charts as image and embed them everywhere in emails, pdf reports, chat bots...!
Requirements: Rust 1.65+
Add to your Cargo.toml:
[dependencies]
chartjs_image = "6"
async (default): Enables async methods (to_buffer(), to_file(), to_data_uri())blocking: Enables blocking/sync methods (to_buffer_blocking(), to_file_blocking(), to_data_uri_blocking())full: Enables both async and blocking# Async only (default)
chartjs_image = "6"
# Blocking only
chartjs_image = { version = "6", default-features = false, features = ["blocking"] }
# Both async and blocking
chartjs_image = { version = "6", features = ["full"] }
use chartjs_image::ChartJSImage;
use chartjs_image::ChartJSImage;
fn main() {
let chart = ChartJSImage::new()
.chart(r#"{
"type": "pie",
"data": {
"labels": ["Red", "Blue", "Yellow"],
"datasets": [{
"data": [300, 50, 100]
}]
}
}"#)
.width("600")
.height("300");
// Get URL (sync, no HTTP request)
let url = chart.to_url();
println!("{}", url);
}
// Async example
use chartjs_image::ChartJSImage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let chart = ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Red","Blue"],"datasets":[{"data":[60,40]}]}}"#)
.width("600")
.height("300");
// Download as bytes
let buffer = chart.to_buffer().await?;
// Save to file
chart.to_file("chart.png").await?;
// Get as data URI
let data_uri = chart.to_data_uri().await?;
// data:image/png;base64,iVBORw0KGgo...
Ok(())
}
account_idCreate an instance with builder pattern. See usage
// Free usage - default configuration
let chart = ChartJSImage::new();
// Enterprise & Enterprise+ subscriptions
let chart = ChartJSImage::builder()
.secret("SECRET_KEY")
.build();
// With custom timeout
let chart = ChartJSImage::builder()
.secret("SECRET_KEY")
.timeout(std::time::Duration::from_secs(10))
.build();
// On-premise subscriptions
let chart = ChartJSImage::builder()
.protocol("https")
.host("custom-domain.tld")
.port(443)
.pathname("/chart.js/2.8.0")
.secret("SECRET_KEY")
.build();
to_url() -> StringGet the full Image-Charts API url (signed and encoded if necessary)
use chartjs_image::ChartJSImage;
fn main() {
let url = ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("300")
.to_url();
println!("{}", url);
}
to_buffer() -> Result<Vec<u8>, ChartJSImageError> (async)to_buffer_blocking() -> Result<Vec<u8>, ChartJSImageError> (blocking)Do a request to Image-Charts API with current configuration and yield image bytes
use chartjs_image::ChartJSImage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let buffer = ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("300")
.to_buffer()
.await?;
println!("Downloaded {} bytes", buffer.len());
Ok(())
}
use chartjs_image::ChartJSImage;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let buffer = ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("300")
.to_buffer_blocking()?;
println!("Downloaded {} bytes", buffer.len());
Ok(())
}
to_file(path) -> Result<(), ChartJSImageError> (async)to_file_blocking(path) -> Result<(), ChartJSImageError> (blocking)Download chart and save to file
use chartjs_image::ChartJSImage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("300")
.to_file("chart.png")
.await?;
println!("Chart saved!");
Ok(())
}
to_data_uri() -> Result<String, ChartJSImageError> (async)to_data_uri_blocking() -> Result<String, ChartJSImageError> (blocking)Do a request to Image-Charts API with current configuration and yield a base64 encoded data URI
use chartjs_image::ChartJSImage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let data_uri = ChartJSImage::new()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("100")
.height("100")
.to_data_uri()
.await?;
// Use in HTML: <img src="{data_uri}" />
println!("{}", &data_uri[..50]);
Ok(())
}
Image-Charts Enterprise and Enterprise+ subscriptions remove the watermark and enable advanced features like custom-domain, high-resolution charts, custom fonts, multiple axis and mixed charts.
Once subscribed to a plan you will receive an ACCOUNT_ID and a SECRET_KEY.
These two parameters are mandatory to sign your request and remove the watermark.
Replace both values in the code example below:
use chartjs_image::ChartJSImage;
fn main() {
let url = ChartJSImage::builder()
.secret("SECRET_KEY")
.build()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("190")
.icretina("1")
.icac("ACCOUNT_ID")
.to_url();
println!("{}", url);
}
Image-Charts virtual appliance can be deployed anywhere inside a customer network.
use chartjs_image::ChartJSImage;
fn main() {
let url = ChartJSImage::builder()
.host("custom-domain.tld")
.secret("SECRET_KEY")
.build()
.chart(r#"{"type":"pie","data":{"labels":["Hello","World"],"datasets":[{"data":[60,40]}]}}"#)
.width("700")
.height("190")
.icretina("1")
.icac("ACCOUNT_ID")
.to_url();
println!("{}", url);
// https://custom-domain.tld/chart.js/2.8.0?c=...&ichm=...
}
c( value ) -> ChartJSImageJavascript/JSON definition of the chart. Use a Chart.js configuration object.
.c("{type:'bar',data:{labels:['Q1','Q2','Q3','Q4'],datasets:[{label:'Users',data:[50,60,70,180]},{label:'Revenue',data:[100,200,300,400]}]}}")
chart( value ) -> ChartJSImageJavascript/JSON definition of the chart. Use a Chart.js configuration object.
.chart("{type:'bar',data:{labels:['Q1','Q2','Q3','Q4'],datasets:[{label:'Users',data:[50,60,70,180]},{label:'Revenue',data:[100,200,300,400]}]}}")
width( value ) -> ChartJSImageWidth of the chart
.width("400")
height( value ) -> ChartJSImageHeight of the chart
.height("300")
backgroundColor( value ) -> ChartJSImageBackground of the chart canvas. Accepts rgb (rgb(255,255,120)), colors (red), and url-encoded hex values (%23ff00ff). Abbreviated as "bkg"
.backgroundColor("black")
.backgroundColor("rgb(255,255,120)")
.backgroundColor("%23ff00ff")
bkg( value ) -> ChartJSImageBackground of the chart canvas. Accepts rgb (rgb(255,255,120)), colors (red), and url-encoded hex values (%23ff00ff). Abbreviated as "bkg"
.bkg("black")
.bkg("rgb(255,255,120)")
.bkg("%23ff00ff")
encoding( value ) -> ChartJSImageEncoding of your "chart" parameter. Accepted values are url and base64.
.encoding("url")
.encoding("base64")
icac( value ) -> ChartJSImageimage-charts enterprise
account_id
.icac("accountId")
ichm( value ) -> ChartJSImageHMAC-SHA256 signature required to activate paid features
.ichm("0785cf22a0381c2e0239e27c126de4181f501d117c2c81745611e9db928b0376")
icretina( value ) -> ChartJSImageretina mode
.icretina("0")
.icretina("1")