Floating bars start and end wherever the data says, not at zero: here, four people’s working hours on one day, from John’s 8:00 start to Eaton’s 19:00 finish.
Floating bars show spans: a shift from start to finish, a price from low to high, a stage of a project from one date to the next. Where bars overlap, as Joe’s and Susan’s do, they show who is at work at the same time. For many tasks with dates and links between them, a Gantt chart does more.
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: false, // no panning: a drag over the plot zooms instead
panY: false,
wheelX: "panX", // a horizontal wheel or trackpad swipe pans...
wheelY: "zoomX", // ...and the vertical wheel zooms in on the hours
layout: root.verticalLayout,
paddingLeft:0 // the names sit at the chart's left edge
}));
// Add cursor: drag across the plot to zoom in on a few hours
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
behavior: "zoomX"
}));
cursor.lineY.set("visible", false); // no horizontal cursor line
var colors = chart.get("colors");
// Data
var data = [{
name: "John",
startTime: 8,
endTime: 11,
columnSettings: {
stroke: colors.getIndex(1),
fill: colors.getIndex(1)
}
}, {
name: "Joe",
startTime: 10,
endTime: 13,
columnSettings: {
stroke: colors.getIndex(3),
fill: colors.getIndex(3)
}
}, {
name: "Susan",
startTime: 11,
endTime: 18,
columnSettings: {
stroke: colors.getIndex(5),
fill: colors.getIndex(5)
}
}, {
name: "Eaton",
startTime: 15,
endTime: 19,
columnSettings: {
stroke: colors.getIndex(7),
fill: colors.getIndex(7)
}
}];
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var yRenderer = am5xy.AxisRendererY.new(root, {
minorGridEnabled: true // a skipped name would still get a faint grid line
});
var yAxis = chart.yAxes.push(
am5xy.CategoryAxis.new(root, {
categoryField: "name",
renderer: yRenderer,
tooltip: am5.Tooltip.new(root, {}) // shows the hovered name on the axis
})
);
yRenderer.grid.template.setAll({
location: 1 // grid lines at the end of each name's row, between the bars
})
yAxis.data.setAll(data);
// The values are hours of the day, shown as 8:00, 9:00 and so on
var xAxis = chart.xAxes.push(
am5xy.ValueAxis.new(root, {
numberFormat: "#':00'",
renderer: am5xy.AxisRendererX.new(root, {
strokeOpacity: 0.1, // a faint line along the hour axis
minGridDistance:60 // at least 60px between hour labels
})
})
);
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Shifts",
xAxis: xAxis,
yAxis: yAxis,
// each bar starts at its startTime instead of at zero
openValueXField: "startTime",
valueXField: "endTime",
categoryYField: "name",
sequencedInterpolation: true // on load, the bars grow one after another
}));
series.columns.template.setAll({
height: am5.percent(100), // each bar fills its row's full height
// each bar's fill and stroke come from columnSettings in its data row
templateField: "columnSettings",
tooltipText: "[bold]{categoryY}[/]: {openValueX}:00 to {valueX}:00" // as "John: 8:00 to 11:00"
});
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
chart.appear(1000, 100);
{
"type": "XYChart",
"settings": {
"panX": false,
"panY": false,
"wheelX": "panX",
"wheelY": "zoomX",
"layout": {
"type": "VerticalLayout"
},
"paddingLeft": 0,
"cursor": {
"type": "XYCursor",
"settings": {
"behavior": "zoomX"
},
"properties": {
"lineY": {
"settings": {
"visible": false
}
}
}
}
},
"properties": {
"series": [
"#series-0"
],
"xAxes": [
"#axis-0"
],
"yAxes": [
"#axis-1"
]
},
"refs": [
{
"data-0": [
{
"name": "John",
"startTime": 8,
"endTime": 11,
"columnSettings": {
"stroke": {
"type": "Color",
"value": "#6350a6"
},
"fill": {
"type": "Color",
"value": "#6350a6"
},
"__parse": true
},
"__parse": true
},
{
"name": "Joe",
"startTime": 10,
"endTime": 13,
"columnSettings": {
"stroke": {
"type": "Color",
"value": "#9c539d"
},
"fill": {
"type": "Color",
"value": "#9c539d"
},
"__parse": true
},
"__parse": true
},
{
"name": "Susan",
"startTime": 11,
"endTime": 18,
"columnSettings": {
"stroke": {
"type": "Color",
"value": "#c95d7d"
},
"fill": {
"type": "Color",
"value": "#c95d7d"
},
"__parse": true
},
"__parse": true
},
{
"name": "Eaton",
"startTime": 15,
"endTime": 19,
"columnSettings": {
"stroke": {
"type": "Color",
"value": "#e3764f"
},
"fill": {
"type": "Color",
"value": "#e3764f"
},
"__parse": true
},
"__parse": true
}
]
},
{
"axis-0": {
"type": "ValueAxis",
"settings": {
"numberFormat": "##':00'",
"renderer": {
"type": "AxisRendererX",
"settings": {
"strokeOpacity": 0.1,
"minGridDistance": 60
}
}
}
}
},
{
"axis-1": {
"type": "CategoryAxis",
"settings": {
"categoryField": "name",
"renderer": {
"type": "AxisRendererY",
"settings": {
"minorGridEnabled": true
},
"properties": {
"grid": {
"properties": {
"template": {
"settings": {
"location": 1
}
}
}
}
}
},
"tooltip": {
"type": "Tooltip"
}
},
"properties": {
"data": "#data-0"
}
}
},
{
"series-0": {
"type": "ColumnSeries",
"settings": {
"name": "Shifts",
"xAxis": "#axis-0",
"yAxis": "#axis-1",
"openValueXField": "startTime",
"valueXField": "endTime",
"categoryYField": "name",
"sequencedInterpolation": true
},
"properties": {
"data": "#data-0",
"columns": {
"properties": {
"template": {
"settings": {
"height": {
"type": "Percent",
"value": 100
},
"templateField": "columnSettings",
"tooltipText": "[bold]{categoryY}[/]: {openValueX}:00 to {valueX}:00"
}
}
}
}
}
}
}
]
}