Overview
The JSON plugin allows you to create entire chart configurations from JSON or JavaScript objects. This enables dynamic chart generation, serialization, and configuration-based chart creation without writing explicit code for every chart element.
Installation
Import the JsonParser class from the plugins module:
import * as am5 from "@amcharts/amcharts5";
import { JsonParser } from "@amcharts/amcharts5/plugins/json";
Basic Usage
Creating a Chart from JSON
Create charts by parsing JSON configuration:
let root = am5.Root.new("chartdiv");
// Create parser
let parser = JsonParser.new(root);
// Define chart configuration
let config = {
type: "XYChart",
settings: {
paddingLeft: 0,
paddingRight: 0
},
children: [
{
type: "CategoryAxis",
settings: {
categoryField: "category",
renderer: {
type: "AxisRendererX"
}
}
},
{
type: "ValueAxis",
settings: {
renderer: {
type: "AxisRendererY"
}
}
}
]
};
// Parse and create chart
parser.parse(config).then((chart) => {
root.container.children.push(chart);
});
Parsing JSON Strings
Parse JSON strings directly:
let jsonString = JSON.stringify(config);
parser.parseString(jsonString).then((chart) => {
root.container.children.push(chart);
});
Configuration Structure
Each chart element is defined with type, settings, and optional properties:
{
"type": "ClassName",
"settings": {
"property1": "value1",
"property2": "value2"
},
"properties": {},
"children": [],
"states": [],
"adapters": []
}
Class name of the amCharts element (e.g., “XYChart”, “LineSeries”, “ValueAxis”)
Initial settings for the element
Additional properties to set after creation
Child elements (for containers)
State definitions for the element
Adapter functions for dynamic value modification
Complete Chart Example
Here’s a complete XY chart with series and data:
let config = {
type: "XYChart",
settings: {
panX: true,
panY: true,
wheelX: "panX",
wheelY: "zoomX"
},
children: [
{
type: "CategoryAxis",
settings: {
categoryField: "category",
renderer: {
type: "AxisRendererX",
settings: {
minGridDistance: 30
}
}
}
},
{
type: "ValueAxis",
settings: {
renderer: {
type: "AxisRendererY"
}
}
}
],
properties: {
series: [
{
type: "ColumnSeries",
settings: {
name: "Series 1",
xAxis: "#xAxis",
yAxis: "#yAxis",
valueYField: "value",
categoryXField: "category"
},
properties: {
data: [
{ category: "A", value: 100 },
{ category: "B", value: 200 },
{ category: "C", value: 150 }
]
}
}
]
},
refs: {
"xAxis": "#children.0",
"yAxis": "#children.1"
}
};
References
Using References
Reference other elements in your configuration using refs and the # prefix:
let config = {
refs: {
"myAxis": {
type: "ValueAxis",
settings: {
renderer: {
type: "AxisRendererY"
}
}
}
},
properties: {
series: [
{
type: "LineSeries",
settings: {
yAxis: "#myAxis", // Reference to myAxis
valueYField: "value"
}
}
]
}
};
Reference Syntax
Reference an element defined in refs object
Access a property of a referenced element
Get a setting value from a referenced element
Escape # to use literal hash symbol (becomes #literal)
Colors and Special Types
Color Values
Define colors using the Color type:
{
"settings": {
"fill": {
"type": "Color",
"value": "#ff0000"
},
"stroke": {
"type": "Color",
"value": 16711680
}
}
}
Percent Values
Define percentage values:
{
"settings": {
"width": {
"type": "Percent",
"value": 80
}
}
}
Gradients
Define linear gradients:
{
"settings": {
"fillGradient": {
"type": "LinearGradient",
"settings": {
"stops": [
{ "color": { "type": "Color", "value": "#ff0000" }, "offset": 0 },
{ "color": { "type": "Color", "value": "#0000ff" }, "offset": 1 }
]
}
}
}
}
States
Define visual states for elements:
let config = {
type: "RoundedRectangle",
settings: {
width: 100,
height: 50,
fill: am5.color(0x0000ff)
},
states: [
{
key: "hover",
settings: {
fill: am5.color(0xff0000)
}
},
{
key: "active",
settings: {
fill: am5.color(0x00ff00)
}
}
]
};
Adapters
Add dynamic value modification with adapters:
let config = {
type: "ColumnSeries",
settings: {
valueYField: "value",
categoryXField: "category"
},
adapters: [
{
key: "fill",
callback: function(fill, target) {
// Dynamically set fill based on value
if (target.dataItem.get("valueY") > 100) {
return am5.color(0x00ff00);
}
return fill;
}
}
]
};
Adapter callbacks must be provided as actual JavaScript functions, not JSON strings.
Templates
Define reusable templates:
let config = {
type: "LineSeries",
settings: {
valueYField: "value",
bullets: [
function() {
return am5.Bullet.new(root, {
sprite: {
type: "Circle",
settings: {
radius: 5,
fill: am5.color(0xff0000)
}
}
});
}
]
}
};
Parent Container
Parse directly into a parent container:
parser.parse(config, {
parent: root.container
}).then((chart) => {
console.log("Chart created and added to container");
});
Use Cases
Configuration-Based Charts
Store chart configurations in a database and generate charts dynamically:
// Fetch config from API
fetch('/api/chart-config')
.then(response => response.json())
.then(config => {
return parser.parse(config);
})
.then(chart => {
root.container.children.push(chart);
});
Chart Serialization
Combine with the Serializer plugin to save and restore chart states:
import { Serializer } from "@amcharts/amcharts5/plugins/json";
// Serialize existing chart
let serializer = Serializer.new(root);
let serialized = serializer.serialize(chart);
// Later, restore the chart
parser.parse(serialized).then((restoredChart) => {
root.container.children.push(restoredChart);
});
Dynamic Chart Generation
Generate different chart types based on user selection:
function createChart(type) {
let config = {
type: type, // "XYChart", "PieChart", etc.
settings: getDefaultSettings(type),
children: getDefaultChildren(type)
};
return parser.parse(config);
}
Error Handling
Handle parsing errors gracefully:
parser.parse(config)
.then((chart) => {
console.log("Chart created successfully");
})
.catch((error) => {
console.error("Failed to parse chart:", error);
});
Limitations
Function callbacks (adapters, bullets, etc.) cannot be serialized as JSON strings. They must be provided as actual JavaScript functions.
Not all chart features can be configured through JSON. Complex interactions may require programmatic setup.
Parsing is asynchronous to allow for dynamic class loading. Always use .then() or await to handle the result.
For frequently used configurations, consider caching parsed results instead of re-parsing each time.
See Also