PBI DataVizzle
PBI DataVizzle

Reputation: 175

(Deneb + Vega-Lite) Trouble with VCONCAT Text Marks conditional formatting issue

Deneb + Vega-Lite difficulties

VCONCAT and Text Mark Conditional Format Issues

I may have gone about this the wrong way, I'm struggling to do two one thing:

- Add a "Total" label to the second VCONCAT spec. This spec intends to be a grand total of all the months of the first spec.

See image below: enter image description here

Link to pbix here: highlighted_hover_dev

POST EDIT: Was able to apply the "Total" label using "datum" - but issue with conditional formatting persists: enter image description here

here's the spec below, apologies it's not the cleanest. Thank you in advance for any assistance, please do suggest a better method if this approach is not ideal.

{
  "data": {
    "name": "dataset"
  },
  "params": [
    {
      "name": "offsets",
      "value": 20
    },
    {
      "name": "offsets_adj",
      "expr": "offsets * 1.8"
    }
  ],
  "transform": [
    {
      "calculate": "timeFormat(datum.dates, '%b')",
      "as": "monthonly"
    },
    {
      "joinaggregate": [
        {
          "op": "sum",
          "field": "sales",
          "as": "max_sales"
        },
        {
          "op": "sum",
          "field": "budget",
          "as": "max_budget"
        }
      ],
      "groupby": [
        "dates"
      ]
    },
    {
      "joinaggregate": [
        {
          "op": "sum",
          "field": "sales",
          "as": "grp_sales"
        },
        {
          "op": "sum",
          "field": "budget",
          "as": "grp_budget"
        }
      ],
      "groupby": [
        "monthonly"
      ]
    },
    {
      "calculate": "datum.max_sales * 1.05",
      "as": "MaxDomain"
    },
    {
      "calculate": "datum.max_sales * 1",
      "as": "text_position"
    },
    {
      "calculate": "datum.sales > datum.budget ? datum.sales : datum.budget",
      "as": "max_value"
    },
    {
      "calculate": "datum.grp_sales - datum.grp_budget",
      "as": "variance"
    },
    {
      "calculate": "datum.max_sales - datum.max_budget",
      "as": "variance_total"
    }
  ],
  "vconcat": [
    {
      "name": "monthly_vconcat",
      "height": 500,
      "width": 500,
      "layer": [
        {
          "params": [
            {
              "name": "hover",
              "select": {
                "type": "point",
                "on": "pointerover",
                "clear": "pointerout"
              }
            }
          ],
          "mark": {
            "type": "bar",
            "color": "#f5f1a3",
            "tooltip": true
          },
          "encoding": {
            "opacity": {
              "condition": {
                "param": "hover",
                "empty": false,
                "value": 0.5
              },
              "value": 0
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 0.8
            },
            "yOffset": 2,
            "opacity": 0.1
          },
          "encoding": {
            "x": {
              "field": "sales",
              "axis": {
                "title": null,
                "labels": false,
                "ticks": false,
                "domain": false,
                "grid": false
              }
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "lightgrey",
            "height": {
              "band": 0.8
            },
            "yOffset": -2,
            "opacity": 0.4
          },
          "encoding": {
            "x": {
              "field": "budget",
              "type": "quantitative"
            },
            "opacity": {
              "condition": {
                "test": {
                  "field": "__selected__",
                  "equal": "off"
                },
                "value": 0.1
              },
              "value": 0.6
            }
          }
        },
        {
          "name": "highlighted_bar",
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 0.8
            },
            "yOffset": 2
          },
          "encoding": {
            "x": {
              "field": "sales__highlight"
            },
            "opacity": {
              "condition": {
                "test": {
                  "field": "__selected__",
                  "equal": "off"
                },
                "value": 0
              },
              "value": 1
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "fontWeight": "bolder",
            "dx": 20
          },
          "encoding": {
            "text": {
              "field": "sales",
              "format": ",.2s"
            },
            "x": {
              "field": "sales"
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "fontWeight": "bolder",
            "color": {
              "expr": "datum.variance >= 0 ? 'limegreen' : 'tomato'"
            },
            "align": "left",
            "dx": {
              "expr": "offsets_adj"
            }
          },
          "encoding": {
            "text": {
              "field": "variance",
              "format": "(+#,0);(-#,0)",
              "formatType": "pbiFormatAutoUnit"
            },
            "x": {
              "field": "text_position"
            }
          }
        }
      ],
      "encoding": {
        "y": {
          "field": "dates",
          "type": "nominal",
          "timeUnit": "month"
        },
        "x": {
          "type": "quantitative",
          "axis": {
            "title": "sales"
          }
        }
      }
    },
    {
      "width": 500,
      "name": "total_vconcat",
      "layer": [
        {
          "mark": {
            "type": "bar",
            "tooltip": true,
            "height": {
              "band": 1.5
            },
            "yOffset": -2,
            "opacity": 0.6,
            "fill": "lightgrey"
          },
          "encoding": {
            "x": {
              "field": "max_budget",
              "type": "quantitative",
              "title": "Total",
              "axis": {
                "title": "",
                "labels": false
              }
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 1.5
            },
            "yOffset": 8
          }
        },
        {
          "mark": {
            "type": "text",
            "dx": 40,
            "fontWeight": "bold",
            "align": "right"
          },
          "encoding": {
            "text": {
              "field": "max_sales",
              "aggregate": "sum",
              "format": ",.3~s"
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "color": {
              "expr": "datum.variance >= 0 ? 'limegreen' : 'tomato'"
            },
            "dx": 50,
            "fontWeight": "bold",
            "align": "left"
          },
          "encoding": {
            "text": {
              "field": "variance",
              "aggregate": "sum",
              "format": "(+#,0);(-#,0)",
              "formatType": "pbiFormatAutoUnit"
            }
          }
        }
      ],
      "encoding": {
        "y": {
          "title": "Total",
          "axis": {
            "domain": false
          }
        },
        "x": {
          "field": "max_sales",
          "type": "quantitative",
          "aggregate": "sum",
          "axis": {
            "title": "",
            "labels": false,
            "ticks": false,
            "domain": false,
            "grid": false,
            "labelPadding": 20
          }
        }
      }
    }
  ]
}

Upvotes: 2

Views: 63

Answers (1)

PBI DataVizzle
PBI DataVizzle

Reputation: 175

SOLVED: The culprit was an "aggregate": "sum" in the text: y-encoding. I also added a better joinaggregrate with no date grouping for grand totals. This appears to work as expected.

enter image description here


{
  "data": {
    "name": "dataset"
  },
  "params": [
    {
      "name": "offsets",
      "value": 20
    },
    {
      "name": "offsets_adj",
      "expr": "offsets * 1.8"
    }
  ],
  "transform": [
    {
      "calculate": "timeFormat(datum.dates, '%b')",
      "as": "monthonly"
    },
    {
      "calculate": "timeFormat(datum.dates, '%Y')",
      "as": "yearly"
    },
    {
      "joinaggregate": [
        {
          "op": "sum",
          "field": "sales",
          "as": "max_sales"
        },
        {
          "op": "sum",
          "field": "budget",
          "as": "max_budget"
        }
      ],
      "groupby": [
        "dates"
      ]
    },
    {
      "joinaggregate": [
        {
          "op": "sum",
          "field": "sales",
          "as": "grp_sales"
        },
        {
          "op": "sum",
          "field": "budget",
          "as": "grp_budget"
        }
      ],
      "groupby": [
        "monthonly"
      ]
    },
    {
      "joinaggregate": [
        {
          "op": "sum",
          "field": "sales",
          "as": "yr_sales"
        },
        {
          "op": "sum",
          "field": "budget",
          "as": "yr_budget"
        }
      ],
      "groupby": []
    },
    {
      "calculate": "datum.yr_sales - datum.yr_budget",
      "as": "year_diff"
    },
    {
      "calculate": "datum.max_sales * 1.05",
      "as": "MaxDomain"
    },
    {
      "calculate": "datum.max_sales * 1",
      "as": "text_position"
    },
    {
      "calculate": "datum.sales > datum.budget ? datum.sales : datum.budget",
      "as": "max_value"
    },
    {
      "calculate": "datum.grp_sales - datum.grp_budget",
      "as": "variance"
    },
    {
      "calculate": "datum.max_sales - datum.max_budget",
      "as": "variance_total"
    }
  ],
  "vconcat": [
    {
      "name": "monthly_vconcat",
      "height": 500,
      "width": 500,
      "layer": [
        {
          "params": [
            {
              "name": "hover",
              "select": {
                "type": "point",
                "on": "pointerover",
                "clear": "pointerout"
              }
            }
          ],
          "mark": {
            "type": "bar",
            "color": "#f5f1a3",
            "tooltip": true
          },
          "encoding": {
            "opacity": {
              "condition": {
                "param": "hover",
                "empty": false,
                "value": 0.5
              },
              "value": 0
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 0.8
            },
            "yOffset": 2,
            "opacity": 0.1
          },
          "encoding": {
            "x": {
              "field": "sales",
              "axis": {
                "title": null,
                "labels": false,
                "ticks": false,
                "domain": false,
                "grid": false
              }
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "lightgrey",
            "height": {
              "band": 0.8
            },
            "yOffset": -2,
            "opacity": 0.4
          },
          "encoding": {
            "x": {
              "field": "budget",
              "type": "quantitative"
            },
            "opacity": {
              "condition": {
                "test": {
                  "field": "__selected__",
                  "equal": "off"
                },
                "value": 0.1
              },
              "value": 0.6
            }
          }
        },
        {
          "name": "highlighted_bar",
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 0.8
            },
            "yOffset": 2
          },
          "encoding": {
            "x": {
              "field": "sales__highlight"
            },
            "opacity": {
              "condition": {
                "test": {
                  "field": "__selected__",
                  "equal": "off"
                },
                "value": 0
              },
              "value": 1
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "fontWeight": "bolder",
            "dx": 20
          },
          "encoding": {
            "text": {
              "field": "sales",
              "format": ",.2s"
            },
            "x": {
              "field": "sales"
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "fontWeight": "bolder",
            "color": {
              "expr": "datum.variance >= 0 ? 'limegreen' : 'tomato'"
            },
            "align": "left",
            "dx": {
              "expr": "offsets_adj"
            }
          },
          "encoding": {
            "text": {
              "field": "variance",
              "format": "(+#,0);(-#,0)",
              "formatType": "pbiFormatAutoUnit"
            },
            "x": {
              "field": "text_position"
            }
          }
        }
      ],
      "encoding": {
        "y": {
          "field": "dates",
          "type": "nominal",
          "timeUnit": "month"
        },
        "x": {
          "type": "quantitative",
          "axis": {
            "title": "sales"
          }
        }
      }
    },
    {
      "width": 500,
      "name": "total_vconcat",
      "layer": [
        {
          "mark": {
            "type": "bar",
            "tooltip": true,
            "height": {
              "band": 1.5
            },
            "yOffset": -2,
            "opacity": 0.6,
            "fill": "lightgrey"
          },
          "encoding": {
            "x": {
              "field": "max_budget",
              "type": "quantitative",
              "title": "Total",
              "axis": {
                "title": "",
                "labels": false
              }
            }
          }
        },
        {
          "mark": {
            "type": "bar",
            "fill": "#404040",
            "tooltip": true,
            "height": {
              "band": 1.5
            },
            "yOffset": 8
          }
        },
        {
          "mark": {
            "type": "text",
            "dx": 40,
            "fontWeight": "bold",
            "align": "right"
          },
          "encoding": {
            "text": {
              "field": "max_sales",
              "aggregate": "sum",
              "format": ",.3~s"
            }
          }
        },
        {
          "mark": {
            "type": "text",
            "color": {
              "expr": "datum.year_diff >= 0 ? 'limegreen' : 'tomato'"
            },
            "dx": 50,
            "fontWeight": "bold",
            "align": "left"
          },
          "encoding": {
            "y": {
              "datum": "Total"
            },
            "text": {
              "field": "year_diff",
              "format": "(+#,0);(-#,0)",
              "formatType": "pbiFormatAutoUnit"
            }
          }
        }
      ],
      "encoding": {
        "y": {
          "datum": "Total",
          "axis": {
            "domain": false,
            "labelFontWeight": "bold"
          }
        },
        "x": {
          "field": "max_sales",
          "type": "quantitative",
          "aggregate": "sum",
          "axis": {
            "orient": "top",
            "title": "",
            "labels": false,
            "ticks": false,
            "domain": false,
            "grid": false,
            "labelPadding": 20
          }
        }
      }
    }
  ]
}

Upvotes: 2

Related Questions