How to Create a Gantt Chart View in SharePoint Online Modern List Using JSON
If you're managing projects or tracking tasks in SharePoint Online, a Gantt Chart view can provide a visual timeline, making it easier to track progress and dependencies. While the classic SharePoint experience had a built-in Gantt Chart view, the modern experience requires some customization using JSON formatting.
Why Use a Gantt Chart in SharePoint Online?
A Gantt Chart helps teams:
? Visualize project timelines and deadlines
? Identify task dependencies
? Improve task tracking and resource planning
Since the modern SharePoint list doesn't support a Gantt view by default, we can achieve this by applying JSON formatting to a list.
Steps to Create a Gantt Chart View in SharePoint Online
1?? Set Up Your SharePoint List
First, create a SharePoint Online list with the following columns:
2?? Apply JSON Formatting for Gantt View
To transform your list into a Gantt-style visualization, navigate to:
?? Click on View → Format Current View → Advanced Mode
Here, paste the following JSON code:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json",
"hideSelection": true,
"hideColumnHeader": true,
"rowFormatter": {
"elmType": "div",
"style": {
"height": "=if(@rowIndex == 0, '88px', '52px')",
"display": "block",
"width": "100%",
"position": "sticky"
},
"attributes": {
"class": "ms-bgColor-neutralLighter--hover"
},
"children": [
{
"elmType": "div",
"attributes": {
"class": "ms-bgColor-themePrimary"
},
"style": {
"width": "100%",
"display": "=if(@rowIndex == 0, 'flex', 'none')",
"height": "36px",
"padding": "0",
"font-weight": "bold",
"border-radius": "6px 6px 0 0"
},
"children": [
{
"elmType": "div",
"txtContent": "Milestone Chart",
"style": {
"width": "400px",
"text-align": "left",
"padding-left": "2.6em",
"box-sizing": "border-box"
},
"attributes": {
"class": "ms-fontSize-16 ms-fontColor-white"
}
},
{
"elmType": "div",
"style": {
"flex-grow": "1",
"height": "100%",
"position": "relative",
"display": "flex",
"align-items": "center"
},
"children": [
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$ProjectStartDate])",
"style": {
"position": "absolute",
"padding": "0px 14px 0px 14px",
"height": "100%",
"margin-left": "40px",
"border-radius": "6px 6px 0 0",
"display": "flex",
"align-items": "center"
},
"attributes": {
"title": "='Project Start: ' + toLocaleDateString([$ProjectStartDate])",
"class": "ms-bgColor-themeDarker ms-fontSize-14 ms-fontColor-white"
}
},
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$ProjectEndDate])",
"style": {
"position": "absolute",
"right": "0",
"padding": "0px 10px 0px 14px",
"height": "100%",
"border-radius": "6px 6px 0 0",
"display": "flex",
"align-items": "Center"
},
"attributes": {
"title": "='Project Finish: ' + toLocaleDateString([$ProjectEndDate])",
"class": "ms-bgColor-themeDarker ms-fontSize-14 ms-fontColor-white"
}
},
{
"elmType": "span",
"txtContent": "=toLocaleDateString( @now)",
"style": {
"position": "relative",
"width": "90px",
"z-index": "100",
"display": "=if([$ProjectEndDate] < @now , 'none', 'block')",
"left": "=floor( (Number(@now)-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 ) + '%'",
"background-color": "#e1dfdd",
"text-align": "center",
"padding": "0 3px",
"margin": "0 0 0 3px"
}
},
{
"elmType": "span",
"attributes": {
"class": "ms-fontColor-gray40"
},
"style": {
"position": "relative",
"display": "=if( [$ProjectEndDate] < @now , 'none', 'block')",
"top": "-1.3em",
"z-index": "1",
"border-left": "5px solid",
"height": "800px",
"width": "0.1em",
"left": "= (Number(@now)-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%' "
}
}
]
}
]
},
{
"elmType": "div",
"style": {
"width": "100%",
"display": "flex"
},
"children": [
{
"elmType": "div",
"style": {
"width": "420px",
"display": "flex",
"flex-wrap": "wrap"
},
"attributes": {
"class": ""
},
"children": [
{
"elmType": "span",
"style": {
"width": "30px",
"padding": "6px 0",
"text-align": "center",
"margin-left": "10px",
"margin-right": "10px",
"cursor": "pointer"
},
"attributes": {
"iconName": "=if([$PercentComplete] >= 1, 'CompletedSolid', if([$PercentComplete] > 0 , 'CortanaLogoReadyOuter', 'CircleRing'))",
"title": "='PercentComplete: ' + Number([$PercentComplete] * 100) + '%'",
"class": "= 'ms-fontSize-14 ms-fontColor-' + if([$PercentComplete] >= 1, 'green', 'neutralSecondaryAlt')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"Progress": "=if([$PercentComplete] == 0, if([$TaskType] == 'Task' || [$TaskType] == '', 25 , 100) , if([$PercentComplete] == 0.25 , 50, if([$PercentComplete] == 0.50, 75, if([$PercentComplete] == 0.75, 100, 0))))"
}
}
},
{
"elmType": "button",
"txtContent": "[$Title]",
"customRowAction": {
"action": "editProps"
},
"style": {
"width": "375px",
"height": "1.6em",
"padding": "0.3em 0 0 0",
"border": "none",
"background-color": "transparent",
"cursor": "pointer",
"text-decoration": "none",
"text-align": "left",
"outline": "none",
"display": "inline-block",
"overflow": "hidden",
"text-overflow": "ellipsis",
"white-space": "nowrap"
},
"attributes": {
"title": "[$Title]",
"class": "= 'ms-fontSize-12 ms-fontWeight-bold ' + if([$DueDate] < @now && [$PercentComplete] < 100, 'ms-fontColor-red', 'ms-fontColor-gray140 ms-fontColor-black--hover')"
}
},
{
"elmType": "span",
"style": {
"width": "24px",
"padding": "1px 0 0 0",
"text-align": "center",
"margin-left": "-18px",
"color": "=if([$DueDate] < @now && [$PercentComplete] < 100, '#e72828', '#0078db')"
},
"attributes": {
"iconName": "=if( ( ([$TaskType] == 'Task' || [$TaskType] == '') && [$DueDate]< @now && [$PercentComplete] < 1 ) || ([$TaskType] == 'Milestone' && [$StartDate]< @now && [$PercentComplete] < 1 ) , 'EventDateMissed12', '')",
"title": "This task is running late!",
"class": "='ms-fontSize-14 ms-fontColor-' + if([$DueDate]< @now && [$PercentComplete] < 1, 'sharedRed20', 'themePrimary')"
}
},
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$StartDate])",
"style": {
"width": "96px",
"padding": "0.1em 0",
"text-align": " center",
"margin-left": "40px",
"margin-right": "24px",
"heigth": "1.4em",
"border-radius": "12px"
},
"attributes": {
"class": "ms-fontSize-12 ms-bgColor-neutralLight"
}
},
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$DueDate])",
"style": {
"width": "96px",
"padding": "0.1em 0",
"text-align": " center",
"border-radius": "12px"
},
"attributes": {
"class": "ms-fontSize-12 ms-bgColor-neutralLight"
}
}
]
},
{
"elmType": "div",
"style": {
"flex-grow": "1",
"position": "relative",
"height": "3.3em",
"padding": "0.3em 0 0 0"
},
"attributes": {
"class": ""
},
"children": [
{
"elmType": "div",
"txtContent": "",
"style": {
"position": "absolute",
"box-sizing": "border-box",
"display": "=if([$TaskType] == 'Task' || [$TaskType] == '' , 'flex', 'none')",
"border-radius": "6px",
"z-index": "10",
"top": "1.1em",
"height": "1.8em",
"overflow": "hidden",
"text-overflow": "ellipsis",
"border": "1.5px solid",
"border-color": "=if([$PercentComplete] >= 0.75, '#4CAF50', if([$PercentComplete] >= 0.5, '#FFC107', if([$PercentComplete] >= 0.25, '#ff8400', '#F44336')))",
"background-color": "#cfe6f7",
"left": "= (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%'",
"width": "= if( [$DueDate] > [$ProjectEndDate], (Number([$ProjectEndDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100 , (Number([$DueDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100 ) + '%'"
},
"attributes": {
"class": "",
"title": ""
}
},
{
"elmType": "div",
"style": {
"position": "absolute",
"box-sizing": "border-box",
"display": "=if(( [$TaskType] == 'Task' || [$TaskType] == '' ) && [$PercentComplete] > 0, 'flex', 'none')",
"border-radius": "=if( [$PercentComplete] < 1, '6px 0 0 6px', '6px')",
"z-index": "20",
"top": "1.1em",
"height": "1.8em",
"overflow": "hidden",
"text-overflow": "ellipsis",
"border": "1px solid",
"border-color": "=if([$DueDate] < @now && [$PercentComplete] < 1, '#ff0000', '#0078db')",
"background-color": "=if([$PercentComplete] >= 0.75, '#4CAF50', if([$PercentComplete] >= 0.5, '#FFC107', if([$PercentComplete] >= 0.25, '#ff8400', '#F44336')))",
"left": "= (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%'",
"width": "= if( [$DueDate] > [$ProjectEndDate], ((Number([$ProjectEndDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100) * [$PercentComplete] + '%' , ((Number([$DueDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100 * [$PercentComplete]) + '%'"
},
"attributes": {
"class": "sp-field-bold",
"title": "=[$Title] + ' - ' + toLocaleDateString([$StartDate]) + ' - ' + toLocaleDateString([$DueDate])"
}
},
{
"elmType": "div",
"txtContent": "",
"style": {
"position": "absolute",
"box-sizing": "border-box",
"border-radius": "6px",
"z-index": "50",
"top": "1.1em",
"height": "1.8em",
"overflow": "hidden",
"text-overflow": "ellipsis",
"border": "=if([$DueDate]< @now && [$PercentComplete] < 1 && ([$TaskType] == 'Task' || [$TaskType] == '' ), '1.8px solid #f8b7bd', 'none')",
"background-color": "",
"left": "= (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%'",
"width": "=if([$TaskType] == 'Milestone', '28px' , if( [$DueDate] > [$ProjectEndDate], (Number([$ProjectEndDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100 , (Number([$DueDate])-Number([$StartDate])+ 86400000) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])+ 86400000) * 100 ) + '%'",
"margin-left": "=if([$TaskType] == 'Milestone', '-14px' , 0"
},
"attributes": {
"class": "",
"title": ""
},
"customCardProps": {
"openOnEvent": "hover",
"directionalHint": "bottomCenter",
"isBeakVisible": true,
"beakStyle": {
"backgroundColor": "white"
},
"formatter": {
"elmType": "div",
"style": {
"max-height": "256px",
"width": "282px",
"display": "flex",
"flex-wrap": "wrap",
"align-items": "flex-start"
},
"attributes": {
"class": "ms-ContextualMenu-list is-open list-436"
},
"children": [
{
"elmType": "div",
"txtContent": "[$Title]",
"style": {
"width": "250px",
"height": "40px",
"padding": "4px 4px 0 4px",
"overflow": "hidden",
"text-overflow": "ellipsis"
},
"attributes": {
"class": "ms-fontSize-14 ms-bgColor-themeLight ms-fontWeight-semibold ms-fontColor-gray160"
}
},
{
"elmType": "div",
"style": {
"width": "12px",
"flex-grow": "1",
"height": "34px",
"padding": "10px 0 0 0 ",
"text-align": "center",
"cursor": "pointer"
},
"attributes": {
"iconName": "Edit",
"class": "ms-fontSize-14 ms-bgColor-themeLight ms-fontColor-gray160"
},
"customRowAction": {
"action": "editProps"
}
},
{
"elmType": "div",
"style": {
"width": "100%",
"display": "flex",
"flex-wrap": "wrap",
"align-items": "flex-start",
"margin": "2px 0"
},
"children": [
{
"elmType": "div",
"style": {
"width": "24px",
"padding": "6px 0",
"text-align": " center",
"heigth": "1.4em"
},
"attributes": {
"iconName": "Timeline"
}
},
{
"elmType": "div",
"txtContent": "0%",
"style": {
"padding": "2px 6px",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"cursor": "pointer",
"heigth": "1.4em"
},
"attributes": {
"class": "='ms-fontSize-14 ms-bgColor-themeLight--hover ms-fontColor-themeDarker--hover ms-bgColor-' + if([$PercentComplete] == 0, 'themeTertiary', 'neutralLight')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"PPercentComplete": "0"
}
}
},
{
"elmType": "div",
"txtContent": "25%",
"style": {
"padding": "2px 6px",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"cursor": "pointer",
"heigth": "1.4em"
},
"attributes": {
"class": "='ms-fontSize-14 ms-bgColor-themeLight--hover ms-fontColor-themeDarker--hover ms-bgColor-' + if([$PercentComplete] == 0.25, 'themeTertiary', 'neutralLight')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"PercentComplete": "25"
}
}
},
{
"elmType": "div",
"txtContent": "50%",
"style": {
"padding": "2px 6px",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"cursor": "pointer",
"heigth": "1.4em"
},
"attributes": {
"class": "='ms-fontSize-14 ms-bgColor-themeLight--hover ms-fontColor-themeDarker--hover ms-bgColor-' + if([$PercentComplete] == 0.5, 'themeTertiary', 'neutralLight')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"percentComplete": "50"
}
}
},
{
"elmType": "div",
"txtContent": "75%",
"style": {
"padding": "2px 6px",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"cursor": "pointer",
"heigth": "1.4em"
},
"attributes": {
"class": "='ms-fontSize-14 ms-bgColor-themeLight--hover ms-fontColor-themeDarker--hover ms-bgColor-' + if([$PercentComplete] == 0.75, 'themeTertiary', 'neutralLight')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"PercentComplete": "75"
}
}
},
{
"elmType": "div",
"txtContent": "100%",
"style": {
"padding": "2px 6px",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"cursor": "pointer",
"heigth": "1.4em"
},
"attributes": {
"class": "='ms-fontSize-14 ms-bgColor-themeLight--hover ms-fontColor-themeDarker--hover ms-bgColor-' + if([$PercentComplete] == 1, 'themeTertiary', 'neutralLight')"
},
"customRowAction": {
"action": "setValue",
"actionInput": {
"percentComplete": "100"
}
}
}
]
},
{
"elmType": "div",
"style": {
"width": "24px",
"display": "=if( ( ([$TaskType] == 'Task' || [$TaskType] == '') && [$DueDate]< @now && [$PercentComplete] < 1 ) || ([$TaskType] == 'Milestone' && [$StartDate]< @now && [$PercentComplete] < 1 ) , 'block', 'none')",
"padding": "6px 0 7px 0",
"text-align": " center",
"heigth": "1.4em",
"margin": "2px 0"
},
"attributes": {
"iconName": "EventDateMissed12",
"class": "sp-field-severity--blocked30 ms-fontSize-14 ms-fontColor-sharedRed20"
}
},
{
"elmType": "div",
"txtContent": "This task is running late!",
"style": {
"width": "254px",
"display": "=if( ( ([$TaskType] == 'Task' || [$TaskType] == '') && [$DueDate]< @now && [$PercentComplete] < 1 ) || ([$TaskType] == 'Milestone' && [$StartDate]< @now && [$PercentComplete] < 1 ) , 'block', 'none')",
"padding": "4px 0 4px 4px",
"text-align": " Left",
"heigth": "1.4em",
"margin": "2px 0"
},
"attributes": {
"class": "sp-field-severity--blocked30 ms-fontSize-14 ms-fontColor-sharedRed20"
}
},
{
"elmType": "div",
"style": {
"width": "24px",
"padding": "6px 0",
"text-align": " center",
"heigth": "1.4em"
},
"attributes": {
"iconName": "Diamond"
}
},
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$StartDate])",
"style": {
"width": "127px",
"padding": "2px 0",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"height": "1.4em"
},
"attributes": {
"class": "ms-fontSize-14 ms-bgColor-neutralLight"
}
},
{
"elmType": "div",
"txtContent": "=toLocaleDateString([$DueDate])",
"style": {
"width": "127px",
"padding": "2px 0",
"text-align": " center",
"border-radius": "14px",
"margin": "2px 2px 0 0 ",
"height": "1.4em"
},
"attributes": {
"class": "ms-fontSize-14 ms-bgColor-neutralLight"
}
},
{
"elmType": "div",
"style": {
"width": "24px",
"padding": "6px 0",
"text-align": " center",
"heigth": "1.4em"
},
"attributes": {
"iconName": "Contact",
"title": "='Assigned to : ' + [$AssignedTo]"
}
},
{
"elmType": "div",
"txtContent": "[$AssignedTo]",
"style": {
"width": "254px",
"padding": "4px 0 4px 4px"
},
"defaultHoverField": "[$AssignedTo]"
},
{
"elmType": "div",
"txtContent": "[$TaskDescription]",
"style": {
"font-style": "italic",
"width": "254px",
"padding": "4px 0 4px 4px"
}
}
]
}
}
},
{
"elmType": "div",
"txtContent": "",
"style": {
"position": "relative",
"box-sizing": "border-box",
"display": "=if([$TaskType] == 'Milestone', 'flex', 'none')",
"z-index": "10",
"top": "0.3em",
"height": "3em",
"left": "= (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%'",
"margin-left": "30px",
"width": "28px",
"color": "=if([$DueDate] < @now && [$PercentComplete] < 1, '#e72828', '#0078db')"
},
"attributes": {
"iconName": "=if([$StartDate]< @now && [$PercentComplete] < 1, 'Diamond', 'Diamond'",
"title": "=[$Title] + ' - ' + toLocaleDateString([$StartDate]) ",
"class": "='ms-fontSize-24 ' + if([$StartDate]< @now && [$PercentComplete] < 1, 'ms-fontColor-sharedRed20', 'ms-fontColor-themePrimary') "
}
},
{
"elmType": "div",
"txtContent": "=getDate([$StartDate]) + '-' + if(getMonth([$StartDate])==0,'Jan',if(getMonth([$StartDate])==1,'Feb',if(getMonth([$StartDate])==2,'Mar',if(getMonth([$StartDate])==3,'Apr',if(getMonth([$StartDate])==4,'May',if(getMonth([$StartDate])==5,'Jun',if(getMonth([$StartDate])==6,'Jul',if(getMonth([$StartDate])==7,'Aug',if(getMonth([$StartDate])==8,'Sep',if(getMonth([$StartDate])==9,'Oct',if(getMonth([$StartDate])==10,'Nov',if(getMonth([$StartDate])==11,'Dec',''))))))))))))",
"style": {
"position": "absolute",
"box-sizing": "border-box",
"display": "=if([$TaskType] == 'Milestone' , 'flex', 'none')",
"z-index": "3",
"top": "10px",
"height": "24px",
"margin-left": "-8px",
"left": "= (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%'",
"width": "60px",
"text-align": "right"
},
"attributes": {
"class": "sp-field-bold ms-fontSize-14"
}
},
{
"elmType": "div",
"txtContent": "=(Number[$PercentComplete]) * 100 + '%'",
"style": {
"position": "absolute",
"box-sizing": "border-box",
"display": "=if([$TaskType] == 'Task' || [$TaskType] == '' , 'flex', 'none')",
"z-index": "3",
"top": "12px",
"height": "24px",
"margin-left": "=if((Number([$DueDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) <= 0.9 , '10px' , '-40px')",
"left": "=if((Number([$DueDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) <= 0.9 , (Number([$DueDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%' , (Number([$StartDate])-Number([$ProjectStartDate])) / (Number([$ProjectEndDate])-Number([$ProjectStartDate])) * 100 + '%' ) ",
"width": "40px",
"color": "=if([$DueDate] < @now && [$PercentComplete] < 1, '#ff0000', '#000000')"
},
"attributes": {
"class": "sp-field-bold ms-fontSize-14"
}
}
]
}
]
}
]
}
}
3?? How the JSON Works
? Dynamic Bar Width: The width of each bar is calculated based on the difference between the Start Date and Due Date.
? Color Coding: The task status determines the bar color:
? Hover Effect: Displays task details on hover.
Final Outcome
Once applied, your modern SharePoint list will display a horizontal bar chart, resembling a Gantt chart, visually representing your tasks and their timelines. This customization enables project teams to manage work efficiently within SharePoint without relying on external tools.
?? Want more SharePoint customization ideas? Let’s discuss in the comments!