[text] Deneb Gantt Chart

Viewer

copydownloadembedprintName: Deneb Gantt Chart
  1. {
  2.   "title": {
  3.     "anchor": "start",
  4.     "align": "left",
  5.     "offset": 20,
  6.     "text": "Deneb Example - Enhanced Gantt Chart",
  7.     "font": "Verdana",
  8.     "fontSize": 24,
  9.     "fontWeight": "bold",
  10.     "fontStyle": "normal",
  11.     "subtitle": "Synthetic Construction Project; PL=planned; AC=actual (completed, in progress) or estimated (not started)",
  12.     "subtitleFont": "Verdana",
  13.     "subtitleFontSize": 16,
  14.     "subtitleFontWeight": "normal",
  15.     "subtitleFontStyle": "italic"
  16.   },
  17.   "data": {"name": "dataset"},
  18.   "transform": [
  19.     {
  20.       "calculate": "datum['Planned Days'] == 0 ? true : false",
  21.       "as": "_is_milestone"
  22.     },
  23.     {
  24.       "calculate": "length( split( datum['WBS'], '.' ) )",
  25.       "as": "_level"
  26.     },
  27.     {
  28.       "calculate": "split( datum['WBS'], '.' )[0]",
  29.       "as": "_phase"
  30.     },
  31.     {
  32.       "calculate": "datum['_level'] == 1 ? datetime(2099,11,31) : datum['Planned Start Date']",
  33.       "as": "_phase_interim_planned_start_date"
  34.     },
  35.     {
  36.       "calculate": "datum['_level'] == 1 ? datetime(2000,0,1) : datum['Planned End Date']",
  37.       "as": "_phase_interim_planned_end_date"
  38.     },
  39.     {
  40.       "joinaggregate": [
  41.         {
  42.           "op": "min",
  43.           "field": "_phase_interim_planned_start_date",
  44.           "as": "_phase_min_planned_start_date"
  45.         }
  46.       ],
  47.       "groupby": ["_phase"]
  48.     },
  49.     {
  50.       "joinaggregate": [
  51.         {
  52.           "op": "max",
  53.           "field": "_phase_interim_planned_end_date",
  54.           "as": "_phase_max_planned_end_date"
  55.         }
  56.       ],
  57.       "groupby": ["_phase"]
  58.     },
  59.     {
  60.       "joinaggregate": [
  61.         {
  62.           "op": "sum",
  63.           "field": "Planned Days",
  64.           "as": "_phase_planned_days"
  65.         }
  66.       ],
  67.       "groupby": ["_phase"]
  68.     },
  69.     {
  70.       "calculate": "datum['_level'] == 1 ? datum['_phase_min_planned_start_date'] : datum['Planned Start Date']",
  71.       "as": "_planned_start_date"
  72.     },
  73.     {
  74.       "calculate": "datum['_level'] == 1 ? datum['_phase_max_planned_end_date'] : datum['Planned End Date']",
  75.       "as": "_planned_end_date"
  76.     },
  77.     {
  78.       "calculate": "datum['_level'] == 1 ? datum['_phase_planned_days'] : datum['Planned Days']",
  79.       "as": "_planned_days"
  80.     },
  81.     {
  82.       "calculate": "datum['_level'] == 1 ? datetime(2099,11,31) : datum['Estimated Start Date']",
  83.       "as": "_phase_interim_actual_start_date"
  84.     },
  85.     {
  86.       "calculate": "datum['_level'] == 1 ? datetime(2000,0,1) : datum['Estimated End Date']",
  87.       "as": "_phase_interim_actual_end_date"
  88.     },
  89.     {
  90.       "joinaggregate": [
  91.         {
  92.           "op": "min",
  93.           "field": "_phase_interim_actual_start_date",
  94.           "as": "_phase_min_actual_start_date"
  95.         }
  96.       ],
  97.       "groupby": ["_phase"]
  98.     },
  99.     {
  100.       "joinaggregate": [
  101.         {
  102.           "op": "max",
  103.           "field": "_phase_interim_actual_end_date",
  104.           "as": "_phase_max_actual_end_date"
  105.         }
  106.       ],
  107.       "groupby": ["_phase"]
  108.     },
  109.     {
  110.       "calculate": "datum['_level'] == 1 ? datum['_phase_min_actual_start_date'] : datum['Estimated Start Date']",
  111.       "as": "_actual_start_date"
  112.     },
  113.     {
  114.       "calculate": "datum['_level'] == 1 ? datum['_phase_max_actual_end_date'] : datum['Estimated End Date']",
  115.       "as": "_actual_end_date"
  116.     },
  117.     {
  118.       "joinaggregate": [
  119.         {
  120.           "op": "sum",
  121.           "field": "Actual Days",
  122.           "as": "_phase_actual_days"
  123.         }
  124.       ],
  125.       "groupby": ["_phase"]
  126.     },
  127.     {
  128.       "calculate": "datum['Actual Days'] + datum['Remaining Days']",
  129.       "as": "_actual_plus_remaining_days"
  130.     },
  131.     {
  132.       "joinaggregate": [
  133.         {
  134.           "op": "sum",
  135.           "field": "_actual_plus_remaining_days",
  136.           "as": "_phase_actual_plus_remaining_days"
  137.         }
  138.       ],
  139.       "groupby": ["_phase"]
  140.     },
  141.     {
  142.       "calculate": "datum['_level'] == 1 ? datum['_phase_actual_plus_remaining_days'] : datum['_actual_plus_remaining_days']",
  143.       "as": "_actual_days"
  144.     },
  145.     {
  146.       "calculate": "datum['_planned_days'] - datum['_actual_days']",
  147.       "as": "_variance_days"
  148.     },
  149.     {
  150.       "calculate": "datum['_variance_days'] / datum['_planned_days']",
  151.       "as": "_variance_percent"
  152.     },
  153.     {
  154.       "calculate": "datum['_phase_actual_days'] == 0 ? datum['_phase_min_actual_start_date'] : timeOffset('day', datum['_phase_min_actual_start_date'], datum['_phase_actual_days'])",
  155.       "as": "_phase_estimated_progress_date"
  156.     },
  157.     {
  158.       "calculate": "datum['_actual_days'] == 0 ? datum['Estimated Start Date'] : timeOffset('day', datum['Estimated Start Date'], datum['Actual Days'])",
  159.       "as": "_estimated_progress_date"
  160.     },
  161.     {
  162.       "calculate": "datum['_phase_actual_plus_remaining_days'] == 0 ? 0 : datum['_phase_actual_days'] / datum['_phase_actual_plus_remaining_days']",
  163.       "as": "_phase_actual_complete_percent"
  164.     },
  165.     {
  166.       "calculate": "datum['_actual_plus_remaining_days'] == 0 ? 0 : datum['Actual Days'] / datum['_actual_plus_remaining_days']",
  167.       "as": "_task_actual_complete_percent"
  168.     },
  169.     {
  170.       "calculate": "datum['_is_milestone'] && datum['Actual End Date'] > datetime( 2001, 0, 1 ) ? 1 : 0",
  171.       "as": "_milestone_actual_complete_percent"
  172.     }
  173.   ],
  174.   "params": [
  175.     {
  176.       "name": "_show_planned",
  177.       "value": true,
  178.       "bind": {
  179.         "input": "checkbox",
  180.         "name": "Show Planned: "
  181.       }
  182.     }
  183.   ],
  184.   "spacing": 0,
  185.   "hconcat": [
  186.     {
  187.       "name": "MATRIX",
  188.       "height": 670,
  189.       "width": 600,
  190.       "hconcat": [
  191.         {
  192.           "name": "WBS_COLUMN",
  193.           "height": {"step": 25},
  194.           "width": 20,
  195.           "title": {
  196.             "text": "WBS",
  197.             "align": "right",
  198.             "anchor": "end",
  199.             "color": "#C9C9C9"
  200.           },
  201.           "mark": {
  202.             "type": "text",
  203.             "align": "right",
  204.             "x": 20,
  205.             "color": {
  206.               "expr": "datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  207.             },
  208.             "fontSize": {
  209.               "expr": "datum['_level'] == 1 ? 14 : 12"
  210.             },
  211.             "fontWeight": {
  212.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  213.             }
  214.           },
  215.           "encoding": {
  216.             "y": {
  217.               "field": "WBS",
  218.               "type": "ordinal",
  219.               "axis": null
  220.             },
  221.             "text": {
  222.               "field": "WBS",
  223.               "type": "nominal"
  224.             }
  225.           }
  226.         },
  227.         {
  228.           "name": "PHASE_TASK_COLUMN",
  229.           "height": {"step": 25},
  230.           "width": 200,
  231.           "title": {
  232.             "text": "Phase\\Task",
  233.             "anchor": "start",
  234.             "align": "left",
  235.             "color": "#C9C9C9"
  236.           },
  237.           "mark": {
  238.             "type": "text",
  239.             "align": "left",
  240.             "x": 0,
  241.             "color": {
  242.               "expr": "datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  243.             },
  244.             "fontSize": {
  245.               "expr": "datum['_level'] == 1 ? 14 : 12"
  246.             },
  247.             "fontWeight": {
  248.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  249.             }
  250.           },
  251.           "encoding": {
  252.             "y": {
  253.               "field": "WBS",
  254.               "type": "ordinal",
  255.               "axis": null
  256.             },
  257.             "text": {
  258.               "field": "Task",
  259.               "type": "nominal"
  260.             }
  261.           }
  262.         },
  263.         {
  264.           "name": "START_DATE_COLUMN",
  265.           "height": {"step": 25},
  266.           "width": 40,
  267.           "title": {
  268.             "text": "AC Start Date",
  269.             "align": "right",
  270.             "anchor": "end",
  271.             "color": "#C9C9C9"
  272.           },
  273.           "mark": {
  274.             "type": "text",
  275.             "align": "right",
  276.             "x": 40,
  277.             "color": {
  278.               "expr": "datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  279.             },
  280.             "fontSize": {
  281.               "expr": "datum['_level'] == 1 ? 14 : 12"
  282.             },
  283.             "fontWeight": {
  284.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  285.             }
  286.           },
  287.           "encoding": {
  288.             "y": {
  289.               "field": "WBS",
  290.               "type": "ordinal",
  291.               "axis": null
  292.             },
  293.             "text": {
  294.               "field": "_actual_start_date",
  295.               "type": "temporal",
  296.               "formatType": "pbiFormat",
  297.               "format": "dd-MMM-yyyy"
  298.             }
  299.           }
  300.         },
  301.         {
  302.           "name": "PLANNED_DURATION_COLUMN",
  303.           "height": {"step": 25},
  304.           "width": 40,
  305.           "title": {
  306.             "text": "PL Dur",
  307.             "align": "right",
  308.             "anchor": "end",
  309.             "color": "#C9C9C9"
  310.           },
  311.           "transform": [
  312.             {
  313.               "calculate": "datum['_planned_days'] + 'd'",
  314.               "as": "_duration"
  315.             }
  316.           ],
  317.           "mark": {
  318.             "type": "text",
  319.             "align": "right",
  320.             "x": 40,
  321.             "color": {
  322.               "expr": "datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  323.             },
  324.             "fontSize": {
  325.               "expr": "datum['_level'] == 1 ? 14 : 12"
  326.             },
  327.             "fontWeight": {
  328.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  329.             }
  330.           },
  331.           "encoding": {
  332.             "y": {
  333.               "field": "WBS",
  334.               "type": "ordinal",
  335.               "axis": null
  336.             },
  337.             "text": {
  338.               "field": "_duration",
  339.               "type": "nominal"
  340.             }
  341.           }
  342.         },
  343.         {
  344.           "name": "ACTUAL_DURATION_COLUMN",
  345.           "height": {"step": 25},
  346.           "width": 40,
  347.           "title": {
  348.             "text": "AC Dur",
  349.             "align": "right",
  350.             "anchor": "end",
  351.             "color": "#C9C9C9"
  352.           },
  353.           "transform": [
  354.             {
  355.               "calculate": "datum['_actual_days'] == 0 && datum['Actual End Date'] < datetime(2000,0,1) ? '' : datum['_actual_days'] + 'd'",
  356.               "as": "_duration"
  357.             }
  358.           ],
  359.           "mark": {
  360.             "type": "text",
  361.             "align": "right",
  362.             "x": 40,
  363.             "color": {
  364.               "expr": "datum['_actual_days'] == 0 && datum['Actual End Date'] > datetime(2000,0,1) ? 'black' : datum['_actual_days'] == 0 ? 'transparent' :  datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  365.             },
  366.             "fontSize": {
  367.               "expr": "datum['_level'] == 1 ? 14 : 12"
  368.             },
  369.             "fontWeight": {
  370.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  371.             }
  372.           },
  373.           "encoding": {
  374.             "y": {
  375.               "field": "WBS",
  376.               "type": "ordinal",
  377.               "axis": null
  378.             },
  379.             "text": {
  380.               "field": "_duration",
  381.               "type": "nominal"
  382.             }
  383.           }
  384.         },
  385.         {
  386.           "name": "VARIANCE_DURATION_COLUMN",
  387.           "height": {"step": 25},
  388.           "width": 40,
  389.           "title": {
  390.             "text": "Variance",
  391.             "align": "right",
  392.             "anchor": "end",
  393.             "color": "#C9C9C9"
  394.           },
  395.           "transform": [
  396.             {
  397.               "calculate": "datum['_actual_days'] == 0 ? '' :datum['_variance_days'] + 'd'",
  398.               "as": "_duration"
  399.             }
  400.           ],
  401.           "mark": {
  402.             "type": "text",
  403.             "align": "right",
  404.             "x": 40,
  405.             "color": {
  406.               "expr": "datum['_actual_days'] == 0 ? 'transparent' : datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  407.             },
  408.             "fontSize": {
  409.               "expr": "datum['_level'] == 1 ? 14 : 12"
  410.             },
  411.             "fontWeight": {
  412.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  413.             }
  414.           },
  415.           "encoding": {
  416.             "y": {
  417.               "field": "WBS",
  418.               "type": "ordinal",
  419.               "axis": null
  420.             },
  421.             "text": {
  422.               "field": "_duration",
  423.               "type": "nominal"
  424.             }
  425.           }
  426.         },
  427.         {
  428.           "name": "VARIANCE_PERCENT_COLUMN",
  429.           "height": {"step": 25},
  430.           "width": 40,
  431.           "title": {
  432.             "text": "Variance %",
  433.             "align": "right",
  434.             "anchor": "end",
  435.             "color": "#C9C9C9"
  436.           },
  437.           "transform": [
  438.             {
  439.               "calculate": "datum['_actual_days'] == 0 ? '' : datum['_variance_percent']",
  440.               "as": "_variance_percent"
  441.             }
  442.           ],
  443.           "mark": {
  444.             "type": "text",
  445.             "align": "right",
  446.             "x": 40,
  447.             "color": {
  448.               "expr": "datum['_actual_days'] == 0 ? 'transparent' : datum['_variance_days'] < 0 ? pbiColor('negative') : 'black'"
  449.             },
  450.             "fontSize": {
  451.               "expr": "datum['_level'] == 1 ? 14 : 12"
  452.             },
  453.             "fontWeight": {
  454.               "expr": "datum['_level'] == 1 ? 'bold' : datum['_variance_days'] < 0 ? 'bold' : 'normal'"
  455.             }
  456.           },
  457.           "encoding": {
  458.             "y": {
  459.               "field": "WBS",
  460.               "type": "ordinal",
  461.               "axis": null
  462.             },
  463.             "text": {
  464.               "field": "_variance_percent",
  465.               "type": "quantitative",
  466.               "format": ".0%"
  467.             }
  468.           }
  469.         }
  470.       ]
  471.     },
  472.     {
  473.       "name": "GANTT",
  474.       "height": 750,
  475.       "width": 900,
  476.       "layer": [
  477.         {
  478.           "name": "TODAY",
  479.           "transform": [
  480.             {
  481.               "filter": "datum['__row__'] == 0"
  482.             },
  483.             {
  484.               "calculate": "datetime( year( datetime( now() ) ), month( datetime( now() ) ), date( datetime( now() ) ) )",
  485.               "as": "_today"
  486.             },
  487.             {
  488.               "calculate": "'TODAY (' + timeFormat(now(), '%b') + ' ' + timeFormat(now(), '%e') + ')'",
  489.               "as": "_today_text"
  490.             }
  491.           ],
  492.           "layer": [
  493.             {
  494.               "name": "TODAY_RULE",
  495.               "mark": {
  496.                 "type": "rule",
  497.                 "strokeWidth": 1,
  498.                 "strokeDash": [8, 8],
  499.                 "color": {
  500.                   "expr": "pbiColor('negative')"
  501.                 }
  502.               },
  503.               "encoding": {
  504.                 "x": {
  505.                   "field": "_today",
  506.                   "type": "temporal"
  507.                 }
  508.               }
  509.             },
  510.             {
  511.               "name": "TODAY_TEXT",
  512.               "mark": {
  513.                 "type": "text",
  514.                 "y": "height",
  515.                 "yOffset": 10,
  516.                 "color": {
  517.                   "expr": "pbiColor('negative')"
  518.                 }
  519.               },
  520.               "encoding": {
  521.                 "x": {
  522.                   "field": "_today",
  523.                   "type": "temporal"
  524.                 },
  525.                 "text": {
  526.                   "field": "_today_text",
  527.                   "type": "nominal"
  528.                 }
  529.               }
  530.             }
  531.           ]
  532.         },
  533.         {
  534.           "name": "PLANNED_GANTT",
  535.           "layer": [
  536.             {
  537.               "name": "PLANNED_PHASE_BAR",
  538.               "transform": [
  539.                 {
  540.                   "filter": "datum['_level'] == 1"
  541.                 }
  542.               ],
  543.               "mark": {
  544.                 "type": "bar",
  545.                 "height": {"band": 0.2},
  546.                 "yOffset": -8
  547.               },
  548.               "encoding": {
  549.                 "x": {
  550.                   "field": "_phase_min_planned_start_date",
  551.                   "type": "temporal",
  552.                   "axis": {
  553.                     "orient": "top",
  554.                     "title": null,
  555.                     "labelPadding": 14,
  556.                     "labelAlign": "center",
  557.                     "labelExpr": "split( timeFormat(datum.value, '%b') + ' ' + timeFormat(datum.value, '%e'), ' ')"
  558.                   }
  559.                 },
  560.                 "x2": {
  561.                   "field": "_phase_max_planned_end_date"
  562.                 },
  563.                 "y": {
  564.                   "field": "WBS",
  565.                   "type": "ordinal",
  566.                   "axis": null
  567.                 },
  568.                 "color": {
  569.                   "condition": [
  570.                     {
  571.                       "test": "_show_planned",
  572.                       "value": {
  573.                         "expr": "pbiColor('min', -0.5)"
  574.                       }
  575.                     }
  576.                   ],
  577.                   "value": "transparent"
  578.                 }
  579.               }
  580.             },
  581.             {
  582.               "name": "PLANNED_PHASE_BAR_START_SYMBOL",
  583.               "transform": [
  584.                 {
  585.                   "filter": "datum['_level'] == 1"
  586.                 }
  587.               ],
  588.               "mark": {
  589.                 "type": "tick",
  590.                 "thickness": 4,
  591.                 "xOffset": 2,
  592.                 "opacity": 1
  593.               },
  594.               "encoding": {
  595.                 "x": {
  596.                   "field": "_phase_min_planned_start_date",
  597.                   "type": "temporal"
  598.                 },
  599.                 "y": {
  600.                   "field": "WBS",
  601.                   "type": "ordinal",
  602.                   "axis": null
  603.                 },
  604.                 "color": {
  605.                   "condition": [
  606.                     {
  607.                       "test": "_show_planned",
  608.                       "value": {
  609.                         "expr": "pbiColor('min', -0.5)"
  610.                       }
  611.                     }
  612.                   ],
  613.                   "value": "transparent"
  614.                 }
  615.               }
  616.             },
  617.             {
  618.               "name": "PLANNED_PHASE_BAR_END_SYMBOL",
  619.               "transform": [
  620.                 {
  621.                   "filter": "datum['_level'] == 1"
  622.                 }
  623.               ],
  624.               "mark": {
  625.                 "type": "tick",
  626.                 "thickness": 4,
  627.                 "xOffset": -2,
  628.                 "opacity": 1
  629.               },
  630.               "encoding": {
  631.                 "x": {
  632.                   "field": "_phase_max_planned_end_date",
  633.                   "type": "temporal"
  634.                 },
  635.                 "y": {
  636.                   "field": "WBS",
  637.                   "type": "ordinal",
  638.                   "axis": null
  639.                 },
  640.                 "color": {
  641.                   "condition": [
  642.                     {
  643.                       "test": "_show_planned",
  644.                       "value": {
  645.                         "expr": "pbiColor('min', -0.5)"
  646.                       }
  647.                     }
  648.                   ],
  649.                   "value": "transparent"
  650.                 }
  651.               }
  652.             },
  653.             {
  654.               "name": "PLANNED_TASK_BAR",
  655.               "transform": [
  656.                 {
  657.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == false"
  658.                 }
  659.               ],
  660.               "mark": {
  661.                 "type": "bar",
  662.                 "height": {"band": 0.7},
  663.                 "yOffset": -4,
  664.                 "cornerRadius": 4
  665.               },
  666.               "encoding": {
  667.                 "x": {
  668.                   "field": "Planned Start Date",
  669.                   "type": "temporal"
  670.                 },
  671.                 "x2": {
  672.                   "field": "Planned End Date"
  673.                 },
  674.                 "y": {
  675.                   "field": "WBS",
  676.                   "type": "ordinal",
  677.                   "axis": null
  678.                 },
  679.                 "color": {
  680.                   "condition": [
  681.                     {
  682.                       "test": "_show_planned",
  683.                       "value": {
  684.                         "expr": "pbiColor('min', -0.25)"
  685.                       }
  686.                     }
  687.                   ],
  688.                   "value": "transparent"
  689.                 }
  690.               }
  691.             },
  692.             {
  693.               "name": "PLANNED_MILESTONE_SYMBOL",
  694.               "transform": [
  695.                 {
  696.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == true"
  697.                 }
  698.               ],
  699.               "mark": {
  700.                 "type": "square",
  701.                 "angle": 45,
  702.                 "height": {"band": 0.7},
  703.                 "opacity": 1,
  704.                 "yOffset": -4,
  705.                 "size": 200
  706.               },
  707.               "encoding": {
  708.                 "x": {
  709.                   "field": "Planned Start Date",
  710.                   "type": "temporal"
  711.                 },
  712.                 "y": {
  713.                   "field": "WBS",
  714.                   "type": "ordinal",
  715.                   "axis": null
  716.                 },
  717.                 "color": {
  718.                   "condition": [
  719.                     {
  720.                       "test": "_show_planned",
  721.                       "value": {
  722.                         "expr": "pbiColor('min', -0.25)"
  723.                       }
  724.                     }
  725.                   ],
  726.                   "value": "transparent"
  727.                 }
  728.               }
  729.             }
  730.           ]
  731.         },
  732.         {
  733.           "name": "ACTUAL_GANTT",
  734.           "layer": [
  735.             {
  736.               "name": "ACTUAL_PHASE_BAR_START_SYMBOL",
  737.               "transform": [
  738.                 {
  739.                   "filter": "datum['_level'] == 1"
  740.                 }
  741.               ],
  742.               "mark": {
  743.                 "type": "tick",
  744.                 "thickness": 4,
  745.                 "xOffset": 2,
  746.                 "yOffset": 4,
  747.                 "opacity": 1,
  748.                 "color": {
  749.                   "expr": "datum['_phase_actual_complete_percent'] > 0 ? 'black' : pbiColor(0, -0.5)"
  750.                 }
  751.               },
  752.               "encoding": {
  753.                 "x": {
  754.                   "field": "_phase_min_actual_start_date",
  755.                   "type": "temporal"
  756.                 },
  757.                 "y": {
  758.                   "field": "WBS",
  759.                   "type": "ordinal",
  760.                   "axis": null
  761.                 },
  762.                 "stroke": {
  763.                   "condition": [
  764.                     {
  765.                       "test": "_show_planned",
  766.                       "value": "black"
  767.                     }
  768.                   ],
  769.                   "value": "transparent"
  770.                 }
  771.               }
  772.             },
  773.             {
  774.               "name": "ACTUAL_PHASE_BAR_END_SYMBOL",
  775.               "transform": [
  776.                 {
  777.                   "filter": "datum['_level'] == 1"
  778.                 }
  779.               ],
  780.               "mark": {
  781.                 "type": "tick",
  782.                 "thickness": 4,
  783.                 "xOffset": -2,
  784.                 "yOffset": 4,
  785.                 "opacity": 1,
  786.                 "color": {
  787.                   "expr": "datum['_phase_actual_complete_percent'] == 1 ? 'black' : pbiColor(0, -0.5)"
  788.                 }
  789.               },
  790.               "encoding": {
  791.                 "x": {
  792.                   "field": "_phase_max_actual_end_date",
  793.                   "type": "temporal"
  794.                 },
  795.                 "y": {
  796.                   "field": "WBS",
  797.                   "type": "ordinal",
  798.                   "axis": null
  799.                 },
  800.                 "stroke": {
  801.                   "condition": [
  802.                     {
  803.                       "test": "_show_planned",
  804.                       "value": "black"
  805.                     }
  806.                   ],
  807.                   "value": "transparent"
  808.                 }
  809.               }
  810.             },
  811.             {
  812.               "name": "ACTUAL_PHASE_BAR_BACKGROUND",
  813.               "transform": [
  814.                 {
  815.                   "filter": "datum['_level'] == 1"
  816.                 }
  817.               ],
  818.               "mark": {
  819.                 "type": "bar",
  820.                 "height": {"band": 0.4},
  821.                 "yOffset": -2,
  822.                 "color": {
  823.                   "expr": "pbiColor(0, -0.5)"
  824.                 }
  825.               },
  826.               "encoding": {
  827.                 "x": {
  828.                   "field": "_phase_min_actual_start_date",
  829.                   "type": "temporal",
  830.                   "axis": {
  831.                     "orient": "top",
  832.                     "title": null,
  833.                     "labelPadding": 14,
  834.                     "labelAlign": "center",
  835.                     "labelExpr": "split( timeFormat(datum.value, '%b') + ' ' + timeFormat(datum.value, '%e'), ' ')"
  836.                   }
  837.                 },
  838.                 "x2": {
  839.                   "field": "_phase_max_actual_end_date"
  840.                 },
  841.                 "y": {
  842.                   "field": "WBS",
  843.                   "type": "ordinal",
  844.                   "axis": null
  845.                 },
  846.                 "stroke": {
  847.                   "condition": [
  848.                     {
  849.                       "test": "_show_planned",
  850.                       "value": "black"
  851.                     }
  852.                   ],
  853.                   "value": "transparent"
  854.                 }
  855.               }
  856.             },
  857.             {
  858.               "name": "ACTUAL_PHASE_BAR_PROGRESS",
  859.               "transform": [
  860.                 {
  861.                   "filter": "datum['_level'] == 1"
  862.                 }
  863.               ],
  864.               "mark": {
  865.                 "type": "bar",
  866.                 "height": {"band": 0.4},
  867.                 "yOffset": -2,
  868.                 "color": "black"
  869.               },
  870.               "encoding": {
  871.                 "x": {
  872.                   "field": "_phase_min_actual_start_date",
  873.                   "type": "temporal",
  874.                   "axis": {
  875.                     "orient": "top",
  876.                     "title": null,
  877.                     "labelPadding": 14,
  878.                     "labelAlign": "center",
  879.                     "labelExpr": "split( timeFormat(datum.value, '%b') + ' ' + timeFormat(datum.value, '%e'), ' ')"
  880.                   }
  881.                 },
  882.                 "x2": {
  883.                   "field": "_phase_estimated_progress_date"
  884.                 },
  885.                 "y": {
  886.                   "field": "WBS",
  887.                   "type": "ordinal",
  888.                   "axis": null
  889.                 },
  890.                 "stroke": {
  891.                   "condition": [
  892.                     {
  893.                       "test": "_show_planned",
  894.                       "value": "black"
  895.                     }
  896.                   ],
  897.                   "value": "transparent"
  898.                 }
  899.               }
  900.             },
  901.             {
  902.               "name": "ACTUAL_TASK_BAR_BACKGROUND",
  903.               "transform": [
  904.                 {
  905.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == false"
  906.                 }
  907.               ],
  908.               "mark": {
  909.                 "type": "bar",
  910.                 "height": {"band": 0.7},
  911.                 "yOffset": 0,
  912.                 "cornerRadius": 4,
  913.                 "color": {
  914.                   "expr": "pbiColor(0, -0.25)"
  915.                 }
  916.               },
  917.               "encoding": {
  918.                 "x": {
  919.                   "field": "Estimated Start Date",
  920.                   "type": "temporal"
  921.                 },
  922.                 "x2": {
  923.                   "field": "Estimated End Date"
  924.                 },
  925.                 "y": {
  926.                   "field": "WBS",
  927.                   "type": "ordinal",
  928.                   "axis": null
  929.                 },
  930.                 "stroke": {
  931.                   "condition": [
  932.                     {
  933.                       "test": "_show_planned",
  934.                       "value": "black"
  935.                     }
  936.                   ],
  937.                   "value": "transparent"
  938.                 }
  939.               }
  940.             },
  941.             {
  942.               "name": "ACTUAL_TASK_BAR_PROGRESS",
  943.               "transform": [
  944.                 {
  945.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == false"
  946.                 }
  947.               ],
  948.               "mark": {
  949.                 "type": "bar",
  950.                 "tooltip": {
  951.                   "content": "data"
  952.                 },
  953.                 "height": {"band": 0.2},
  954.                 "yOffset": 0,
  955.                 "cornerRadius": 4,
  956.                 "color": "black"
  957.               },
  958.               "encoding": {
  959.                 "x": {
  960.                   "field": "Estimated Start Date",
  961.                   "type": "temporal"
  962.                 },
  963.                 "x2": {
  964.                   "field": "_estimated_progress_date"
  965.                 },
  966.                 "y": {
  967.                   "field": "WBS",
  968.                   "type": "ordinal",
  969.                   "axis": null
  970.                 }
  971.               }
  972.             },
  973.             {
  974.               "name": "ACTUAL_MILESTONE_SYMBOL",
  975.               "transform": [
  976.                 {
  977.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == true"
  978.                 }
  979.               ],
  980.               "mark": {
  981.                 "type": "square",
  982.                 "angle": 45,
  983.                 "height": {"band": 0.7},
  984.                 "yOffset": 0,
  985.                 "opacity": 1,
  986.                 "size": 200,
  987.                 "color": {
  988.                   "expr": "datum['_milestone_actual_complete_percent'] == 1 ? 'black' : pbiColor(0, -0.5)"
  989.                 }
  990.               },
  991.               "encoding": {
  992.                 "x": {
  993.                   "field": "Estimated Start Date",
  994.                   "type": "temporal"
  995.                 },
  996.                 "y": {
  997.                   "field": "WBS",
  998.                   "type": "ordinal",
  999.                   "axis": null
  1000.                 },
  1001.                 "stroke": {
  1002.                   "condition": [
  1003.                     {
  1004.                       "test": "_show_planned",
  1005.                       "value": "black"
  1006.                     }
  1007.                   ],
  1008.                   "value": "transparent"
  1009.                 }
  1010.               }
  1011.             },
  1012.             {
  1013.               "name": "ACTUAL_PHASE_BAR_PROGRESS_TEXT",
  1014.               "transform": [
  1015.                 {
  1016.                   "filter": "datum['_level'] == 1"
  1017.                 }
  1018.               ],
  1019.               "mark": {
  1020.                 "type": "text",
  1021.                 "xOffset": 4,
  1022.                 "yOffset": 4,
  1023.                 "align": "left",
  1024.                 "baseline": "middle",
  1025.                 "color": {
  1026.                   "expr": "datum['_phase_actual_complete_percent'] == 0 ? 'transparent' : 'black'"
  1027.                 }
  1028.               },
  1029.               "encoding": {
  1030.                 "x": {
  1031.                   "field": "_phase_max_actual_end_date",
  1032.                   "type": "temporal"
  1033.                 },
  1034.                 "y": {
  1035.                   "field": "WBS",
  1036.                   "type": "ordinal",
  1037.                   "axis": null
  1038.                 },
  1039.                 "text": {
  1040.                   "field": "_phase_actual_complete_percent",
  1041.                   "type": "quantitative",
  1042.                   "format": ".0%"
  1043.                 }
  1044.               }
  1045.             },
  1046.             {
  1047.               "name": "ACTUAL_TASK_BAR_PROGRESS_TEXT",
  1048.               "transform": [
  1049.                 {
  1050.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == false"
  1051.                 }
  1052.               ],
  1053.               "mark": {
  1054.                 "type": "text",
  1055.                 "xOffset": 4,
  1056.                 "yOffset": 0,
  1057.                 "align": "left",
  1058.                 "baseline": "middle",
  1059.                 "color": {
  1060.                   "expr": "datum['_task_actual_complete_percent'] == 0 ? 'transparent' : 'black'"
  1061.                 }
  1062.               },
  1063.               "encoding": {
  1064.                 "x": {
  1065.                   "field": "Estimated End Date",
  1066.                   "type": "temporal"
  1067.                 },
  1068.                 "y": {
  1069.                   "field": "WBS",
  1070.                   "type": "ordinal",
  1071.                   "axis": null
  1072.                 },
  1073.                 "text": {
  1074.                   "field": "_task_actual_complete_percent",
  1075.                   "type": "quantitative",
  1076.                   "format": ".0%"
  1077.                 }
  1078.               }
  1079.             },
  1080.             {
  1081.               "name": "ACTUAL_MILESTONE_PROGRESS_TEXT",
  1082.               "transform": [
  1083.                 {
  1084.                   "filter": "datum['_level'] > 1 && datum['_is_milestone'] == true"
  1085.                 }
  1086.               ],
  1087.               "mark": {
  1088.                 "type": "text",
  1089.                 "xOffset": 14,
  1090.                 "yOffset": 0,
  1091.                 "align": "left",
  1092.                 "baseline": "middle",
  1093.                 "color": {
  1094.                   "expr": "datum['_milestone_actual_complete_percent'] == 0 ? 'transparent' : 'black'"
  1095.                 }
  1096.               },
  1097.               "encoding": {
  1098.                 "x": {
  1099.                   "field": "Estimated End Date",
  1100.                   "type": "temporal"
  1101.                 },
  1102.                 "y": {
  1103.                   "field": "WBS",
  1104.                   "type": "ordinal",
  1105.                   "axis": null
  1106.                 },
  1107.                 "text": {
  1108.                   "field": "_milestone_actual_complete_percent",
  1109.                   "type": "quantitative",
  1110.                   "format": ".0%"
  1111.                 }
  1112.               }
  1113.             }
  1114.           ]
  1115.         },
  1116.         {
  1117.           "name": "PROJECT_METRICS",
  1118.           "transform": [
  1119.             {
  1120.               "joinaggregate": [
  1121.                 {
  1122.                   "op": "min",
  1123.                   "field": "_phase_min_planned_start_date",
  1124.                   "as": "_project_planned_start_date"
  1125.                 }
  1126.               ]
  1127.             },
  1128.             {
  1129.               "joinaggregate": [
  1130.                 {
  1131.                   "op": "max",
  1132.                   "field": "_phase_max_planned_end_date",
  1133.                   "as": "_project_planned_end_date"
  1134.                 }
  1135.               ]
  1136.             },
  1137.             {
  1138.               "calculate": "( datum['_project_planned_end_date'] - datum['_project_planned_start_date'] ) / (24*60*60*1000)",
  1139.               "as": "_project_planned_days"
  1140.             },
  1141.             {
  1142.               "joinaggregate": [
  1143.                 {
  1144.                   "op": "min",
  1145.                   "field": "_phase_min_actual_start_date",
  1146.                   "as": "_project_actual_start_date"
  1147.                 }
  1148.               ]
  1149.             },
  1150.             {
  1151.               "joinaggregate": [
  1152.                 {
  1153.                   "op": "max",
  1154.                   "field": "_phase_max_actual_end_date",
  1155.                   "as": "_project_actual_end_date"
  1156.                 }
  1157.               ]
  1158.             },
  1159.             {
  1160.               "calculate": "( datum['_project_actual_end_date'] - datum['_project_actual_start_date'] ) / (24*60*60*1000)",
  1161.               "as": "_project_actual_days"
  1162.             },
  1163.             {
  1164.               "calculate": "datum['_project_actual_days'] - datum['_project_planned_days']",
  1165.               "as": "_project_variance_days"
  1166.             },
  1167.             {
  1168.               "calculate": "datum['_project_variance_days'] / datum['_project_planned_days']",
  1169.               "as": "_project_variance_percent"
  1170.             },
  1171.             {
  1172.               "calculate": "datum['_project_variance_days'] < 0 ? 'AHEAD OF SCHEDULE' : datum['_project_variance_days'] > 0 ? 'BEHIND SCHEDULE': 'ON SCHEDULE'",
  1173.               "as": "_project_schedule_status"
  1174.             },
  1175.             {
  1176.               "filter": "datum['ID'] <= 4"
  1177.             },
  1178.             {
  1179.               "calculate": "datum['ID'] == 1 ? -340 : datum['ID'] == 2 ? -320 : datum['ID'] == 3 ? -300 : datum['ID'] == 4 ? -280 : null",
  1180.               "as": "_metric_y"
  1181.             },
  1182.             {
  1183.               "calculate": "datum['ID'] == 1 ? 'Status:' : datum['ID'] == 2 ? 'Plan:' : datum['ID'] == 3 ? 'Actual:' : datum['ID'] == 4 ? 'Variance:' : null",
  1184.               "as": "_metric_label"
  1185.             },
  1186.             {
  1187.               "calculate": "datum['ID'] == 1 ? datum['_project_schedule_status'] : datum['ID'] == 2 ? timeFormat( datum['_project_planned_start_date'], '%b %e, %Y' ) + ' to ' + timeFormat( datum['_project_planned_end_date'], '%b %e, %Y' ) + ' (' + format( datum['_project_planned_days'], ',.0f' ) + ' days)' : datum['ID'] == 3 ? timeFormat( datum['_project_actual_start_date'], '%b %e, %Y' ) + ' to ' + timeFormat( datum['_project_actual_end_date'], '%b %e, %Y' ) + ' (' + format( datum['_project_actual_days'], ',.0f' ) + ' days)' : datum['ID'] == 4 ? format( datum['_project_variance_days'], ',.0f' ) + ' days (' + format( datum['_project_variance_percent'], '.0%' ) + ')' : null",
  1188.               "as": "_metric_value"
  1189.             }
  1190.           ],
  1191.           "layer": [
  1192.             {
  1193.               "name": "PROJECT_METRICS_BOX",
  1194.               "mark": {
  1195.                 "type": "rect",
  1196.                 "x": 400,
  1197.                 "x2": 900,
  1198.                 "y": 20,
  1199.                 "y2": 132,
  1200.                 "fill": "#F0F0F0",
  1201.                 "stroke": {
  1202.                   "expr": "datum['_project_variance_days'] < 0 ? pbiColor('positive') : datum['_project_variance_days'] > 0 ? pbiColor('negative') : 'black'"
  1203.                 },
  1204.                 "strokeWidth": 4
  1205.               },
  1206.               "encoding": {
  1207.                 "text": {
  1208.                   "field": "_project_metrics_multiline_text",
  1209.                   "type": "nominal"
  1210.                 }
  1211.               }
  1212.             },
  1213.             {
  1214.               "name": "PROJECT_METRICS_TITLE",
  1215.               "mark": {
  1216.                 "type": "text",
  1217.                 "x": 404,
  1218.                 "y": 35,
  1219.                 "align": "left",
  1220.                 "fontSize": 24,
  1221.                 "color": "black"
  1222.               },
  1223.               "encoding": {
  1224.                 "text": {
  1225.                   "value": "PROJECT METRICS"
  1226.                 }
  1227.               }
  1228.             },
  1229.             {
  1230.               "name": "PROJECT_METRICS_LABEL",
  1231.               "mark": {
  1232.                 "type": "text",
  1233.                 "x": 404,
  1234.                 "y": 400,
  1235.                 "yOffset": {
  1236.                   "expr": "datum['_metric_y']"
  1237.                 },
  1238.                 "align": "left",
  1239.                 "fontSize": 16,
  1240.                 "fontStyle": "italic",
  1241.                 "color": "black"
  1242.               },
  1243.               "encoding": {
  1244.                 "text": {
  1245.                   "field": "_metric_label",
  1246.                   "type": "nominal"
  1247.                 }
  1248.               }
  1249.             },
  1250.             {
  1251.               "name": "PROJECT_METRICS_VALUE",
  1252.               "mark": {
  1253.                 "type": "text",
  1254.                 "x": 510,
  1255.                 "y": 400,
  1256.                 "yOffset": {
  1257.                   "expr": "datum['_metric_y']"
  1258.                 },
  1259.                 "align": "left",
  1260.                 "fontSize": 16,
  1261.                 "fontStyle": "italic",
  1262.                 "color": "black"
  1263.               },
  1264.               "encoding": {
  1265.                 "text": {
  1266.                   "field": "_metric_value",
  1267.                   "type": "nominal"
  1268.                 }
  1269.               }
  1270.             }
  1271.           ]
  1272.         }
  1273.       ]
  1274.     }
  1275.   ]
  1276. }

Editor

You can edit this paste and save as new:


File Description
  • Deneb Gantt Chart
  • Paste Code
  • 24 Apr-2024
  • 39.34 Kb
You can Share it: