Skip to content

Instantly share code, notes, and snippets.

@Giammaria
Last active November 4, 2024 22:09
Show Gist options
  • Save Giammaria/6407a64ecfc4a9dbfb8670f56ecd820c to your computer and use it in GitHub Desktop.
Save Giammaria/6407a64ecfc4a9dbfb8670f56ecd820c to your computer and use it in GitHub Desktop.
20241029_sf_radial_readiness_v
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": {"signal": "backgroundRGB"},
"width": 500,
"padding": 10,
"usermeta": {
"developedBy": "Madison Giammaria",
"LinkedIn": "https://www.linkedin.com/in/madison-giammaria-58463b33",
"email": "[email protected]",
"inspiration": "https://sunny-edi.herokuapp.com/"
},
"signals": [
{"name": "dayInMilliseconds", "value": 86400000},
{
"name": "persistOVLColors",
"init": "false",
"on": [
{
"events": [
{"type": "keydown", "source": "window", "filter": "event.ctrlKey"}
],
"update": "!persistOVLColors"
}
]
},
{
"name": "showColorIndicatorsConfig",
"description": "configurations for the show color indicators toggle control",
"update": "{enabled: true, initialValue: false, xOffset: 40, track: {height: 7.5, width: 25, cornerRadius: 5, fill: '#EEE', stroke: '#777', strokeWidth: 1}, handle: {stroke: '#777', strokeWidth: 1, fill: '#fff'}, label: {text: 'Details', font: 'Segoe UI', fontSize: 12, fill: '#666', fontStyle: 'regular', dy: 10}, on: {fill: '#d1e0ec', fillOpacity: 1, stroke: '#777', strokeWidth: 1}, tooltip: {text: 'Show/hide indicator colors'}}"
},
{
"name": "xAxisOuterPaddingPercentage",
"description": "percentage of padding between x-axis and day text marks",
"value": 0.015
},
{
"name": "yearAxisRadius",
"description": "radius for the year axis domain",
"init": "min(width,height)/2.3"
},
{
"name": "monthAxisRadius",
"description": "radius for the month axis domain",
"init": "yearAxisRadius-25"
},
{
"name": "dayRadius",
"description": "radius for the day line (text) marks",
"init": "monthAxisRadius-6"
},
{
"name": "outerContentRadius",
"description": "radius for the content marks inside the radial axes",
"init": "dayRadius-50"
},
{
"name": "innerContentRadius",
"description": "radius for the content marks inside the radial axes",
"init": "outerContentRadius/2"
},
{
"name": "lightColor",
"description": "light color for theme as hex value",
"value": "#EEE"
},
{
"name": "mediumColor",
"description": "medium color for theme as hex value",
"value": "#AAA"
},
{
"name": "darkColor",
"description": "dark color for theme as hex value",
"value": "#999"
},
{
"name": "backgroundRGB",
"description": "rgb value of the canvas background",
"value": "#000"
},
{"name": "placementNumberOfRows", "value": 4},
{"name": "fleetPlacementRadialOffset", "init": "PI/20"},
{"name": "fleetIconSize", "value": 15},
{
"name": "hoverMonth",
"description": "datum of the currently focused month",
"init": "{FirstOfMonthDate: extent(pluck(data('dataset_exploded'), 'FirstOfMonthDate'))[1]}",
"on": [
{
"events": {
"type": "mouseover",
"markname": "month_axis_hover_interactive"
},
"update": "datum"
}
]
},
{
"name": "hoverUnit",
"description": "datum of the currently focused unit",
"init": "null",
"on": [
{
"events": {
"type": "mouseover",
"markname": "placement_interactive_arcs"
},
"update": "datum"
},
{
"events": {
"type": "mouseout",
"markname": "placement_interactive_arcs"
},
"update": "null"
}
]
},
{
"name": "height",
"description": "height of the canvas to match the width",
"update": "width"
},
{
"name": "showHelp",
"description": "boolean to show/hide the help. Toggle via double click",
"value": true,
"on": [{"events": {"type": "dblclick"}, "update": "!showHelp"}]
}
],
"marks": [
{
"name": "helper_text",
"description": "text to instruct the user to mouseover the chart",
"type": "text",
"interactive": false,
"encode": {
"enter": {
"x": {"signal": "0"},
"y": {"signal": "height*1.005"},
"fontStyle": {"value": "italic"},
"text": {
"signal": "['• Mouseover the radial', '‎ ‎ ‎timeline to explore', '• Press Ctrl to toggle', '‎ ‎ ‎C-Rate indicator colors']"
},
"fontSize": {"value": 12},
"fill": {"signal": "darkColor"},
"angle": {"value": 0}
},
"update": {"opacity": {"signal": "showHelp ? 1 : 0"}}
}
},
{
"name": "helper_arrow_text",
"description": "arrow pointing to the chart",
"type": "text",
"interactive": false,
"from": {"data": "helper_text"},
"encode": {
"enter": {
"x": {"signal": "datum['bounds']['x2']+2.5"},
"y": {"signal": "datum['bounds']['y1']+5"},
"baseline": {"value": "middle"},
"text": {"value": "⤴"},
"fontSize": {"value": 25},
"fill": {"signal": "darkColor"},
"angle": {"value": 0}
},
"update": {"opacity": {"signal": "showHelp ? 1 : 0"}}
}
},
{
"name": "day_bars",
"description": "colored pipe (|) text marks that serve as a daily indicator",
"from": {"data": "dataset_exploded"},
"interactive": false,
"type": "text",
"encode": {
"update": {
"x": {"signal": "width/2"},
"dx": {"signal": "datum.Day === 1 ? -1 : 0"},
"y": {"signal": "height/2"},
"text": {
"signal": "datum.Day === 1 ? '⯌' : datum.Day === 15 ? '|' : null"
},
"align": {"value": "center"},
"fontfamily": {"value": "consolas"},
"fontSize": {
"signal": "datum.Day === 1 || datum.IsLastDayOfMonth ? 10 : 5"
},
"fontWeight": {"value": 400},
"baseline": {"value": "top"},
"fill": {"signal": "mediumColor"},
"theta": {"scale": "dayAxisScale", "field": "Date"},
"radius": {"signal": "dayRadius"},
"angle": {"signal": "scale('dayAxisScale', datum['Date'])*(180/PI)"}
}
}
},
{
"name": "month_axis_domain",
"description": "month axis domain arcs",
"from": {"data": "day_bars"},
"interactive": false,
"transform": [
{
"type": "formula",
"expr": "datum.datum.datum.FirstOfMonthDate",
"as": "FirstOfMonthDate"
},
{"type": "formula", "expr": "datum['datum']['theta']", "as": "theta"},
{
"type": "joinaggregate",
"fields": ["theta", "theta"],
"ops": ["min", "max"],
"groupby": ["FirstOfMonthDate"],
"as": ["startAngle", "endAngle"]
},
{
"type": "formula",
"expr": "datum['startAngle']+(datum['endAngle']-datum['startAngle'])/2",
"as": "midAngle"
},
{
"type": "formula",
"expr": "datum['midAngle'] < PI/2 || datum['midAngle'] > PI*1.5 ? false : true",
"as": "flipLabel"
},
{
"type": "formula",
"expr": "datum.datum.datum.Day === 1 ? 1 : 0",
"as": "opacity"
},
{
"type": "formula",
"expr": "datum['opacity'] === 1 ? datum['Date'] : null",
"as": "Date"
}
],
"type": "arc",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"align": {"value": "center"},
"baseline": {"value": "top"},
"fill": {"signal": "darkColor"},
"startAngle": {"signal": "datum['datum']['startAngle']"},
"endAngle": {"signal": "datum['datum']['endAngle']"},
"innerRadius": {"signal": "monthAxisRadius-1.5"},
"outerRadius": {"signal": "monthAxisRadius"},
"opacity": {"field": "opacity"}
}
}
},
{
"name": "month_axis_hover_interactive",
"description": "month axis domain arcs that are used to capture the month and year",
"from": {"data": "month_axis_domain"},
"interactive": true,
"type": "arc",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"align": {"value": "center"},
"baseline": {"value": "top"},
"fill": {"signal": "lightColor"},
"startAngle": {
"signal": "datum['startAngle']-bandwidth('dayAxisScale')/2"
},
"endAngle": {
"signal": "datum['endAngle']+bandwidth('dayAxisScale')/2"
},
"innerRadius": {"signal": "monthAxisRadius-(min(width,height)/2)"},
"outerRadius": {"signal": "width/2"},
"opacity": {"value": 0}
}
}
},
{
"name": "month_axis_hover",
"description": "month axis domain arcs that appear on hover to indicate the currently focused month",
"from": {"data": "month_axis_domain"},
"interactive": false,
"type": "arc",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"align": {"value": "center"},
"baseline": {"value": "top"},
"fill": {"signal": "lightColor"},
"startAngle": {
"signal": "datum['startAngle']-bandwidth('dayAxisScale')/2"
},
"endAngle": {
"signal": "datum['endAngle']+bandwidth('dayAxisScale')/2"
},
"innerRadius": {"signal": "monthAxisRadius-(min(width,height)/2)"},
"outerRadius": {"signal": "monthAxisRadius+40"},
"opacity": {
"signal": "isValid(hoverMonth) && datum.FirstOfMonthDate === hoverMonth.FirstOfMonthDate && datum['opacity'] > 0 ? 0.3 : 0"
}
}
}
},
{
"name": "month_axis_label_hover",
"description": "month axis text labels that appear on hover to indicate the currently focused week",
"from": {"data": "month_axis_domain"},
"interactive": false,
"type": "text",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"dy": {"signal": "(datum['flipLabel'] ? -1 : 1) *-7.5"},
"fill": {"signal": "lightColor"},
"fontSize": {"value": 14},
"align": {"value": "center"},
"text": {
"signal": "(datum['flipLabel'] ? '⮘ ' : '') + utcFormat(datum.FirstOfMonthDate, '%b %y') + (datum['flipLabel'] ? '' : ' ⮚')"
},
"baseline": {"signal": "datum['flipLabel'] ? 'top': 'bottom'"},
"radius": {"signal": "monthAxisRadius+45"},
"theta": {"signal": "datum['midAngle']"},
"angle": {
"signal": "(datum['flipLabel'] ? (-1*PI/PI*180) : 0) + datum['midAngle']*(180/PI)"
},
"opacity": {
"signal": "isValid(hoverMonth) && datum.FirstOfMonthDate === hoverMonth.FirstOfMonthDate && datum['opacity'] > 0 ? 1 : 0"
}
}
}
},
{
"name": "year_axis_domain",
"description": "year axis domain arcs",
"from": {"data": "day_bars"},
"interactive": false,
"transform": [
{
"type": "formula",
"expr": "datum['datum']['datum']['Year']",
"as": "Year"
},
{"type": "formula", "expr": "datum['datum']['theta']", "as": "theta"},
{
"type": "joinaggregate",
"fields": ["theta", "theta"],
"ops": ["min", "max"],
"groupby": ["Year"],
"as": ["startAngle", "endAngle"]
},
{
"type": "formula",
"expr": "datum['startAngle']+(datum['endAngle']-datum['startAngle'])/2",
"as": "midAngle"
},
{
"type": "formula",
"expr": "datum['midAngle'] < PI/2 || datum['midAngle'] > PI*1.5 ? false : true",
"as": "flipLabel"
},
{
"type": "window",
"ops": ["dense_rank"],
"fields": ["Year"],
"groupby": ["startAngle"],
"as": ["startAngleDR"]
},
{
"type": "formula",
"expr": "datum['startAngleDR'] === 1 ? 1 : 0",
"as": "opacity"
},
{
"type": "formula",
"expr": "datum['opacity'] === 1 ? datum['Date'] : null",
"as": "Date"
}
],
"type": "arc",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"align": {"value": "center"},
"baseline": {"value": "top"},
"fill": {"signal": "lightColor"},
"startAngle": {"signal": "datum['datum']['startAngle']"},
"endAngle": {"signal": "datum['datum']['endAngle']"},
"innerRadius": {"signal": "yearAxisRadius-15"},
"outerRadius": {"signal": "yearAxisRadius"},
"opacity": {"field": "opacity"}
},
"hover": {"opacity": {"value": 0}}
}
},
{
"name": "year_axis_start_ticks",
"description": "pipe (|) text mark on the year axis that shows the start of a year",
"from": {"data": "year_axis_domain"},
"interactive": false,
"type": "text",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"fill": {"signal": "lightColor"},
"stroke": {"signal": "lightColor"},
"strokeWidth": {"value": 3},
"align": {"value": "left"},
"text": {"value": "▮"},
"fontSize": {"value": 15},
"baseline": {"value": "bottom"},
"radius": {"signal": "yearAxisRadius"},
"theta": {"field": "startAngle", "offset": {"value": -0.001}},
"angle": {"signal": "datum['startAngle']*(180/PI)"}
}
}
},
{
"name": "year_axis_end_ticks",
"description": "pipe (|) text mark on the year axis that shows the end of a year",
"from": {"data": "year_axis_domain"},
"interactive": false,
"type": "text",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"fill": {"signal": "lightColor"},
"stroke": {"signal": "lightColor"},
"strokeWidth": {"value": 3},
"align": {"value": "right"},
"text": {"value": "▮"},
"fontSize": {"value": 15},
"baseline": {"value": "bottom"},
"radius": {"signal": "yearAxisRadius"},
"theta": {"field": "endAngle", "offset": {"value": 0.003}},
"angle": {"signal": "datum['endAngle']*(180/PI)"}
}
}
},
{
"name": "year_axis_labels",
"description": "year axis text labels",
"from": {"data": "year_axis_domain"},
"interactive": false,
"type": "text",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"dy": {"signal": "(datum['flipLabel'] ? 1 : 0)"},
"fill": {"signal": "'#444'"},
"fontSize": {"value": 15},
"fontWeight": {"value": "500"},
"align": {"value": "center"},
"text": {"signal": "datum.Year"},
"baseline": {"signal": "datum['flipLabel'] ? 'top': 'bottom'"},
"radius": {"signal": "monthAxisRadius+9"},
"theta": {"signal": "datum['midAngle']"},
"angle": {
"signal": "(datum['flipLabel'] ? (-1*PI/PI*180) : 0) + datum['midAngle']*(180/PI)"
},
"opacity": {"signal": "datum['opacity']"}
}
}
},
{
"name": "outer_content_background",
"description": "a filled arc with the same color as the canvas background. This arc prevents the month hover arcs from obsecuring the line graphs",
"interactive": true,
"type": "arc",
"encode": {
"update": {
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"startAngle": {"value": 0},
"endAngle": {"signal": "2*PI"},
"innerRadius": {"value": 0},
"outerRadius": {"signal": "outerContentRadius"},
"fill": {"signal": "backgroundRGB"},
"stroke": {"signal": "darkColor"},
"strokeOpacity": {"value": 0.5}
}
}
},
{
"name": "placement_ready_group",
"description": "placement for the ready units",
"type": "group",
"interactive": false,
"encode": {
"update": {
"x": {"signal": "width/2 - outerContentRadius"},
"x2": {"signal": "width/2 + outerContentRadius"},
"y": {"signal": "height/2"},
"y2": {"signal": "height/2-outerContentRadius"},
"fill": {"value": "red"},
"fillOpacity": {"value": 0}
}
},
"marks": [
{
"name": "placement_interactive_arcs",
"from": {"data": "ready_placement"},
"type": "arc",
"interactive": true,
"encode": {
"update": {
"x": {"field": "cx"},
"y": {"field": "cy"},
"startAngle": {"field": "startAngle"},
"endAngle": {"field": "endAngle"},
"outerRadius": {
"field": "rowRadius",
"offset": {"signal": "bandwidth('xScaleReadyRow')/2"}
},
"innerRadius": {
"field": "rowRadius",
"offset": {"signal": "-bandwidth('xScaleReadyRow')/2"}
},
"fill": {"signal": "lightColor"},
"opacity": {"value": 0},
"tooltip": {
"signal": "{title: datum['Reporting Unit'], 'Field Comm': datum['Field Comm'], Delta: datum.Delta, 'C-Rate': isValid(datum.OVL) ? 'C-'+datum.OVL : 'N/A', 'Core Assmt.': datum.Assessment || 'N/A'}"
}
}
}
},
{
"from": {"data": "ready_placement"},
"type": "text",
"interactive": false,
"encode": {
"update": {
"x": {"field": "cx"},
"y": {"field": "cy"},
"dy": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? fleetIconSize/10 : 0"
},
"text": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? '𝅛' : '|'"
},
"theta": {"field": "theta"},
"radius": {"field": "rowRadius"},
"angle": {"field": "angle"},
"fontSize": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? fleetIconSize*1.5 : fleetIconSize"
},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {
"signal": "persistOVLColors || (isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit']) ? scale('scaleOVLColor', datum.OVL) : lightColor"
}
}
}
}
]
},
{
"name": "placement_not_ready_group",
"description": "placement for the units that are not ready",
"type": "group",
"interactive": false,
"encode": {
"update": {
"x": {"signal": "width/2 - outerContentRadius"},
"x2": {"signal": "width/2 + outerContentRadius"},
"y": {"signal": "height/2"},
"y2": {"signal": "height/2-outerContentRadius"},
"fill": {"value": "red"},
"fillOpacity": {"value": 0}
}
},
"marks": [
{
"name": "placement_interactive_arcs",
"from": {"data": "notReady_placement"},
"type": "arc",
"interactive": true,
"encode": {
"update": {
"x": {"field": "cx"},
"y": {"field": "cy"},
"startAngle": {"field": "startAngle"},
"endAngle": {"field": "endAngle"},
"outerRadius": {
"field": "rowRadius",
"offset": {"signal": "bandwidth('xScaleNotReadyRow')/2"}
},
"innerRadius": {
"field": "rowRadius",
"offset": {"signal": "-bandwidth('xScaleNotReadyRow')/2"}
},
"fill": {"signal": "lightColor"},
"opacity": {"value": 0},
"tooltip": {
"signal": "{title: datum['Reporting Unit'], 'Field Comm': datum['Field Comm'], Delta: datum.Delta, 'C-Rate': isValid(datum.OVL) ? 'C-'+datum.OVL : 'N/A', 'Core Assmt.': datum.Assessment || 'N/A'}"
}
}
}
},
{
"from": {"data": "notReady_placement"},
"type": "text",
"interactive": false,
"encode": {
"update": {
"x": {"field": "cx"},
"y": {"field": "cy"},
"dy": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? fleetIconSize/10 : 0"
},
"text": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? '𝅛' : '|'"
},
"theta": {"field": "theta"},
"radius": {"field": "rowRadius"},
"angle": {"field": "angle"},
"fontSize": {
"signal": "isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit'] ? fleetIconSize*1.5 : fleetIconSize"
},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {
"signal": "persistOVLColors || (isValid(hoverUnit) && datum['Reporting Unit'] === hoverUnit['Reporting Unit']) ? scale('scaleOVLColor', datum.OVL) : '#666'"
}
}
}
}
]
},
{
"name": "group_ready_text",
"type": "group",
"from": {"data": "unit_aggregates"},
"interactive": false,
"encode": {
"update": {
"x": {"signal": "width/2-innerContentRadius/1.5"},
"x2": {"signal": "width/2+innerContentRadius/1.5"},
"y": {"signal": "height/2-innerContentRadius/1.5"},
"y2": {"signal": "height/2+innerContentRadius/1.5"}
}
},
"marks": [
{
"name": "ready_percentage_text",
"type": "text",
"interactive": false,
"encode": {
"update": {
"x": {"signal": "(innerContentRadius/1.5)"},
"y": {"signal": "(innerContentRadius/1.5)"},
"dy": {"signal": "-innerContentRadius/2.15"},
"text": {
"signal": "[format(parent.readyCount/parent.totalCount, '.2%'), '']"
},
"fill": {"value": "#CCC"},
"baseline": {"value": "middle"},
"align": {"value": "center"},
"fontSize": {"value": 19},
"fontWeight": {"value": 500}
}
}
},
{
"name": "ready_readytext",
"type": "text",
"interactive": false,
"encode": {
"update": {
"x": {"signal": "(innerContentRadius/1.5)"},
"y": {"signal": "(innerContentRadius/1.5)"},
"dy": {"signal": "-innerContentRadius/2.15"},
"text": {"signal": "['', 'Ready']"},
"fill": {"value": "#CCC"},
"baseline": {"value": "middle"},
"align": {"value": "center"},
"lineHeight": {"value": 19},
"fontSize": {"value": 14},
"fontWeight": {"value": 500}
}
}
},
{
"name": "ready_count_text",
"type": "text",
"interactive": false,
"encode": {
"update": {
"x": {"signal": "(innerContentRadius/1.5)"},
"y": {"signal": "(innerContentRadius/1.5)"},
"dy": {"signal": "innerContentRadius/3.5"},
"text": {
"signal": "[parent.readyCount + ' / ' + parent.totalCount, 'Reporting Units']"
},
"fill": {"signal": "mediumColor"},
"baseline": {"value": "middle"},
"align": {"value": "center"},
"fontSize": {"value": 12}
}
}
}
]
}
],
"legends": [
{
"stroke": "scaleIsReadyColor",
"orient": "none",
"legendX": {"signal": "width-200"},
"legendY": {"signal": "height+28"},
"direction": "horizontal",
"symbolType": "stroke",
"encode": {
"symbols": {
"update": {
"angle": {"value": 90},
"size": {"value": 200},
"opacity": {"signal": "persistOVLColors ? 0 : 1"}
}
},
"labels": {
"update": {
"fill": {"signal": "scale('scaleIsReadyColor', datum.value)"},
"text": {"signal": "datum.value ? 'Ready' : 'Not Ready'"},
"fontSize": {"value": 13},
"opacity": {"signal": "persistOVLColors ? 0 : 1"}
}
}
}
},
{
"stroke": "scaleOVLColor",
"symbolType": "stroke",
"orient": "none",
"legendX": {"signal": "width-300"},
"legendY": {"signal": "height+28"},
"direction": "horizontal",
"encode": {
"symbols": {
"update": {
"angle": {"value": 90},
"size": {"value": 200},
"opacity": {"signal": "persistOVLColors ? 1 : 0"}
}
},
"labels": {
"update": {
"fill": {"signal": "scale('scaleOVLColor', datum.value)"},
"text": {"signal": "'C-'+datum.value"},
"fontSize": {"value": 13},
"opacity": {"signal": "persistOVLColors ? 1 : 0"}
}
}
}
}
],
"scales": [
{
"name": "dayAxisScale",
"type": "band",
"domain": {
"data": "dataset_exploded",
"field": "Date",
"sort": {"field": "Date"}
},
"range": [0, {"signal": "2*PI"}],
"paddingInner": {"signal": "xAxisOuterPaddingPercentage"},
"paddingOuter": {"signal": "xAxisOuterPaddingPercentage/2"}
},
{
"name": "xScaleReadyRow",
"type": "band",
"domain": {"signal": "sequence(1,placementNumberOfRows+1)"},
"range": {"signal": "[outerContentRadius-innerContentRadius, 0]"},
"padding": 0
},
{
"name": "xScaleNotReadyRow",
"type": "band",
"domain": {"signal": "sequence(1,placementNumberOfRows+1)"},
"range": {"signal": "[outerContentRadius-innerContentRadius, 0]"},
"padding": 0
},
{
"name": "scaleIsReadyColor",
"type": "ordinal",
"domain": [true, false],
"range": [
{"signal": "lightColor"},
"#666"
]
},
{
"name": "scaleOVLColor",
"type": "ordinal",
"domain": [1, 2, 3, 4, 5],
"range": [
"#59805C",
"#4CAF50 ",
"#FFEB3B ",
"#F44336",
{"signal": "mediumColor"}
]
}
],
"data": [
{
"name": "dataset",
"url": "https://raw.githubusercontent.com/Giammaria/PublicFiles/refs/heads/master/data/sf-notional-dataset.csv",
"format": {
"type": "csv",
"parse": {
"Field Comm": "string",
"Delta": "string",
"Reporting Unit": "string",
"Location": "string",
"Capability": "string",
"Component": "string",
"Squadron Type": "string",
"Mission": "string",
"Date": "date",
"P": "number",
"S": "number",
"R": "number",
"T": "number",
"OVL": "number",
"Override C-Rating": "number",
"Assessment": "string",
"Primary Degraders": "string",
"Secondary Degraders": "string",
"Month Look Back": "number",
"Last Month Lookback Filter": "string",
"Details Max Date": "date"
}
},
"transform": [
{"type": "filter", "expr": "datum.Mission === 'CORE'"},
{
"type": "window",
"ops": ["dense_rank"],
"groupby": ["Date"],
"as": ["dr"]
},
{"type": "filter", "expr": "datum.dr >= 100 && datum.dr < 335"},
{
"type": "project",
"fields": [
"Date",
"Reporting Unit",
"Field Comm",
"Delta",
"OVL",
"Assessment"
],
"as": [
"Date",
"Reporting Unit",
"Field Comm",
"Delta",
"OVL",
"Assessment"
]
}
]
},
{
"name": "dataset_formatted",
"source": "dataset",
"transform": [
{
"type": "formula",
"expr": "+utcFormat(datum.Date, '%Y')",
"as": "Year"
},
{
"type": "formula",
"expr": "+utcFormat(datum.Date, '%m')",
"as": "MonthNumber"
},
{
"type": "formula",
"expr": "utcFormat(datum.Date, '%B')",
"as": "Month"
},
{
"type": "formula",
"expr": "utcFormat(datum.Date, '%b')",
"as": "MonthAbbreviation"
},
{
"type": "formula",
"expr": "toDate(utcFormat(datum.Date, '01-%b-%Y 00:00:00.000'))",
"as": "FirstOfMonthDate"
}
]
},
{
"name": "dataset_exploded",
"source": "dataset_formatted",
"transform": [
{
"type": "formula",
"expr": "toDate(utcFormat(timeOffset('day', timeOffset('month', datum.FirstOfMonthDate, 1), -1), '%d-%b-%Y 00:00:00.000'))",
"as": "LastOfMonthDate"
},
{
"type": "formula",
"expr": "round((datum.LastOfMonthDate-datum.FirstOfMonthDate)/dayInMilliseconds)+1",
"as": "Days"
},
{
"type": "aggregate",
"ops": ["count"],
"groupby": [
"Year",
"Month",
"MonthAbbreviation",
"Days",
"FirstOfMonthDate",
"LastOfMonthDate"
],
"as": ["count"]
},
{"type": "formula", "expr": "sequence(0, datum.Days, 1)", "as": "Day"},
{"type": "flatten", "fields": ["Day"]},
{
"type": "formula",
"expr": "timeOffset('day', datum.FirstOfMonthDate, datum['Day'])",
"as": "Date"
},
{"type": "formula", "expr": "datum.Day + 1", "as": "Day"},
{
"type": "formula",
"expr": "utcFormat(datum.Date, '%b%d') === utcFormat(datum.LastOfMonthDate, '%b%d')",
"as": "IsLastDayOfMonth"
},
{
"type": "project",
"fields": [
"FirstOfMonthDate",
"Date",
"Year",
"Month",
"MonthAbbreviation",
"Day",
"IsLastDayOfMonth"
]
}
]
},
{
"name": "detail_data",
"source": "dataset_formatted",
"transform": [
{
"type": "filter",
"expr": "datum.FirstOfMonthDate === hoverMonth.FirstOfMonthDate"
},
{"type": "formula", "expr": "datum.OVL <= 2", "as": "isReady"},
{"type": "collect", "sort": {"field": "OVL"}},
{
"type": "window",
"ops": ["dense_rank"],
"groupby": ["isReady"],
"as": ["index"]
}
]
},
{
"name": "unit_aggregates",
"source": "detail_data",
"transform": [
{
"type": "aggregate",
"ops": ["count"],
"groupby": ["isReady"],
"as": ["rowCount"]
},
{"type": "pivot", "field": "isReady", "value": "rowCount"},
{"type": "formula", "expr": "datum.true", "as": "readyCount"},
{"type": "formula", "expr": "datum.false", "as": "notReadyCount"},
{
"type": "formula",
"expr": "datum.readyCount+datum.notReadyCount",
"as": "totalCount"
},
{
"type": "project",
"fields": ["readyCount", "notReadyCount", "totalCount"]
}
]
},
{
"name": "ready_placement",
"source": "detail_data",
"transform": [
{"type": "filter", "expr": "datum.isReady"},
{
"type": "formula",
"expr": "datum.index%placementNumberOfRows === 0 ? placementNumberOfRows : datum.index%placementNumberOfRows",
"as": "row"
},
{
"type": "formula",
"expr": "scale('xScaleReadyRow', datum.row)",
"as": "rowStartX"
},
{
"type": "formula",
"expr": "(outerContentRadius*2)-scale('xScaleReadyRow', datum.row)-bandwidth('xScaleReadyRow')",
"as": "rowEndX"
},
{
"type": "window",
"ops": ["dense_rank"],
"groupby": ["row"],
"as": ["seat"]
},
{
"type": "joinaggregate",
"ops": ["count"],
"groupby": ["row"],
"as": ["seatCount"]
},
{
"type": "joinaggregate",
"ops": ["max"],
"fields": ["seatCount"],
"as": ["seatCount"]
},
{
"type": "formula",
"expr": "(datum.rowEndX - datum.rowStartX)/2",
"as": "rowRadius"
},
{
"type": "formula",
"expr": "(fleetPlacementRadialOffset/2)+(datum.seat/datum.seatCount)*(PI-fleetPlacementRadialOffset)-PI/2",
"as": "theta"
},
{"type": "formula", "expr": "datum.theta*(180/PI)", "as": "angle"},
{"type": "formula", "expr": "outerContentRadius", "as": "cx"},
{
"type": "formula",
"expr": "(height/2)-(height/2-outerContentRadius)",
"as": "cy"
},
{
"type": "window",
"ops": ["lag", "lead"],
"fields": ["theta", "theta"],
"groupby": ["row", "row"],
"as": ["lagTheta", "leadTheta"]
},
{
"type": "formula",
"expr": "isValid(datum.leadTheta) && isValid(datum.lagTheta) ? (datum.leadTheta - datum.lagTheta)/2 : null",
"as": "thetaBandWidth"
},
{
"type": "joinaggregate",
"ops": ["mean"],
"fields": ["thetaBandWidth"],
"as": ["thetaBandWidth"]
},
{
"type": "formula",
"expr": "datum.theta-(datum.thetaBandWidth/2)",
"as": "startAngle"
},
{
"type": "formula",
"expr": "datum.theta+(datum.thetaBandWidth/2)",
"as": "endAngle"
}
]
},
{
"name": "notReady_placement",
"source": "detail_data",
"transform": [
{"type": "filter", "expr": "!datum.isReady"},
{
"type": "formula",
"expr": "datum.index%placementNumberOfRows === 0 ? placementNumberOfRows : datum.index%placementNumberOfRows",
"as": "row"
},
{
"type": "formula",
"expr": "scale('xScaleNotReadyRow', datum.row)",
"as": "rowStartX"
},
{
"type": "formula",
"expr": "(outerContentRadius*2)-scale('xScaleNotReadyRow', datum.row)-bandwidth('xScaleNotReadyRow')",
"as": "rowEndX"
},
{
"type": "window",
"ops": ["dense_rank"],
"groupby": ["row"],
"as": ["seat"]
},
{
"type": "joinaggregate",
"ops": ["count"],
"groupby": ["row"],
"as": ["seatCount"]
},
{
"type": "joinaggregate",
"ops": ["max"],
"fields": ["seatCount"],
"as": ["seatCount"]
},
{
"type": "formula",
"expr": "(datum.rowEndX - datum.rowStartX)/2",
"as": "rowRadius"
},
{
"type": "formula",
"expr": "((fleetPlacementRadialOffset/2)+(datum.seat/datum.seatCount)*(PI-fleetPlacementRadialOffset)-PI/2)+PI",
"as": "theta"
},
{"type": "formula", "expr": "datum.theta*(180/PI)", "as": "angle"},
{"type": "formula", "expr": "outerContentRadius", "as": "cx"},
{
"type": "formula",
"expr": "(height/2)-(height/2-outerContentRadius)",
"as": "cy"
},
{
"type": "window",
"ops": ["lag", "lead"],
"fields": ["theta", "theta"],
"groupby": ["row", "row"],
"as": ["lagTheta", "leadTheta"]
},
{
"type": "formula",
"expr": "isValid(datum.leadTheta) && isValid(datum.lagTheta) ? (datum.leadTheta - datum.lagTheta)/2 : null",
"as": "thetaBandWidth"
},
{
"type": "joinaggregate",
"ops": ["mean"],
"fields": ["thetaBandWidth"],
"as": ["thetaBandWidth"]
},
{
"type": "formula",
"expr": "datum.BandWidth || 0.11",
"as": "thetaBandWidth"
},
{
"type": "formula",
"expr": "datum.theta-(datum.thetaBandWidth/2)",
"as": "startAngle"
},
{
"type": "formula",
"expr": "datum.theta+(datum.thetaBandWidth/2)",
"as": "endAngle"
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment