A line chart that draws the eye to its latest value: the last point pulses like a live signal, while the dashed line keeps the history in the background.
Movement catches the eye, so one pulsing point says "look here" without a label. It suits numbers that update, like a price or a sensor reading, where the newest value matters most.
Built with amCharts 5, a JavaScript library. The JavaScript includes your theme and renderer (canvas or SVG); the JSON also follows the changes you make with the controls.
npm install @amcharts/amcharts5. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code."type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root),
am5themes_Responsive.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: true, // drag the plot sideways to pan
panY: true, // ...or up and down
wheelX: "panX", // a horizontal wheel or trackpad swipe pans
wheelY: "zoomX", // the vertical wheel zooms in on the dates
pinchZoomX:true, // pinch to zoom on touch screens
paddingLeft: 0 // the value labels sit at the chart's left edge
}));
// Add cursor
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {}));
cursor.lineY.set("visible", false); // no horizontal cursor line, only the vertical one
// Add scrollbar, hidden at first
// https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/
chart.set("scrollbarX", am5.Scrollbar.new(root, { orientation: "horizontal", forceHidden: true }));
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
// the chart can be panned up to 30% past the ends of the data
maxDeviation: 0.3,
baseInterval: { // one data point per day
timeUnit: "day",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {
minorGridEnabled: true, // fainter grid lines between the labeled dates
minGridDistance: 70 // at least 70px between labels; on narrow screens some are skipped
}),
tooltip: am5.Tooltip.new(root, {}) // the cursor shows the date on the axis
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
maxDeviation: 0.3, // the values can be panned up to 30% past their range too
renderer: am5xy.AxisRendererY.new(root, {})
}));
// Create series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.LineSeries.new(root, {
name: "Series 1",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value",
valueXField: "date",
tooltip: am5.Tooltip.new(root, {
labelText: "{valueY}" // the hovered day's value
})
}));
series.strokes.template.setAll({
strokeWidth: 2, // a 2px line...
strokeDasharray: [3, 3] // ...dashed: 3px dash, 3px gap
});
// Create animating bullet by adding two circles in a bullet container and
// animating radius and opacity of one of them.
series.bullets.push(function(root, series, dataItem) {
// only the data item marked "bullet: true" (the last point) gets one
if (dataItem.dataContext.bullet) {
var container = am5.Container.new(root, {});
var circle0 = container.children.push(am5.Circle.new(root, {
radius: 5, // a 5px red dot that stays put
fill: am5.color(0xff0000)
}));
// a second dot on top of it, which grows and fades out
var circle1 = container.children.push(am5.Circle.new(root, {
radius: 5,
fill: am5.color(0xff0000)
}));
circle1.animate({
key: "radius",
to: 20, // grows to a 20px radius...
duration: 1000, // ...in one second
easing: am5.ease.out(am5.ease.cubic), // fast at first, slowing down
loops: Infinity // over and over
});
circle1.animate({
key: "opacity",
to: 0, // ...while fading out
from: 1,
duration: 1000,
easing: am5.ease.out(am5.ease.cubic),
loops: Infinity
});
return am5.Bullet.new(root, {
sprite: container
})
}
})
// Set data
var data = [{
date: new Date(2025, 5, 12).getTime(),
value: 50
}, {
date: new Date(2025, 5, 13).getTime(),
value: 53
}, {
date: new Date(2025, 5, 14).getTime(),
value: 56
}, {
date: new Date(2025, 5, 15).getTime(),
value: 52
}, {
date: new Date(2025, 5, 16).getTime(),
value: 48
}, {
date: new Date(2025, 5, 17).getTime(),
value: 47
}, {
date: new Date(2025, 5, 18).getTime(),
value: 59,
bullet: true
}]
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear(1000);
chart.appear(1000, 100);
{
"type": "XYChart",
"settings": {
"panX": true,
"panY": true,
"wheelX": "panX",
"wheelY": "zoomX",
"pinchZoomX": true,
"paddingLeft": 0,
"cursor": {
"type": "XYCursor",
"properties": {
"lineY": {
"settings": {
"visible": false
}
}
}
},
"scrollbarX": {
"type": "Scrollbar",
"settings": {
"orientation": "horizontal",
"forceHidden": true
}
}
},
"properties": {
"series": [
"#series-0"
],
"xAxes": [
"#axis-0"
],
"yAxes": [
"#axis-1"
]
},
"refs": [
{
"data-0": [
{
"date": 1749675600000,
"value": 50
},
{
"date": 1749762000000,
"value": 53
},
{
"date": 1749848400000,
"value": 56
},
{
"date": 1749934800000,
"value": 52
},
{
"date": 1750021200000,
"value": 48
},
{
"date": 1750107600000,
"value": 47
},
{
"date": 1750194000000,
"value": 59,
"bullet": true
}
]
},
{
"axis-0": {
"type": "DateAxis",
"settings": {
"maxDeviation": 0.3,
"baseInterval": {
"timeUnit": "day",
"count": 1
},
"renderer": {
"type": "AxisRendererX",
"settings": {
"minorGridEnabled": true,
"minGridDistance": 70
}
},
"tooltip": {
"type": "Tooltip"
}
}
}
},
{
"axis-1": {
"type": "ValueAxis",
"settings": {
"maxDeviation": 0.3,
"renderer": {
"type": "AxisRendererY"
}
}
}
},
{
"series-0": {
"type": "LineSeries",
"settings": {
"name": "Series 1",
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"valueYField": "value",
"valueXField": "date",
"tooltip": {
"type": "Tooltip",
"settings": {
"labelText": "{valueY}"
}
}
},
"properties": {
"data": "#data-0",
"strokes": {
"properties": {
"template": {
"settings": {
"strokeWidth": 2,
"strokeDasharray": [
3,
3
]
}
}
}
}
}
}
}
]
}