Last active
November 11, 2024 15:02
-
-
Save Giammaria/094ee84b221121693da892f852732f57 to your computer and use it in GitHub Desktop.
20241104_MET_Measure_Aggregation_Bar_Chart_v
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "$schema": "https://vega.github.io/schema/vega/v5.json", | |
| "width": 1100, | |
| "height": 500, | |
| "background": "#000", | |
| "view": {"stroke": "transparent"}, | |
| "signals": [ | |
| {"name": "yStep", "value": 71}, | |
| {"name": "visibleItems", "update": "ceil(height / yStep)"}, | |
| { | |
| "name": "asPercentage", | |
| "init": "configAsPercentage.initialValue", | |
| "on": [ | |
| { | |
| "events": "@group_asPercentageToggle:pointerdown", | |
| "update": "!asPercentage" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "granularityLevel", | |
| "init": "configGranularityButtons.initialValue", | |
| "on": [ | |
| { | |
| "events": "@granularity_level_button_background:pointerdown", | |
| "update": "datum.datum.name" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "configVerticalScrollbar", | |
| "description": "configurations for the vertical scroll bar", | |
| "update": "{enabled: actualHeight>height,innerPadding: 10, track: {width: 10, height: extent([actualHeight, height])[0], fill: '#232323', stroke: '#444'}, handle: {height: max((height/actualHeight)*extent([actualHeight, height])[0], 30), fill: '#999', hover: {fill: '#CCC'}}}" | |
| }, | |
| { | |
| "name": "configGranularityButtons", | |
| "description": "configurations for the granularity level button controls", | |
| "init": "{initialValue: 'MET', padding: 5, yOffset: 2.5, label: {text: 'Granularity', font: 'Segoe UI', fontSize: 12, fill: mediumColor, fontStyle: 'regular', dy: 15}, outerStroke: '#777', fill: lightColor, selectedFill: '#b5cae1'}" | |
| }, | |
| { | |
| "name": "sortBy", | |
| "init": "configSortButtons.initialValue", | |
| "on": [ | |
| { | |
| "events": "@sort_button_background:pointerdown", | |
| "update": "datum.datum.name" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "sortByClickCount", | |
| "init": "0", | |
| "on": [ | |
| { | |
| "events": "@sort_button_background:pointerdown", | |
| "update": "sortByClickCount+1" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "sortByChange", | |
| "value": false, | |
| "update": "isValid(data('sortByChange')) && length(data('sortByChange')) > 0 ? data('sortByChange')[0]['change'] : sortByChange" | |
| }, | |
| { | |
| "name": "sortOrder", | |
| "value": "descending", | |
| "update": "isValid(data('sortByChange')) && length(data('sortByChange')) > 0 ? data('sortByChange')[0].sortOrder : sortOrder" | |
| }, | |
| { | |
| "name": "sortDirectionMet", | |
| "value": "descending", | |
| "on": [ | |
| { | |
| "events": "@sort_button_background:pointerdown{0, 100}", | |
| "update": "sortByChange ? sortDirectionMet : datum.datum.name === 'Criteria Met' ? sortDirectionMet === 'descending' ? 'ascending' : 'descending' : sortDirectionMet" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "sortDirectionNotMet", | |
| "value": "descending", | |
| "on": [ | |
| { | |
| "events": "@sort_button_background:pointerdown{0, 100}", | |
| "update": "sortByChange ? sortDirectionNotMet : datum.datum.name === 'Criteria Not Met' ? sortDirectionNotMet === 'descending' ? 'ascending' : 'descending' : sortDirectionNotMet" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "configSortButtons", | |
| "description": "configurations for the sort level button controls", | |
| "init": "{initialValue: 'Criteria Not Met', padding: 5, yOffset: 2.5, label: {text: 'Sort', font: 'Segoe UI', fontSize: 12, fill: mediumColor, fontStyle: 'regular', dy: 15}, outerStroke: '#777', fill: lightColor, selectedFill: '#b5cae1'}" | |
| }, | |
| { | |
| "name": "configAsPercentage", | |
| "description": "configurations for the 'as percentage' toggle control", | |
| "update": "{enabled: true, initialValue: false, xOffset: 40, track: {height: 7.5, width: 25, cornerRadius: 5, fill: lightColor, stroke: '#777', strokeWidth: 1}, handle: {stroke: '#777', strokeWidth: 1, fill: '#fff'}, label: {text: 'Percentage', font: 'Segoe UI', fontSize: 12, fill: mediumColor, fontStyle: 'regular', dy: 11.5}, on: {fill: '#b5cae1', fillOpacity: 1, stroke: '#777', strokeWidth: 1}, tooltip: {text: 'Toggle between counts and percentages'}}" | |
| }, | |
| { | |
| "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": "#777" | |
| }, | |
| { | |
| "name": "backgroundRGB", | |
| "description": "rgb value of the canvas background", | |
| "value": "#000" | |
| }, | |
| { | |
| "name": "verticalScrollbarMouseDown", | |
| "description": "boolean indicating whether the vertical scrollbar is currently being clicked", | |
| "value": false, | |
| "on": [ | |
| { | |
| "events": "@group_verticalScrollbar:pointerdown", | |
| "update": "configVerticalScrollbar.enabled" | |
| }, | |
| { | |
| "events": { | |
| "type": "mouseout", | |
| "scope": "view", | |
| "markname": "group_verticalScrollbar", | |
| "filter": ["!event.pointerdown"] | |
| }, | |
| "update": "false" | |
| }, | |
| { | |
| "events": { | |
| "type": "mouseover", | |
| "scope": "scope", | |
| "markname": "group_verticalScrollbar", | |
| "filter": ["event.pointerdown"] | |
| }, | |
| "update": "true" | |
| }, | |
| {"events": {"type": "pointerup"}, "update": "false"} | |
| ] | |
| }, | |
| { | |
| "name": "verticalScrollbarMouseOver", | |
| "description": "boolean indicating whether the vertical scrollbar is currently being moused over", | |
| "value": false, | |
| "on": [ | |
| { | |
| "events": "@group_verticalScrollbar:mouseover", | |
| "update": "configVerticalScrollbar.enabled" | |
| }, | |
| {"events": "@group_verticalScrollbar:mouseout", "update": "false"} | |
| ] | |
| }, | |
| { | |
| "name": "verticalScrollPercent", | |
| "description": "the percentage of the current vertical scroll", | |
| "value": 0, | |
| "on": [ | |
| { | |
| "events": { | |
| "type": "wheel", | |
| "consume": true, | |
| "filter": ["!event.ctrlKey", "!event.shiftKey"] | |
| }, | |
| "update": "!configVerticalScrollbar.enabled ? 0 : clamp(verticalScrollPercent - (-event.deltaY * pow(3, event.deltaMode) * 0.00015), 0,(actualHeight-height+yStep)/actualHeight)" | |
| }, | |
| { | |
| "events": "@group_verticalScrollbar:pointerdown", | |
| "update": "!configVerticalScrollbar.enabled ? 0 : invert('scaleScrollHandleY', y(group()))" | |
| }, | |
| { | |
| "events": { | |
| "type": "pointermove", | |
| "source": "scope", | |
| "markname": "group_verticalScrollbar", | |
| "between": [{"type": "pointerdown"}, {"type": "pointerup"}] | |
| }, | |
| "update": "!configVerticalScrollbar.enabled ? 0 : verticalScrollbarMouseDown && isValid(group()) ? invert('scaleScrollHandleY', clamp(y(group()), configVerticalScrollbar.handle.height, configVerticalScrollbar.track.height)) : verticalScrollPercent" | |
| }, | |
| { | |
| "events": { | |
| "type": "pointermove", | |
| "source": "scope", | |
| "markname": "group_verticalScrollbar", | |
| "between": [{"type": "pointerdown"}, {"type": "mouseout"}] | |
| }, | |
| "update": "!configVerticalScrollbar.enabled ? 0 : isValid(group()) ? invert('scaleScrollHandleY', clamp(y(group()), configVerticalScrollbar.handle.height, configVerticalScrollbar.track.height)) : verticalScrollPercent" | |
| }, | |
| { | |
| "events": {"signal": "!configVerticalScrollbar.enabled"}, | |
| "update": "0" | |
| }, | |
| { | |
| "events": "@granularity_level_button_background:pointerdown", | |
| "update": "0" | |
| }, | |
| {"events": "@sort_button_background:pointerdown", "update": "0"} | |
| ] | |
| }, | |
| { | |
| "name": "yHoverDatum", | |
| "init": "null", | |
| "on": [ | |
| { | |
| "events": "mouseover", | |
| "update": "isValid(datum) && isValid(datum.yLabel) ? datum : null" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "unit", | |
| "value": {}, | |
| "on": [ | |
| {"events": "pointermove", "update": "isTuple(group()) ? group() : {}"} | |
| ] | |
| }, | |
| { | |
| "name": "selection", | |
| "update": "vlSelectionResolve('selection_store', 'union', true, true)" | |
| }, | |
| { | |
| "name": "selection_tuple", | |
| "on": [ | |
| { | |
| "events": [{"source": "scope", "type": "click"}], | |
| "update": "datum && item().mark.marktype !== 'group' && indexof(item().mark.role, 'legend') < 0 ? {_vgsid_: datum['_vgsid_'], datum: datum} : null", | |
| "force": true | |
| }, | |
| { | |
| "events": [{"source": "view", "type": "click"}], | |
| "update": "!datum ? null : selection_tuple", | |
| "force": true | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "selectionCount", | |
| "update": "isValid(selection) && isValid(selection.vlPoint) && isValid(selection.vlPoint.or) ? length(selection.vlPoint.or) : 0" | |
| }, | |
| { | |
| "name": "ctrlKey", | |
| "init": "false", | |
| "on": [ | |
| { | |
| "events": [{"type": "mousemove", "filter": "event.ctrlKey"}], | |
| "update": "true" | |
| }, | |
| { | |
| "events": [{"type": "mousemove", "filter": "!event.ctrlKey"}], | |
| "update": "false" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "submitSelections", | |
| "value": false, | |
| "on": [ | |
| { | |
| "events": [{"source": "scope", "type": "click"}], | |
| "update": "datum && isValid(datum['_vgsid_']) ? true : false", | |
| "force": true | |
| }, | |
| { | |
| "events": [{"source": "view", "type": "click"}], | |
| "update": "!datum ? true : submitSelections", | |
| "force": true | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "selection_modify", | |
| "on": [ | |
| { | |
| "events": {"signal": "selection_tuple"}, | |
| "update": "submitSelections ? modify('selection_store', null, (!ctrlKey ? true : null), isValid(selection_tuple) && isValid(selection_tuple['_vgsid_']) && isValid(selection_tuple.datum) ? selection_tuple.datum : null) : null" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "highlightIds", | |
| "init": "[]", | |
| "on": [ | |
| { | |
| "events": [{"signal": "selection"}], | |
| "update": "isValid(selection) && isValid(selection.vlPoint) && isValid(selection.vlPoint.or) ? pluck(selection.vlPoint.or, '_vgsid_') : []" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "horizontalRange", | |
| "description": "the range used in the x-axis scale for the Gantt", | |
| "update": "[0, width-(configVerticalScrollbar.enabled ? configVerticalScrollbar.innerPadding*2 : 0)]" | |
| }, | |
| { | |
| "name": "actualHeight", | |
| "description": "height of all rows if not cut off by vertical scrolling", | |
| "update": "(data('preYDomain')[0].rc+visibleItems) * yStep" | |
| } | |
| ], | |
| "marks": [ | |
| { | |
| "type": "group", | |
| "clip": true, | |
| "marks": [ | |
| { | |
| "name": "y_item_hover_rect_Label", | |
| "type": "rect", | |
| "from": {"data": "yDomain"}, | |
| "interactive": true, | |
| "encode": { | |
| "update": { | |
| "tooltip": { | |
| "signal": "{'title': granularityLevel + ': ' + datum.yLabel, 'Count': datum.Count + ' reporting units'}" | |
| }, | |
| "x": {"value": 0}, | |
| "x2": {"signal": "horizontalRange[1]"}, | |
| "y": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[0]" | |
| }, | |
| "y2": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[1]" | |
| }, | |
| "fill": {"value": "transparent"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "y_item_hover_rect", | |
| "type": "rect", | |
| "from": {"data": "yDomain"}, | |
| "interactive": true, | |
| "encode": { | |
| "update": { | |
| "tooltip": { | |
| "signal": "{'title': granularityLevel + ': ' + datum.yLabel, 'Count': datum.Count + ' reporting units'}" | |
| }, | |
| "x": {"value": 0}, | |
| "x2": {"signal": "scale('xScaleCount', datum.Count)"}, | |
| "y": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[0]" | |
| }, | |
| "y2": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[1]" | |
| }, | |
| "fill": {"value": "transparent"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "total_rect", | |
| "type": "rect", | |
| "from": {"data": "yDomain"}, | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "tooltip": {"signal": "datum.ySort"}, | |
| "x": {"value": 0}, | |
| "x2": {"signal": "scale('xScaleCount', datum.Count)"}, | |
| "y": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[0]" | |
| }, | |
| "y2": { | |
| "signal": "scale('yScale', datum.ySort) + range('subYAxisScale')[1]" | |
| }, | |
| "fill": {"signal": "'#444'"}, | |
| "stroke": { | |
| "signal": "isValid(yHoverDatum) && isValid(yHoverDatum.ySort) && yHoverDatum.ySort === datum.ySort ? '#888' : '#666'" | |
| }, | |
| "strokeWidth": { | |
| "signal": "isValid(yHoverDatum) && isValid(yHoverDatum.ySort) && yHoverDatum.ySort === datum.ySort ? 2 : 1" | |
| }, | |
| "opacity": { | |
| "signal": "asPercentage ? 0 : isValid(highlightIds) ? length(highlightIds) > 0 ? indexof(highlightIds, datum['_vgsid_']) >= 0 ? 1 : 0.5 : 1 : 1" | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| "name": "yAxisLabel", | |
| "type": "text", | |
| "from": {"data": "yDomain"}, | |
| "encode": { | |
| "update": { | |
| "y": {"scale": "yScale", "field": "ySort"}, | |
| "dy": {"value": 2.5}, | |
| "text": {"signal": "datum.yLabel"}, | |
| "fill": {"signal": "lightColor"}, | |
| "fillOpacity": { | |
| "signal": "isValid(yHoverDatum) && isValid(yHoverDatum.ySort) && yHoverDatum.ySort === datum.ySort ? 1 : 0.85" | |
| }, | |
| "fontWeight": { | |
| "signal": "isValid(yHoverDatum) && isValid(yHoverDatum.ySort) && yHoverDatum.ySort === datum.ySort ? 600 : 400" | |
| }, | |
| "baseline": {"value": "top"}, | |
| "limit": {"signal": "horizontalRange[1]"}, | |
| "opacity": { | |
| "signal": "length(data('selection_store'))>0 ? indexof(pluck(data('selection_store'), 'yLabel'), datum['yLabel']) >= 0 ? 1 : 0.5 : 1" | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| "name": "criteria_met_bars", | |
| "type": "group", | |
| "from": { | |
| "facet": { | |
| "data": "bars", | |
| "groupby": ["yLabel", "ySort", "Count"], | |
| "name": "criteria_met_facet" | |
| } | |
| }, | |
| "marks": [ | |
| { | |
| "name": "criteria_met_rects", | |
| "type": "rect", | |
| "from": {"data": "criteria_met_facet"}, | |
| "encode": { | |
| "update": { | |
| "tooltip": { | |
| "signal": "{'title': granularityLevel + ': ' + datum.yLabel, 'Count': datum['Sub Count'] + ' out of ' + datum.Count + ' reporting units with criteria ' + (datum['Criteria Met'] === 'N' ? 'not' : '') + ' met', '%': format(datum['Percentage'], '.0%')+ ' reporting units with criteria ' + (datum['Criteria Met'] === 'N' ? 'not' : '') + ' met'}" | |
| }, | |
| "x": {"value": 0}, | |
| "x2": { | |
| "signal": "asPercentage ? scale('xScalePercentage', datum['Percentage']) : scale('xScaleCount', datum['Sub Count'])" | |
| }, | |
| "y": { | |
| "signal": "scale('yScale', datum['ySort']) + scale('subYAxisScale', datum['Criteria Met'])" | |
| }, | |
| "height": {"signal": "bandwidth('subYAxisScale')"}, | |
| "stroke": {"value": "#000"}, | |
| "strokeWidth": { | |
| "signal": "isValid(yHoverDatum) && isValid(yHoverDatum.ySort) && yHoverDatum.ySort === datum.ySort ? 2 : 1" | |
| }, | |
| "opacity": { | |
| "signal": "isValid(highlightIds) ? length(highlightIds) > 0 ? indexof(highlightIds, datum['_vgsid_']) >= 0 || indexof(highlightIds, datum['parent_vgsid_']) >= 0 ? 1 : 0.5 : 1 : 1" | |
| }, | |
| "fill": {"signal": "datum.Fill"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "header_group", | |
| "type": "group", | |
| "encode": {"update": {"x": {"signal": "0"}, "y": {"value": -65}}}, | |
| "marks": [ | |
| { | |
| "name": "group_granularityLevelButtons", | |
| "type": "group", | |
| "marks": [ | |
| { | |
| "name": "labelText", | |
| "type": "text", | |
| "encode": { | |
| "update": { | |
| "text": {"signal": "configGranularityButtons.label.text"}, | |
| "baseline": {"value": "bottom"}, | |
| "font": {"signal": "configGranularityButtons.label.font"}, | |
| "fontSize": { | |
| "signal": "configGranularityButtons.label.fontSize" | |
| }, | |
| "fontStyle": { | |
| "signal": "configGranularityButtons.label.fontStyle" | |
| }, | |
| "align": {"value": "left"}, | |
| "fill": {"signal": "configGranularityButtons.label.fill"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "granularity_level_dummy_labels", | |
| "description": "text marks that will be used by other button marks for reactive geometry", | |
| "type": "text", | |
| "from": {"data": "granularityLevelConfig"}, | |
| "interactive": false, | |
| "encode": { | |
| "enter": { | |
| "x": { | |
| "signal": "configGranularityButtons.padding+datum.rowNumber*31.5" | |
| }, | |
| "y": { | |
| "signal": "configGranularityButtons.yOffset+configGranularityButtons.label.dy" | |
| }, | |
| "fontSize": { | |
| "signal": "configGranularityButtons.label.fontSize-2" | |
| }, | |
| "text": {"field": "label"}, | |
| "fill": {"value": "#666"}, | |
| "opacity": {"value": 0} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "granularity_level_button_background", | |
| "description": "the background for the expand/collapse buttons", | |
| "type": "rect", | |
| "from": {"data": "granularity_level_dummy_labels"}, | |
| "interactive": true, | |
| "encode": { | |
| "update": { | |
| "x": { | |
| "signal": "datum.bounds.x1-configGranularityButtons.padding" | |
| }, | |
| "x2": { | |
| "signal": "datum.bounds.x2+configGranularityButtons.padding" | |
| }, | |
| "y": { | |
| "signal": "datum.bounds.y1-configGranularityButtons.padding" | |
| }, | |
| "y2": { | |
| "signal": "datum.bounds.y2+configGranularityButtons.padding" | |
| }, | |
| "cornerRadiusTopLeft": { | |
| "signal": "datum.datum.rowNumber == 0 ? 5 : 0" | |
| }, | |
| "cornerRadiusBottomLeft": { | |
| "signal": "datum.datum.rowNumber == 0 ? 5 : 0" | |
| }, | |
| "cornerRadiusTopRight": { | |
| "signal": "datum.datum.rowNumber == 1 ? 5 : 0" | |
| }, | |
| "cornerRadiusBottomRight": { | |
| "signal": "datum.datum.rowNumber == 1 ? 5 : 0" | |
| }, | |
| "fillOpacity": {"value": 1}, | |
| "strokeWidth": {"value": 1}, | |
| "fill": { | |
| "signal": "datum.datum.name === granularityLevel ? configGranularityButtons.selectedFill : configGranularityButtons.fill" | |
| }, | |
| "opacity": {"value": 1}, | |
| "cursor": {"value": "pointer"}, | |
| "tooltip": {"signal": "datum.datum.tooltip"} | |
| }, | |
| "hover": {"opacity": {"value": 0.9}} | |
| } | |
| }, | |
| { | |
| "name": "granularity_level_labels", | |
| "description": "text marks that will be used by other button marks for reactive geometry", | |
| "type": "text", | |
| "from": {"data": "granularity_level_dummy_labels"}, | |
| "interactive": false, | |
| "encode": { | |
| "enter": { | |
| "x": {"signal": "datum.x"}, | |
| "y": {"signal": "datum.y"}, | |
| "text": {"signal": "datum.datum.label"}, | |
| "fontSize": {"signal": "datum.fontSize"}, | |
| "fill": {"value": "#333"}, | |
| "opacity": {"value": 1} | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "group_sortLevelButtons", | |
| "type": "group", | |
| "from": {"data": "group_granularityLevelButtons"}, | |
| "encode": {"update": {"x": {"signal": "datum.bounds.x2+15"}}}, | |
| "marks": [ | |
| { | |
| "name": "labelText", | |
| "type": "text", | |
| "encode": { | |
| "update": { | |
| "text": {"signal": "configSortButtons.label.text"}, | |
| "baseline": {"value": "bottom"}, | |
| "font": {"signal": "configSortButtons.label.font"}, | |
| "fontSize": {"signal": "configSortButtons.label.fontSize"}, | |
| "fontStyle": {"signal": "configSortButtons.label.fontStyle"}, | |
| "align": {"value": "left"}, | |
| "fill": {"signal": "configSortButtons.label.fill"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "sort_dummy_labels", | |
| "description": "text marks that will be used by other button marks for reactive geometry", | |
| "type": "text", | |
| "from": {"data": "sortConfig"}, | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "x": { | |
| "signal": "configSortButtons.padding+datum.rowNumber*35" | |
| }, | |
| "y": { | |
| "signal": "configSortButtons.yOffset+configSortButtons.label.dy" | |
| }, | |
| "fontSize": {"signal": "configSortButtons.label.fontSize-2"}, | |
| "text": { | |
| "signal": "datum.label + (datum.name === 'Criteria Met' ? (sortDirectionMet === 'descending' ? '▾' : '▴') : (sortDirectionNotMet === 'descending' ? '▾' : '▴'))" | |
| }, | |
| "fill": {"value": "#666"}, | |
| "opacity": {"value": 0} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "sort_button_background", | |
| "description": "the background for the expand/collapse buttons", | |
| "type": "rect", | |
| "from": {"data": "sort_dummy_labels"}, | |
| "interactive": true, | |
| "encode": { | |
| "update": { | |
| "x": {"signal": "datum.bounds.x1-configSortButtons.padding"}, | |
| "x2": {"signal": "datum.bounds.x2+configSortButtons.padding"}, | |
| "y": {"signal": "datum.bounds.y1-configSortButtons.padding"}, | |
| "y2": {"signal": "datum.bounds.y2+configSortButtons.padding"}, | |
| "cornerRadiusTopLeft": { | |
| "signal": "datum.datum.rowNumber == 0 ? 5 : 0" | |
| }, | |
| "cornerRadiusBottomLeft": { | |
| "signal": "datum.datum.rowNumber == 0 ? 5 : 0" | |
| }, | |
| "cornerRadiusTopRight": { | |
| "signal": "datum.datum.rowNumber == 1 ? 5 : 0" | |
| }, | |
| "cornerRadiusBottomRight": { | |
| "signal": "datum.datum.rowNumber == 1 ? 5 : 0" | |
| }, | |
| "fillOpacity": {"value": 1}, | |
| "strokeWidth": {"value": 1}, | |
| "fill": { | |
| "signal": "datum.datum.name === sortBy ? configSortButtons.selectedFill : configSortButtons.fill" | |
| }, | |
| "opacity": {"value": 1}, | |
| "cursor": {"value": "pointer"}, | |
| "tooltip": { | |
| "signal": "replace(datum.datum.tooltip, 'by criteria','by '+(asPercentage ? 'percentage' : 'count' )+' of criteria')" | |
| } | |
| }, | |
| "hover": {"opacity": {"value": 0.9}} | |
| } | |
| }, | |
| { | |
| "name": "sort_labels", | |
| "description": "text marks that will be used by other button marks for reactive geometry", | |
| "type": "text", | |
| "from": {"data": "sort_dummy_labels"}, | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "x": {"signal": "datum.x"}, | |
| "y": {"signal": "datum.y"}, | |
| "text": {"signal": "datum.text"}, | |
| "fontSize": {"signal": "datum.fontSize"}, | |
| "fill": {"value": "#333"}, | |
| "opacity": {"value": 1} | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "group_asPercentageToggle", | |
| "description": "group for the marks that make up the toggle control to show as percentage vs count percentage", | |
| "type": "group", | |
| "from": {"data": "group_sortLevelButtons"}, | |
| "interactive": true, | |
| "clip": false, | |
| "encode": { | |
| "update": { | |
| "x": {"signal": "datum.datum.bounds.x2+120"}, | |
| "y": {"signal": "datum.datum.bounds.y1+1"}, | |
| "height": {"signal": "30"}, | |
| "width": {"signal": "configAsPercentage.track.width"}, | |
| "fill": {"value": "transparent"}, | |
| "tooltip": {"signal": "configAsPercentage.tooltip.text"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| }, | |
| "marks": [ | |
| { | |
| "name": "asPercentageToggle_text", | |
| "description": "the title for the toggle control", | |
| "type": "text", | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "text": {"signal": "configAsPercentage.label.text || ''"}, | |
| "baseline": {"value": "top"}, | |
| "font": {"signal": "configAsPercentage.label.font"}, | |
| "fontSize": {"signal": "configAsPercentage.label.fontSize"}, | |
| "fontStyle": {"signal": "configAsPercentage.label.fontStyle"}, | |
| "align": {"value": "left"}, | |
| "fill": {"signal": "configAsPercentage.label.fill"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "track_rect", | |
| "description": "the track for the toggle control", | |
| "type": "rect", | |
| "from": {"data": "asPercentageToggle_text"}, | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "y": { | |
| "signal": "datum.bounds.y2+configAsPercentage.label.dy" | |
| }, | |
| "height": {"signal": "configAsPercentage.track.height"}, | |
| "x": {"signal": "0"}, | |
| "x2": {"signal": "configAsPercentage.track.width"}, | |
| "cornerRadius": { | |
| "signal": "configAsPercentage.track.cornerRadius" | |
| }, | |
| "fill": { | |
| "signal": "asPercentage ? configAsPercentage.on.fill : configAsPercentage.track.fill" | |
| }, | |
| "stroke": {"signal": "configAsPercentage.track.stroke"}, | |
| "strokeWidth": { | |
| "signal": "configAsPercentage.track.strokeWidth" | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| "name": "toggle_outer_arc", | |
| "description": "the circle mark that serves as the the 'toggle handle'", | |
| "from": {"data": "asPercentageToggle_text"}, | |
| "type": "arc", | |
| "interactive": false, | |
| "encode": { | |
| "enter": { | |
| "y": { | |
| "signal": "datum.bounds.y2+configAsPercentage.label.dy+configAsPercentage.track.height/2" | |
| }, | |
| "innerRadius": {"value": 0}, | |
| "outerRadius": { | |
| "signal": "configAsPercentage.track.height*0.9" | |
| }, | |
| "startAngle": {"signal": "0"}, | |
| "endAngle": {"signal": "2*PI"}, | |
| "stroke": { | |
| "signal": "configAsPercentage.handle.stroke || '#BBB'" | |
| }, | |
| "strokeWidth": { | |
| "signal": "configAsPercentage.handle.strokeWidth" | |
| }, | |
| "fill": {"signal": "configAsPercentage.handle.fill || '#fff'"} | |
| }, | |
| "update": { | |
| "x": { | |
| "signal": "asPercentage ? configAsPercentage.track.width-configAsPercentage.track.cornerRadius : configAsPercentage.track.cornerRadius" | |
| } | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "group_verticalScrollbar", | |
| "description": "the group of marks that make up the vertical scrollbar", | |
| "type": "group", | |
| "clip": true, | |
| "encode": { | |
| "update": { | |
| "x": { | |
| "signal": "verticalScrollbarMouseDown ? 0 : width-configVerticalScrollbar.track.width" | |
| }, | |
| "width": { | |
| "signal": "configVerticalScrollbar.enabled ? verticalScrollbarMouseDown ? width+configVerticalScrollbar.track.width : configVerticalScrollbar.track.width : 0" | |
| }, | |
| "y": {"value": 0}, | |
| "height": { | |
| "signal": "configVerticalScrollbar.enabled ? configVerticalScrollbar.track.height : 0" | |
| }, | |
| "fill": {"value": "transparent"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| }, | |
| "marks": [ | |
| { | |
| "name": "rect_verticalScrollbar_track", | |
| "description": "the track for the scrollbar", | |
| "type": "rect", | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "x": { | |
| "signal": "verticalScrollbarMouseDown ? width-configVerticalScrollbar.track.width : 0" | |
| }, | |
| "width": { | |
| "signal": "configVerticalScrollbar.enabled ? configVerticalScrollbar.track.width : 0" | |
| }, | |
| "y": {"value": 0}, | |
| "height": { | |
| "signal": "configVerticalScrollbar.enabled ? configVerticalScrollbar.track.height : 0" | |
| }, | |
| "fill": {"signal": "configVerticalScrollbar.track.fill"}, | |
| "stroke": {"signal": "configVerticalScrollbar.track.stroke"}, | |
| "cursor": {"value": "pointer"} | |
| } | |
| } | |
| }, | |
| { | |
| "name": "rect_verticalScrollbar_handle", | |
| "description": "the handle for the scrollbar", | |
| "type": "rect", | |
| "interactive": false, | |
| "encode": { | |
| "update": { | |
| "x": { | |
| "signal": "verticalScrollbarMouseDown ? width-configVerticalScrollbar.track.width : 0" | |
| }, | |
| "width": { | |
| "signal": "configVerticalScrollbar.enabled ? configVerticalScrollbar.track.width : 0" | |
| }, | |
| "y": { | |
| "signal": "scale('scaleScrollHandleY', verticalScrollPercent)-configVerticalScrollbar.handle.height" | |
| }, | |
| "y2": { | |
| "signal": "scale('scaleScrollHandleY', verticalScrollPercent)" | |
| }, | |
| "fill": { | |
| "signal": "verticalScrollbarMouseOver ? configVerticalScrollbar.handle.hover.fill : configVerticalScrollbar.handle.fill" | |
| }, | |
| "cursor": {"value": "pointer"} | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| ], | |
| "scales": [ | |
| { | |
| "name": "yScale", | |
| "type": "band", | |
| "domain": {"data": "yDomain", "field": "ySort", "sort": true}, | |
| "range": {"step": {"signal": "yStep"}}, | |
| "paddingInner": 0.15, | |
| "paddingOuter": 0 | |
| }, | |
| { | |
| "name": "subYAxisScale", | |
| "type": "band", | |
| "domain": { | |
| "data": "bars", | |
| "field": "Criteria Met", | |
| "sort": {"field": "Criteria Met Sub Sort"} | |
| }, | |
| "range": {"signal": "[17.5, bandwidth('yScale')]"}, | |
| "padding": 0.2 | |
| }, | |
| { | |
| "name": "scaleScrollHandleY", | |
| "type": "linear", | |
| "domain": [0, {"signal": "(actualHeight-height)/actualHeight"}], | |
| "range": { | |
| "signal": "[configVerticalScrollbar.handle.height, configVerticalScrollbar.track.height]" | |
| }, | |
| "clamp": true | |
| }, | |
| { | |
| "name": "xScaleCount", | |
| "type": "linear", | |
| "domain": {"data": "dataset_formatted", "fields": ["Count", "Sub Count"]}, | |
| "range": {"signal": "horizontalRange"}, | |
| "zero": true | |
| }, | |
| { | |
| "name": "xScalePercentage", | |
| "type": "linear", | |
| "domain": [0, 1], | |
| "range": {"signal": "horizontalRange"}, | |
| "zero": true | |
| }, | |
| { | |
| "name": "colorScale", | |
| "type": "ordinal", | |
| "domain": {"signal": "asPercentage ? ['Y', 'N'] : ['Y', 'N', 'Total']"}, | |
| "range": { | |
| "signal": "asPercentage ? ['#4CAF50', '#F44336'] : ['#4CAF50', '#F44336', '#242424']" | |
| } | |
| } | |
| ], | |
| "axes": [ | |
| { | |
| "scale": "xScaleCount", | |
| "orient": "top", | |
| "title": { | |
| "signal": "['Count of Reporting Units', 'with Criteria Met vs. Not Met']" | |
| }, | |
| "titleOpacity": {"signal": "(asPercentage ? 0 : 1)"}, | |
| "titlePadding": 25, | |
| "titleLineHeight": 20, | |
| "titleFontSize": 14, | |
| "domainOpacity": {"signal": "(asPercentage ? 0 : 1)"}, | |
| "domainColor": {"signal": "darkColor"}, | |
| "labelColor": {"signal": "mediumColor"}, | |
| "labelOpacity": { | |
| "signal": "datum.value%1 === 0 ? (asPercentage ? 0 : 1) : 0" | |
| }, | |
| "tickDash": [2, 4], | |
| "tickColor": {"signal": "darkColor"}, | |
| "titleColor": {"signal": "mediumColor"}, | |
| "tickOpacity": { | |
| "signal": "datum.value%1 === 0 ? (asPercentage ? 0 : 1) : 0" | |
| }, | |
| "grid": true, | |
| "gridColor": {"signal": "darkColor"}, | |
| "gridDash": [2, 4], | |
| "gridOpacity": { | |
| "signal": "datum.value%1 === 0 ? (asPercentage ? 0 : 1) : 0" | |
| }, | |
| "encode": { | |
| "labels": {"update": {"text": {"signal": "format(datum.value, '.0f')"}}} | |
| } | |
| }, | |
| { | |
| "scale": "xScalePercentage", | |
| "orient": "top", | |
| "title": { | |
| "signal": "['Percentage of Reporting Units', 'with Criteria Met vs. Not Met']" | |
| }, | |
| "titleOpacity": {"signal": "(asPercentage ? 1 : 0)"}, | |
| "titlePadding": 25, | |
| "titleLineHeight": 20, | |
| "titleFontSize": 14, | |
| "domainOpacity": {"signal": "(asPercentage ? 1 : 0)"}, | |
| "domainColor": {"signal": "darkColor"}, | |
| "labelColor": {"signal": "mediumColor"}, | |
| "labelOpacity": {"signal": "(asPercentage ? 1 : 0)"}, | |
| "tickDash": [2, 4], | |
| "tickColor": {"signal": "darkColor"}, | |
| "titleColor": {"signal": "mediumColor"}, | |
| "tickOpacity": {"signal": "(asPercentage ? 1 : 0)"}, | |
| "grid": true, | |
| "gridColor": {"signal": "darkColor"}, | |
| "gridDash": [2, 4], | |
| "gridOpacity": {"signal": "(asPercentage ? 1 : 0)"}, | |
| "encode": { | |
| "labels": {"update": {"text": {"signal": "format(datum.value, '.0%')"}}} | |
| } | |
| } | |
| ], | |
| "legends": [ | |
| { | |
| "fill": "colorScale", | |
| "orient": "none", | |
| "legendX": {"signal": "width -(asPercentage ? 76 : 126)"}, | |
| "legendY": {"signal": "-55"}, | |
| "symbolType": "square", | |
| "direction": "horizontal", | |
| "labelColor": "#eee", | |
| "encode": { | |
| "symbols": { | |
| "update": { | |
| "stroke": { | |
| "signal": "datum.value === 'Total' ? '#666' : 'transparent'" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ], | |
| "data": [ | |
| { | |
| "name": "dataset", | |
| "url": "https://raw.githubusercontent.com/Giammaria/PublicFiles/refs/heads/master/data/sf-notional-MET-standards-dataset.csv", | |
| "format": { | |
| "type": "tsv", | |
| "parse": { | |
| "Field Comm": "string", | |
| "Delta": "string", | |
| "Reporting Unit": "string", | |
| "Location": "string", | |
| "Capability": "string", | |
| "Component": "string", | |
| "Squadron Type": "string", | |
| "Mission": "string", | |
| "Task Number": "string", | |
| "Task Title": "string", | |
| "Task Full Name": "string", | |
| "MET Display Title": "string", | |
| "MET Analytics Series": "string", | |
| "MET Analytics Code": "string", | |
| "MET Analytics Name": "string", | |
| "MET Analytics Sort": "number", | |
| "MET Measure Full Name": "string", | |
| "Measure": "string", | |
| "Criteria Met": "string", | |
| "REMARK": "string" | |
| } | |
| } | |
| }, | |
| { | |
| "name": "dataset_formatted", | |
| "source": "dataset", | |
| "transform": [ | |
| { | |
| "type": "formula", | |
| "expr": "granularityLevel === 'MET' ? datum['Task Full Name'] : datum['MET Measure Full Name']", | |
| "as": "yLabel" | |
| }, | |
| { | |
| "type": "aggregate", | |
| "fields": ["Criteria Met"], | |
| "groupby": ["yLabel", "Criteria Met"], | |
| "as": ["Sub Count"] | |
| }, | |
| { | |
| "type": "joinaggregate", | |
| "fields": ["Sub Count"], | |
| "ops": ["sum"], | |
| "groupby": ["yLabel"], | |
| "as": ["Count"] | |
| }, | |
| { | |
| "type": "pivot", | |
| "field": "Criteria Met", | |
| "value": "Sub Count", | |
| "groupby": ["yLabel", "Count"] | |
| }, | |
| {"type": "formula", "expr": "datum.N || 0", "as": "N"}, | |
| {"type": "formula", "expr": "datum.Y || 0", "as": "Y"}, | |
| {"type": "formula", "expr": "datum.Y", "as": "Count of Criteria Met"}, | |
| { | |
| "type": "formula", | |
| "expr": "datum.N", | |
| "as": "Count of Criteria Not Met" | |
| }, | |
| { | |
| "type": "fold", | |
| "fields": ["N", "Y"], | |
| "as": ["Criteria Met", "Sub Count"] | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "(datum['Sub Count'] || 0)/datum.Count", | |
| "as": "Percentage" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "sortBy === 'Criteria Met' ? indexof(['Y', 'Q', 'N'], datum['Criteria Met']) : indexof(['N', 'Q', 'Y'], datum['Criteria Met'])", | |
| "as": "Criteria Met Sort" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "['#4CAF50', '#FFEB3B', '#F44336'][indexof(['Y', 'Q', 'N'], datum['Criteria Met'])]", | |
| "as": "Fill" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "indexof(['Y', 'Q', 'N'], datum['Criteria Met'])", | |
| "as": "Criteria Met Sub Sort" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "preYDomain", | |
| "source": "dataset_formatted", | |
| "transform": [ | |
| { | |
| "type": "formula", | |
| "expr": "asPercentage ? datum.Percentage : datum['Sub Count']", | |
| "as": "valueForSort" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "sortBy === 'Criteria Met' ? datum['Criteria Met'] === 'Y' ? datum.valueForSort * (sortOrder === 'descending' ? 1000 : 1) : datum.valueForSort * (sortOrder === 'descending' ? 1 : 1000) : datum['Criteria Met'] === 'N' ? datum.valueForSort * (sortOrder === 'descending' ? 1000 : 1) : datum.valueForSort * (sortOrder === 'descending' ? 1 : 1000) ", | |
| "as": "ySortVal" | |
| }, | |
| { | |
| "type": "project", | |
| "fields": [ | |
| "yLabel", | |
| "ySortVal", | |
| "Count", | |
| "Count of Criteria Met", | |
| "Count of Criteria Not Met" | |
| ] | |
| }, | |
| { | |
| "type": "aggregate", | |
| "ops": ["max"], | |
| "fields": ["ySortVal"], | |
| "groupby": [ | |
| "yLabel", | |
| "Count", | |
| "Count of Criteria Met", | |
| "Count of Criteria Not Met" | |
| ], | |
| "as": ["ySortVal"] | |
| }, | |
| { | |
| "type": "window", | |
| "ops": ["row_number"], | |
| "sort": {"field": "ySortVal", "order": {"signal": "sortOrder"}}, | |
| "as": ["ySort"] | |
| }, | |
| {"type": "collect", "sort": {"field": "ySort"}}, | |
| { | |
| "type": "joinaggregate", | |
| "ops": ["distinct"], | |
| "fields": ["yLabel"], | |
| "as": ["rc"] | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "+(granularityLevel === 'MET' ? -1 : 1) * datum.ySort", | |
| "as": "_vgsid_" | |
| }, | |
| {"type": "formula", "expr": "'y'", "as": "barType"} | |
| ] | |
| }, | |
| { | |
| "name": "yDomain", | |
| "source": "preYDomain", | |
| "transform": [ | |
| { | |
| "type": "filter", | |
| "expr": "datum.ySort >= floor(verticalScrollPercent * (datum.rc)) && datum.ySort <= ceil((verticalScrollPercent * (datum.rc)) + visibleItems)" | |
| }, | |
| {"type": "collect", "sort": {"field": "ySort"}} | |
| ] | |
| }, | |
| { | |
| "name": "bars", | |
| "source": "dataset_formatted", | |
| "transform": [ | |
| {"type": "formula", "expr": "'criteria'", "as": "barType"}, | |
| { | |
| "type": "lookup", | |
| "from": "yDomain", | |
| "key": "yLabel", | |
| "fields": ["yLabel"], | |
| "values": ["ySort", "_vgsid_"], | |
| "as": ["ySort", "parent_vgsid_"] | |
| }, | |
| { | |
| "type": "filter", | |
| "expr": "indexof(domain('yScale'), datum.ySort) >=0" | |
| }, | |
| { | |
| "type": "window", | |
| "ops": ["row_number"], | |
| "sort": {"field": "ySortVal", "order": {"signal": "sortOrder"}}, | |
| "as": ["_vgsid_"] | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "(granularityLevel === 'MET' ? -1 : 1) * (datum._vgsid_ + length(data('preYDomain')))", | |
| "as": "_vgsid_" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "granularityLevelConfig", | |
| "values": [ | |
| { | |
| "rowNumber": 0, | |
| "name": "MET", | |
| "label": "MET", | |
| "tooltip": "Criteria met by MET" | |
| }, | |
| { | |
| "rowNumber": 1, | |
| "name": "Measure", | |
| "label": "Measure", | |
| "tooltip": "Criteria met by measure" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "sortConfig", | |
| "values": [ | |
| { | |
| "rowNumber": 0, | |
| "name": "Criteria Met", | |
| "label": "Met", | |
| "tooltip": "Sort by criteria met" | |
| }, | |
| { | |
| "rowNumber": 1, | |
| "name": "Criteria Not Met", | |
| "label": "Not Met", | |
| "tooltip": "Sort by criteria not met" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "sortByChange", | |
| "on": [ | |
| { | |
| "trigger": "sortByClickCount", | |
| "remove": false, | |
| "insert": "{sortBy: sortBy, timestamp: now(), sortOrder: sortBy === 'Criteria Met' ? (sortDirectionMet === 'descending' ? 'descending' : 'ascending') : sortDirectionNotMet === 'descending' ? 'descending' : 'ascending'}" | |
| } | |
| ], | |
| "transform": [ | |
| { | |
| "type": "window", | |
| "ops": ["row_number"], | |
| "sort": {"field": "timestamp", "order": "descending"}, | |
| "as": ["rn"] | |
| }, | |
| {"type": "filter", "expr": "datum.rn<=2"}, | |
| { | |
| "type": "window", | |
| "ops": ["lag", "max"], | |
| "fields": ["sortBy", "rn"], | |
| "as": ["lagSortBy", "rowCt"] | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "datum.rowCt === 1 && configSortButtons.initialValue!==datum.sortBy ? true : datum.rn === 1 && datum.rowCt === 2 && isValid(datum.lagSortBy) && datum.sortBy !== datum.lagSortBy", | |
| "as": "change" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "datum.rn === 1 ? datum.sortOrder : null", | |
| "as": "sortOrder" | |
| }, | |
| { | |
| "type": "joinaggregate", | |
| "ops": ["max", "max"], | |
| "fields": ["change", "sortOrder"], | |
| "as": ["change", "sortOrder"] | |
| } | |
| ] | |
| }, | |
| {"name": "selection_store", "transform": []}, | |
| { | |
| "name": "lyra_selections", | |
| "source": "dataset", | |
| "transform": [ | |
| { | |
| "type": "formula", | |
| "expr": "pluck(data('selection_store'), 'yLabel')", | |
| "as": "yLabels" | |
| }, | |
| { | |
| "type": "formula", | |
| "expr": "granularityLevel === 'MET' ? datum['Task Full Name'] : datum['MET Measure Full Name']", | |
| "as": "yLabel" | |
| }, | |
| {"type": "filter", "expr": "indexof(datum.yLabels, datum.yLabel) >=0"}, | |
| { | |
| "type": "lookup", | |
| "from": "selection_store", | |
| "key": "yLabel", | |
| "fields": ["yLabel"], | |
| "values": ["barType", "Criteria Met"], | |
| "as": ["barType", "Select Criteria Met"] | |
| }, | |
| { | |
| "type": "filter", | |
| "expr": "datum.barType === 'y' ? true : (datum['Select Criteria Met'] === datum['Criteria Met'])" | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "lyra_self_highlight", | |
| "on": [ | |
| {"trigger": "selection", "remove": true}, | |
| { | |
| "trigger": "selection", | |
| "insert": "isValid(selection) && isValid(selection.vlPoint) && isValid(selection.vlPoint.or) ? pluck(selection.vlPoint.or, '_vgsid_') : []" | |
| } | |
| ] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment