Back to column formats
Column formattingSharePoint Online

Yearly Gantt Chart

This sample demonstrates the display of a yearly Gantt chart.

Yearly Gantt Chart formatting preview
Sample preview · View original image

Copy. Apply. Make it yours.

Get this format

2 definitions

Review the requirements below, then paste this JSON into the matching formatting panel. Show me where.

Use your list's internal column names and replace any tenant-specific URLs or flow IDs. Formatting is presentation, not a way to secure data.

Column formatting
Download JSON
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "style": {
    "display": "flex",
    "flex-direction": "column",
    "margin": "5px",
    "box-sizing": "border-box"
  },
  "children": [
    {
      "elmType": "div",
      "style": {
        "display": "flex",
        "flex-direction": "row",
        "justify-content": "space-between",
        "width": "100%",
        "margin-bottom": "3px"
      },
      "attributes": {
        "class": "=if([$Start] <= @now && [$End] >= @now, 'ms-fontColor-themePrimary', if([$Start] && [$End], 'ms-fontColor-neutralSecondary', 'ms-fontColor-neutralTertiary')) + ' ms-fontWeight-bold'"
      },
      "children": [
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "1"
        },
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "3"
        },
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "5"
        },
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "7"
        },
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "9"
        },
        {
          "elmType": "span",
          "style": {
            "width": "100%",
            "text-align": "left"
          },
          "txtContent": "11"
        }
      ]
    },
    {
      "elmType": "div",
      "style": {
        "display": "flex",
        "width": "100%",
        "border": "2px solid",
        "height": "24px",
        "overflow": "hidden",
        "position": "relative",
        "box-sizing": "border-box"
      },
      "attributes": {
        "class": "=if([$Start] <= @now && [$End] >= @now, 'ms-fontColor-themePrimary', if([$Start] > @now, 'ms-fontColor-themeTertiary', 'ms-fontColor-neutralTertiary'))"
      },
      "children": [
        {
          "elmType": "div",
          "style": {
            "position": "relative",
            "cursor": "pointer",
            "width": "=if(Number(Date(getYear([$Start]) + '/01/01')) < (Number(Date(getYear([$End]) + '/01/01'))) && getYear([$Start]) < getYear(@now),(Number(Date([$End])) - Number(Date(getYear([$End]) + '/01/01'))) / (Number(Date('' + getYear([$Start]) + '/12/31')) - Number(Date('' + getYear([$Start]) + '/01/01'))) * 100 + '%',((Number(Date([$End])) - Number(Date([$Start]))) / (Number(Date('' + getYear([$Start]) + '/12/31')) - Number(Date('' + getYear([$Start]) + '/01/01')))) * 100 + '%')",
            "left": "=if(Number(Date(getYear([$Start]) + '/01/01')) < (Number(Date(getYear([$End]) + '/01/01'))) && getYear([$Start]) < getYear(@now),'0%',if(Number(Date(getYear([$Start]) + '/01/01')) > (Number(Date(getYear([$End]) + '/12/31'))),'200%',(((Number(Date([$Start])) - Number(Date('' + getYear([$Start]) + '/01/01')))/(Number(Date('' + getYear([$Start]) + '/12/31')) - Number(Date('' + getYear([$Start]) + '/01/01'))))) * 100 + '%'))"
          },
          "attributes": {
            "class": "=if([$Start] <= @now && [$End] >= @now,'ms-bgColor-themePrimary ms-bgColor-themeTertiary--hover',if([$Start] > @now, 'ms-bgColor-themeTertiary ms-bgColor-themeLight--hover','ms-bgColor-neutralTertiary ms-bgColor-neutralSecondary--hover'))"
          },
          "customCardProps": {
            "directionalHint": "topCenter",
            "isBeakVisible": true,
            "openOnEvent": "hover",
            "formatter": {
              "elmType": "div",
              "style": {
                "display": "flex",
                "align-items": "center",
                "justify-content": "center",
                "width": "210px",
                "height": "30px",
                "margin": "10px",
                "font-weight": "bold"
              },
              "attributes": {
                "class": "ms-fontSize-l"
              },
              "children": [
                {
                  "elmType": "div",
                  "children": [
                    {
                      "elmType": "span",
                      "txtContent": "[$Start.displayValue]"
                    },
                    {
                      "elmType": "span",
                      "style": {
                        "margin-left": "5px",
                        "margin-right": "5px"
                      },
                      "txtContent": "-"
                    },
                    {
                      "elmType": "span",
                      "txtContent": "[$End.displayValue]"
                    }
                  ]
                }
              ]
            }
          }
        },
        {
          "elmType": "div",
          "txtContent": "=if([$Start] && [$End], if(Number(Date(getYear([$Start]) + '/01/01')) < (Number(Date(getYear([$End]) + '/01/01'))) && getYear([$Start]) < getYear(@now), getYear([$End]), getYear([$Start])), '----')",
          "attributes": {
            "class": "=if([$Start] && [$End], 'ms-fontColor-neutralPrimary', 'ms-fontColor-neutralSecondary') + ' ms-fontSize-mi ms-fontWeight-bold'"
          },
          "style": {
            "position": "absolute",
            "top": "2px",
            "left": "4px",
            "opacity": "0.4"
          }
        }
      ]
    },
    {
      "elmType": "div",
      "style": {
        "display": "flex",
        "width": "100%",
        "border": "1px solid",
        "height": "8px",
        "box-sizing": "border-box"
      },
      "attributes": {
        "class": "=if([$Start] <= @now && [$End] >= @now, 'ms-fontColor-themePrimary', if([$Start] > @now, 'ms-fontColor-themeTertiary', 'ms-fontColor-neutralTertiary'))"
      },
      "children": [
        {
          "elmType": "div",
          "style": {
            "cursor": "pointer",
            "display": "=if(getYear([$Start]) == getYear(@now) || getYear([$End]) == getYear(@now), 'inherit', 'none')",
            "position": "relative",
            "width": "3px",
            "left": "=floor(((Number(@now)-Number(Date('' + getYear(@now) + '/1/1')))/(1000*60*60*24))/365 * 100) + '%'"
          },
          "attributes": {
            "class": "ms-bgColor-sharedRed10 ms-bgColor-orangeLight--hover"
          },
          "customCardProps": {
            "directionalHint": "topCenter",
            "isBeakVisible": true,
            "openOnEvent": "hover",
            "formatter": {
              "elmType": "div",
              "style": {
                "display": "flex",
                "align-items": "center",
                "justify-content": "center",
                "width": "90px",
                "height": "30px",
                "margin": "10px",
                "font-weight": "bold"
              },
              "attributes": {
                "class": "ms-fontSize-l"
              },
              "children": [
                {
                  "elmType": "div",
                      "txtContent": "=toLocaleDateString(@now)"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}

From the contributor

How to use this sample

Summary

This sample demonstrates the display of a yearly Gantt chart.

screenshot of the sample

  • Schedules prior to the current date are shown with neutral colors
  • Schedules containing the current date are shown with primary theme colors
  • Schedules later than the current date are shown with light theme colors
  • Year shown is the either the current year for active schedules,the last year of a past schedule, or the first year of a future schedule
  • Full schedule date range is shown on hover

View requirements

This format can be applied to any column type but expects the following columns to be part of the view:

Type Internal Name Required
DateTime Start Yes
DateTime End Yes

Sample

Solution Author(s)
generic-yearly-gantt-chart.json Tetsuya Kawahara, Chris Kent
generic-yearly-gantt-chart-with-today.json Alvin Fong, DRVRogo, Chris Kent

Version history

Version Date Comments
1.0 April 12, 2021 Initial release
1.1 August 27, 2022 Added generic-yearly-gantt-chart-with-today.json
1.2. August 9, 2025 Latest year is prioritized in ranges that span across years (unless first year is current year), neutral colors used for ranges outside current year

Disclaimer

THIS CODE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.