Apply a Gantt Chart view in SharePoint

Gantt charts are very useful in projectmanagement to give the people involved a clear overview when a task should start and finish in relation to other tasks.

Using view format in SharePoint (Online only), we can achieve this to a certain extent. Mind me, it is far from perfect and in its current version it is mainly useful for top-level views.

So what are we talking about…

Let’s get started

First we need a list with 4 extra columns, ProjectStart, ProjectDue, TaskStart and TaskDue. you can use different names but the script will be looking for the internal names mentioned.
Once the list is created we need to add some data. And last but not least we will have to create a view using the JSON-code.

Create a list

Create a new “blank” list from Site Contents, and add the needed date columns. obviously you can create more columns if you like, but these are the bare minimum.

20 dec 2020: Added the “Progress” column for status indicator.

ColumnnameColumntype
TitleText
ProjectStartDate and time
ProjectDueDate and time
TaskStartDate and time
TaskDueDate and time
ProgressNumber (min: 0, max:100, percentage)

Please note that whenever you create a column an internal name is assigned to this column. If you change the name of a column, you do not change the internal name. So make sure you use the correct name straight away.

Create a new view

In the future you are still going to need the default view “All items” to add new entries in your list. So we better create a new view.

  1. Click on All items [1]
  2. Choose Save view as [2]
  3. In the pop-up you add a useful name [3], I am using “Gantt Chart”.
  4. Click on Save [4]

Apply the View formatting

  1. Click on All items [1]
  2. Choose Format current view [2] to open the Format view-pane.
  1. Click on Advanced mode [3]
  2. Go to the code on this page
  3. Click on the Copy code-button to copy the code
  4. Return to your SharePoint page.
  5. Paste the code (using <CTRL>+<V>) in the Format view-pane [4].
  6. To test, click on Preview [5].
  7. And if everything works out fine just click on Save [6].

The Gantt-chart JSON-script

6 nov 2020: Updated to include a marker for the current date
20 dec 2020: Updated to include a header, status indicator and fix for TaskDue after ProjectDue
23 dec 2020: Updated to include indicators and background color

{
  "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json",
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "style": {
      "height": "=if(@rowIndex == 0, '7em', '4em')",
      "display" : "block",
      "width" : "100%"
    },
    "children": [
      {
          "elmType" : "div",
          "attributes" : {
              "class" : "ms-bgColor-gray20"
          },
          "style" : {
              "width" : "100%",
              "display": "=if(@rowIndex == 0, 'flex', 'none')",
              "height" : "3em"
          },
            "children" : [
                            {
                                "elmType" : "div",
                                "txtContent" : "Taskname",
                                "style" : {
                                    "width" : "220px",
                                    "text-align" : "left",
                                    "padding-left" : "0.4em",
                                    "font-weight" : "bold",
                                    "box-sizing": "border-box"
                                    },
                                "attributes": {
                                    "class" : "ms-fontSize-16"    
                                    }
                            },
                            {
                               "elmType" : "div",
                               "style": {
                                    "flex-grow": "1",
                                    "height": "3em",
                                    "font-weight" : "bold"
                                },
                                "attributes": {
                                    "class" : "ms-fontSize-14"    
                                    },
                                "children" : [
                                        {
                                            "elmType" : "span",
                                            "txtContent": "=toLocaleDateString([$ProjectStart])",
                                            "style" : {
                                                "position": "relative",
                                                "left" :"0"
                                                }
                                        },
                                       {
                                            "elmType" : "span",
                                            "txtContent": "=toLocaleDateString([$ProjectDue])",
                                            "style" : {
                                                "position": "absolute",
                                                "right" :"0"
                                                }
                                        }
                                        ,
                                        {
                                            "elmType" : "span",
                                            "txtContent" : "=toLocaleDateString( @now)",
                                            "style" : {
                                                    "position": "relative",
                                                    "width": "100px",
                                                    "font-size":"1em",
                                                    "z-index" : "100",
                                                    "display" : "=if( [$ProjectDue] < @now , 'none', 'block')",
                                                    "left": "= floor( (Number(@now)-Number([$ProjectStart])) /  (Number([$ProjectDue])-Number([$ProjectStart]))  * 100 ) + '%' "
                                                } 
                                            }


                                ]
                            }
            ]
      },

      {  
         "elmType" : "div", 
         "style" : {
              "width" : "100%",
              "display": "flex"
          },
              "children": [
                            {
                                "elmType" : "span",
                                "style" : {
                                        "width": "20px",
                                        "padding-top" : "0.4em", 

                                        "color" : "=if( [$Progress] == 1, '#107c10' ,if( [$TaskDue] > [$ProjectDue] ,'#a80000', if( [$TaskStart]> @now, '#d0d4d8', if( [$TaskDue]< @now, '#a80000', '#699DE0') ) ) )"
                                    },
                                "attributes" : {
                                    "iconName" : "=if( [$Progress] == 1, 'CompletedSolid' ,if( [$TaskDue] > [$ProjectDue] ,'WarningSolid', if( [$TaskStart]> @now, 'Calendar', if( [$TaskDue]< @now, 'AlarmClock', 'CircleRing') ) ) )",
                                    "title": "[$Progress]",
                                    "class" : "ms-fontSize-16"
                                }
                            },
                            
                            {
                                "elmType": "button",
                                "txtContent": "[$Title]",
                                "customRowAction": {
                                "action": "editProps"
                                },
                                "style": {
                                "width": "200px",
                                "max-height" : "2em",
                                "padding" : "0",
                                "border": "none",
                                "background-color": "transparent",
                                "cursor": "pointer",
                                "text-decoration": "none",
                                "text-align": "left",
                                "outline": "none",
                                "display" : "inline-block",
                                "overflow" :"hidden",
                                "text-overflow" : "ellipsis"
                                },
                                "attributes": {
                                "title":  "[$Title]",
                                "class": "ms-fontSize-16 ms-fontColor-themePrimary ms-fontColor-themeDarker--hover"
                                }
                            },
                            {
                                "elmType": "div",
                                "style": {
                                "flex-grow": "1",
                                "position": "relative",
                                "height": "3em",
                                "border-style": "dotted",
                                "border-width": "1px 0 1px 0"
                                },
                                "attributes": {
                                "class": "ms-borderColor-neutralTertiary"
                                },
                                "children": [

                                {
                                    "elmType": "div",
                                    "txtContent": "=toLocaleDateString([$TaskStart]) + ' - ' + toLocaleDateString([$TaskDue])",
                                    "style": {
                                    "position": "relative",
                                    "box-sizing": "border-box",
                                    "display": "flex",
                                    "border-radius": "1em",
                                     "z-index" : "1",
                                    "top" : "0.2em",
                                    "height": "2.6em",
                                    "overflow" : "hidden",
                                    "text-overflow" : "ellipsis",
                                    "padding" : "0 0.2em 0 0.4em",
                                    "border": "1px solid",
                                    "border-color" : "=if( [$Progress] == 1, '#107c10' ,if( [$TaskDue] > [$ProjectDue] ,'#a80000', if( [$TaskStart]> @now, '#d0d4d8', if( [$TaskDue]< @now, '#a80000', '#699de0') ) ) )",
                                    "background-color" : "=if( [$Progress] == 1, '#bed6be' ,if( [$TaskDue] > [$ProjectDue] ,'#d6b3b3', if( [$TaskStart]> @now, '#dbe2ea', if( [$TaskDue]< @now, '#d6b3b3', '#c7d5e7') ) ) )",
                                    "left": "=  (Number([$TaskStart])-Number([$ProjectStart])) / (Number([$ProjectDue])-Number([$ProjectStart])) * 100  + '%'",
                                    "width": "= if( [$TaskDue] > [$ProjectDue],  (Number([$ProjectDue])-Number([$TaskStart])+ 86400000) / (Number([$ProjectDue])-Number([$ProjectStart])+ 86400000) * 100  ,  (Number([$TaskDue])-Number([$TaskStart])+ 86400000) / (Number([$ProjectDue])-Number([$ProjectStart])+ 86400000) * 100 ) + '%'"
                                    },
                                    "attributes": {
                                    "title": "=[$Title] + ' - ' + toLocaleDateString([$TaskStart]) + ' - ' + toLocaleDateString([$TaskDue])"
                                    }
                                },
                                {
                                    "elmType" : "span",
                                    "txtContent" : "",
                                    "attributes" : {
                                        "title" : "=toLocaleDateString( @now)",
                                        "class" : "ms-fontColor-gray40"
                                    },
                                    "style" : {
                                            "position": "relative",
                                            "display" : "=if( [$ProjectDue] < @now , 'none', 'block')",
                                            "top"  : "-2.6em",
                                            "z-index" : "100",
                                            "border-left" : "5px solid",
                                            "height": "3em",
                                            "width" : "1em",
                                            "left": "=  (Number(@now)-Number([$ProjectStart])) /  (Number([$ProjectDue])-Number([$ProjectStart]))  * 100  + '%' "
                                        } 
                                    }
                                ]
                            }
                            ]
    }
    ]
  }
}

4 Comments

  1. Great! Thank you for sharing your expertise! Just wondering if there is a way to allow +/- of time span, just like what Microsoft Project can do?

    1. Hi Toshi Iwata,
      As it stands this is not really possible.
      The only way to get something closely to that is to apply grouping to the view.
      So that means adding additional columns to identify the parent task and to group by this additional column. But I think you really need to rewrite the script itself to get this.
      Geert

  2. Hi Geert,
    thank you for that great piece of json formatting code! I was just wondering, if it is possible to add some more columns before the gantt is to be displayed.
    In which section of the code do I have to enter the code?
    Thank you in advance:-)

    1. Hi Victoria,
      If you want to add more columns, you need to start reading from line 100.
      Adding more columns isn’t going to be easy, so the easiest thing to do is to change
      "txtContent": "[$Title]",
      into
      "txtContent": "=[$Title]+' '+[$NewColumn]",

      If you really want to do more, it is basically that area the needs to be converted to a div with multiple children.
      Make sure to check Federico’s version on Linkedid
      Hope this helps
      Geert

Leave a Reply

Your email address will not be published. Required fields are marked *