1

I've been working on a personal project to create an election tracker and then a published dashboard in google looker. I have a google sheet imported and a simple line chart working already but I can't get the vega-lite visual to work.

This is how the sheet is structured (plus a few other party labeled columns I shortened it here to fit):

Polling firm Fieldwork date Sample PVV GLPvdA VVD NSC Calc weight
Ipsos I&O 2025年06月16日. 1 969 19,20% 18,30% 15,40% 1,30% 0.123
Ipsos I&O 2025年06月06日. 1 957 19,00% 16,70% 14,80% 1,70% 0.123
Verian 2025年05月26日. 1 567 18,40% 17,90% 19,40% 1,50% 0.2

And this is a visual I have working now: setup chart

What I want is to essentially replicate how the shaded error bands work in power bi, minimum and maximum being the values per party.

so for the line which is a simple

SUM(VVD*Calc weight)/SUM(Calc weight)

the error band should be min(VVD) and max(VVD), shaded appropriately between.

I've gotten this far with this code which renders the chart well enough but no data is showing up:

{
 "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
 "description": "Line chart showing weighted average party support with min/max error bands.",
 "title": {
 "text": "Weighted Average Party Support with Min/Max Bands",
 "anchor": "middle",
 "fontSize": 16,
 "offset": 10
 },
 "data": {"name": "data"},
 "transform": [
 {
 "fold": ["PVV", "VVD", "GLPvdA", "CDA"],
 "as": ["party", "value"]
 },
 {"calculate": "toDate(datum['Fieldwork date'])", "as": "Fieldwork date"},
 {"calculate": "toNumber(datum.value)", "as": "value"},
 {"calculate": "toNumber(datum['Calc weight'])", "as": "Calc weight"},
 {
 "calculate": "datum.value * datum['Calc weight']",
 "as": "weighted_value"
 },
 {
 "aggregate": [
 {"op": "sum", "field": "weighted_value", "as": "sum_weighted_value"},
 {"op": "sum", "field": "Calc weight", "as": "sum_calc_weight"},
 {"op": "min", "field": "value", "as": "min_party_value"},
 {"op": "max", "field": "value", "as": "max_party_value"}
 ],
 "groupby": ["Fieldwork date", "party"]
 },
 {
 "calculate": "datum.sum_weighted_value / datum.sum_calc_weight",
 "as": "weighted_avg"
 },
 {"filter": "isValid(datum.weighted_avg)"}
 ],
 "layer": [
 {
 "mark": {
 "type": "area",
 "opacity": 0.2,
 "line": false
 },
 "encoding": {
 "x": {
 "field": "Fieldwork date",
 "type": "temporal",
 "title": "Date",
 "axis": {"format": "%Y-%m"}
 },
 "y": {
 "field": "min_party_value",
 "type": "quantitative",
 "title": "Party Support (%)",
 "scale": {"zero": false}
 },
 "y2": {"field": "max_party_value"},
 "color": {
 "field": "party",
 "type": "nominal",
 "title": "Party",
 "legend": {"orient": "bottom", "columns": 2}
 },
 "tooltip": [
 {"field": "Fieldwork date", "type": "temporal", "title": "Date", "format": "%Y-%m"},
 {"field": "party", "type": "nominal", "title": "Party"},
 {"field": "weighted_avg", "type": "quantitative", "title": "Weighted Avg", "format": ".1f"},
 {"field": "min_party_value", "type": "quantitative", "title": "Min Value", "format": ".1f"},
 {"field": "max_party_value", "type": "quantitative", "title": "Max Value", "format": ".1f"}
 ]
 }
 },
 {
 "mark": {"type": "line", "point": true},
 "encoding": {
 "x": {
 "field": "Fieldwork date",
 "type": "temporal"
 },
 "y": {"field": "weighted_avg", "type": "quantitative"},
 "color": {"field": "party", "type": "nominal"},
 "tooltip": [
 {"field": "Fieldwork date", "type": "temporal", "title": "Date", "format": "%Y-%m"},
 {"field": "party", "type": "nominal", "title": "Party"},
 {"field": "weighted_avg", "type": "quantitative", "title": "Weighted Avg", "format": ".1f"},
 {"field": "min_party_value", "type": "quantitative", "title": "Min Value", "format": ".1f"},
 {"field": "max_party_value", "type": "quantitative", "title": "Max Value", "format": ".1f"}
 ]
 }
 }
 ],
 "resolve": {
 "axis": {"y": "independent"}
 }
}

chart setup

The calculation works in the basic chart, so I assume the json is the problem here, which wouldn't be surprising, it's really not my forte.

Can you take a look at it and help me clean this up if it's a reasonable thing to achieve/request?

Many thanks!!

asked Jul 25, 2025 at 9:44

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.