New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support expression for formatting axis #5122
Comments
Can you describe more how would I'm confused since expression is more general than format (e.g., it can include multiple fields). |
Related vega/vega#1853 |
Motivating context: At the end of the day, what I'd really like to see is a fork of https://observablehq.com/@mbostock/working-with-wikipedia-data that formats the X ticks of the bar chart using "$90B" rather than "90G". |
Copying over my comment from the other issue, here's an example of resultant Vega that we'd ideally want to generate: "axes": [
{
"scale": "x",
"orient": "top",
...
"format": "s",
"encode": {
"labels": {
"update": {
"text": {"signal": "replace(datum.label, 'G', 'B')"}
}
}
}
}, |
The idea is that you would write a spec like {
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"data": {
"values": [
{"a": "A","b": 28}, {"a": "B","b": 55}, {"a": "C","b": 43},
{"a": "D","b": 91}, {"a": "E","b": 81}, {"a": "F","b": 53},
{"a": "G","b": 19}, {"a": "H","b": 87}, {"a": "I","b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {
"field": "b",
"type": "quantitative",
"axis": {
"formatType": "expression",
"format": "+datum.label * 10"
}
}
}
} We would then use the provided format in the In the implementation, we will need to distinguish format types that vega supports (number and time) from the expression format type. |
Thanks for explanation. I think this makes sense. One case that the expression (without extension) in Vega wouldn't support is when we want to add unit to only the topmost labels, like this:
I'll file issue in Vega to see if we can expose more info in the datum besides |
Good point. This should just be a part of the guide encoding (which is a secret feature right now) then we don't have to introduce this as a conflicting formatType. |
@arvind You can invoke formatting in expressions. For example |
I think you mean One problem with formatType: 'expression' is that it will still be either inconsistent or weird for If we say, text's But if text's formatType supports For example, imagine:
Basically, the Also, the transition from
to
is a bit drastic (not incremental).
which may have a smoother transition as some of the original part is still kept. However, the con of this approach is that the format would be separate from the label text and Alternatively, we could introduce a separate
which is simpler, but still split Given they should be together, I wonder if we should eliminate
This seems nicer but still have a inconsistency issue for Perhaps, we can get around that by always replacing |
FWIW, none of our examples currently use |
Btw, as I think about the need for axis/legend encode block, I think the secret |
Maybe this could be a use case for vega-label? For data exploration, the SI system in vega-lite really just works fine. For data explanation, repeating the measurement unit in each axis label instead of mentioning it in the axis title is hardly more readable. |
What do you think about passing in a JavaScript function as part of the Vega spec? This would allow arbitrary JavaScript (e.g. post-process the result from the format function using any other function). It also feels simpler than anything I've seen proposed here. |
Hi @curran, that's precisely the purpose of Vega's expression functions — giving us an escape hatch rather than continuously expanding the surface area of the visualization language itself. And, importantly, having our own expression parser allows us to control and sandbox allowable functions — a necessary feature for deploying Vega/Vega-Lite specifications in security-concious environments like Wikipedia. If the expression functions do not cover a desired feature, our preference would be to introduce new functions (rather than enable wholly arbitrary JavaScript). Hope that makes sense! |
Plus, you can use expressions in other languages such as Python with Altair. |
Excellent! It's great to know the "escape hatch" is there. It's also great to hear the reasoning behind the desire to introduce new functions to the sandboxed environment, which makes total sense. However, I still would love to be able to write this, from the Vega-Lite JS API: const xAxisTickFormat = number =>
d3.format('.3s')(number)
.replace('G', 'B');
vl.markBar()
.data({values: d3.zip(names, totals)})
.encode(
vl.y().fieldN("0").sort(null).axis({title: null}),
vl.x().fieldQ("1").axis({orient: "top", format: xAxisTickFormat, title: "Total revenue (est.)"})
)
.width(width)
.autosize({type: "fit-x", contains: "padding"})
.render() Perpaps the JS API internally could re-write or transform the spec such that the function passed in is invoked via Vega's expression functions. This would make the JS API more usable, as developers could use what they already know, rather than learning an entirely different language that they do not already know. Although, this development would only make the JS API more usable, and would not improve the core Vega-Lite spec at all, so the audience for this improvement would be limited (would exclude Altair users for example), so I can understand it would not be a high priority in the grand scheme of things. Food for thought! Thanks all for your time here. I really appreciate your efforts. |
Another strategy to handle this specific use case could be to file a feature request with d3.format to allow the localising of the SI letters via the (d3.formatLocale function)[https://github.com/d3/d3-format/blob/master/README.md#formatLocale]. This would then apply downstream to the vega ecosystem. |
It's worth noting that Vega expression is just a subset of Javascript. Thus, supporting arbitrary JS format function won't be a high priority for us for now. |
The format expression is simply for labels. I think a better alternative is to make
Then we don't have to mess with format (and also can reuse results from We can then do:
to replace G with B as discussed above. |
Or we can even make it
though it's a bit less obvious that we have expression support here. |
I see. Yes, I agree that expression should be a separate property then. However, I don't think we want to use the existing How about we add a new property |
From a Slack converation, @domoritz and I settled on adding a new property named
|
Fixed in #5260 |
Will labelExpr also work with text, for formatting the text mark layer? The link in the documentation: https://vega.github.io/vega-lite/usage/config.html#custom-format-type is broken on how to use custom format types |
Here are the docs: https://vega.github.io/vega-lite/docs/config.html#custom-format-type. I'm fixing the links right now. |
Does this work in the tooltip as well? If not, possible to add?
|
Tooltip is not a guide so the property isn't called labelExpr. You can use a formatExpr. |
Any examples I could reference? Thanks! |
SOrry, I misremembered and spoke too soon. There is no formatExpr and I don't know why labelExpr shows up in the autocomplete since there is no axis. What you need to do is to either create a custom formatter (https://vega.github.io/vega-lite/docs/config.html#custom-format-type) or derive a new field using the calculate transform and use that field in the tooltip. |
Thank you for raising the issue @jbleich89. You found a bug that will be fixed in #7039. |
@domoritz Actually, my original use case is to add a unit to the end of a formatted number value. A custom format expression could do the job, but seems to be overkill for this simply and frequent use case. The |
@domoritz The proposition to create an issue for a new BTW: I get an error for
|
We already have format types for number and time. We could introduce a flexible expression formatter. This would resolve vega/vega-lite-api#12.
Related issue: vega/vega#608
cc @curran
The text was updated successfully, but these errors were encountered: