问题
How can I dynamically change a data field encoded for the y-axis based upon a selection? I am trying to build a visualization to display event count data over the 24 hours of a day, and I want the user to be able to select different timezones (e.g. EST, CST, MST, or PST).
To do this, I have built out a single selection where I specify all the options I list above in the parentheses, with EST being set as my default. I want to create a condition where when I chose another option besides EST, I see the visualization dynamically update. I've explored creating other hour fields specifically for those timeframes, or adding in condition logic to try to account for these dynamic changes, but I have not arrived at a good solution yet. Can anyone help out?
Here is an example of what a few lines of my data look like
"data": {
"values": [
{
"title_column":"example",
"Type": "Technology",
"Events": "100",
"Hour": "0",
"Date": "9/1/20",
"Time Period": "Last Time"
},
{
"title_column":"example",
"Type": "Technology",
"Events": "110",
"Hour": "1",
"Date": "9/1/20",
"Time Period": "Last Time"
},
and the visualization looks like this when it is put together, with it dynamically updating based on the selection:
And when my code is static, it looks like this:
"layer":[
{"mark":{
"type":"bar",
"point":true,
"color":"#FFC94E",
"height":15
},
"selection": {
"timezone": {
"type": "single",
"init": {"changer": "EST"},
"bind": {
"changer": {"input": "select",
"options": ["EST","CST (-1 Hour)","MST (-2 Hours)","PST (-3 Hours)"]}
}
}
},
"encoding":
{
"x":{"field":"Events",
"type":"quantitative",
"aggregate":"sum",
"axis":null},
"y": {"field":"Hour",
"type":"ordinal",
"axis":{
"labelSeparation":1,
"labelPadding":4,
"title":null
}
}
}}]
}
However, focusing in particular on the y encoding of the bottom part of the code, I would ideally like to make that dynamic. I'm thinking I could create calculations for each of the timezones and then write a condition that works like the following below, but I have not been able to get this to work. Any help is greatly appreciated!
"y": {
"condition": {
"selection": {"timezone" : "EST"},
"datum": "datum.Hour"
}
"condition": {
"selection": {"timezone" : "CST (-1 Hour)"},
"datum": "datum.Hour_CST"
}
...
}
Here is the link to my code: vega editor.
回答1:
Selections can only filter on column values, not column names. Fortunately, you can convert column names to column values by using a Fold Transform.
To accomplish what you want, I'd suggest the following:
- Use a series of Calculate Transforms to calculate new columns containing the values you want to show.
- Use a Fold Transform to stack these values into a single column with an associated key column.
- Link the selection binding to the key column created in the fold transform.
- Use a Filter Transform to filter the values based on the selection
- Finally, add a row encoding so that the selected column is labeled on the axis.
Put together, it looks like this (open in vega editor):
{
"width": 300,
"data": {
"values": [...]
},
"transform": [
{"filter": {"field": "Time Period", "equal": "Last Time"}},
{"calculate": "datum.Hour - 0", "as": "EST"},
{"calculate": "datum.Hour - 1", "as": "CST (-1 Hour)"},
{"calculate": "datum.Hour - 2", "as": "MST (-2 Hours)"},
{"calculate": "datum.Hour - 3", "as": "PST (-3 Hours)"},
{
"fold": ["EST", "CST (-1 Hour)", "MST (-2 Hours)", "PST (-3 Hours)"],
"as": ["Zone", "Hour"]
},
{"filter": {"selection": "timezone"}}
],
"selection": {
"timezone": {
"type": "single",
"init": {"Zone": "EST"},
"bind": {
"Zone": {
"name": "timezone",
"input": "select",
"options": [
"EST",
"CST (-1 Hour)",
"MST (-2 Hours)",
"PST (-3 Hours)"
]
}
}
}
},
"mark": {"type": "bar", "point": true, "color": "#FFC94E", "height": 15},
"encoding": {
"x": {
"field": "Events",
"type": "quantitative",
"aggregate": "sum",
"axis": null
},
"y": {
"field": "Hour",
"type": "ordinal",
"axis": {"labelSeparation": 1, "labelPadding": 4, "title": null}
},
"row": {
"field": "Zone",
"type": "nominal",
"title": null
}
}
}
来源:https://stackoverflow.com/questions/64449715/dynamically-change-y-axis-field-in-encoding-based-on-selection-vega-lite