-
Notifications
You must be signed in to change notification settings - Fork 95
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
Feature: Formal URL API #1365
Comments
OK I just did a quick prototype. Per some googling, I found this article, which recommends brotli for JSON. Brotli is well-defined, mature, and available in most languages. Here is some python that encodes the json with brotli, and then base64 encodes it so it is valid in a URI: import brotli
import base64
import altair as alt
from vega_datasets import data
source = data.cars()
chart = alt.Chart(source).mark_point().encode(
x='Horsepower',
y='Miles_per_Gallon',
size='Acceleration'
)
json = chart.to_json()
json_bytes = json.encode("utf-8")
compressed = brotli.compress(json_bytes)
encoded = base64.b64encode(compressed)
decoded = base64.b64decode(encoded)
decompressed = brotli.decompress(decoded)
json_restored = decompressed.decode("utf-8")
assert json_restored == json
print(encoded)
# b'W8zWIYqypFoCrAu4w8rgT3h3YQLVJXA+/lZfywhGSDK7uVQegr....
print(len(encoded))
# 9156 This is that chart in the web viewer If I share that URL, it is 19512 characters long, twice the length of the 9k from the brotli encoding (if I am understanding this right)! So not only would we get a more portable API, but also we get a performance boost! With the current lz implementation, if I have very many datapoints (> ~500??) then the URL gets too long and many apps like slack and Google Docs stop working with them, defeating the point. |
Vega-Embed has an "open in the editor" action that uses an API in the editor to load the spec. Maybe that works as well (although you can only trigger it from js: https://github.com/vega/vega-embed/blob/880d55f7cf57e27716c510ad73715db877cd718c/src/post.ts#L29). I am all open to use brotli but we do need to be backwards compatible. We need to use a different URL, I suppose. Would you like to send a pull request? |
I'm a little intimidated by the typescript, I have never worked with it before. I can try to task a stab at it, but I might give up. First, we should figure out a rough shape of the API. To make it backward-compatible, we could move to parameters, something like:
but IDK, I am no expert in web APIs so I'm not sure what the conventions are here. I want to figure this out before I actually implement anything. Like should it be this?
|
Btw, I looked at lz-string and the replacement for uri encoding is pretty simple: https://github.com/pieroxy/lz-string/blob/35cdd797ae7415211add846e529669643e893904/src/main.ts#L136C16-L136C29. Maybe you can dig a bit more to see whether you can replicate it in Python. Brotli will add some overhead in terms of bundle size that I want to be careful with. |
I suppose if lz-string is always going to be supported by the editor, then there is no harm in adding it to Altair, it should be a single python file. Then moving to brotli could be a later discussion. What do you think about the better compression of brotli? Have you heard from any other users complaints about long URLs? |
I thought Brotli was for fast compression, not small. I've not heard about many issues with long urls. If the spec is large, I always recommend gist or the api I linked to above. |
First, thanks for your work on this, I think vega is brilliant.
I want to make it easy to share interactive versions of charts with coworkers. I am using altair to make charts. I could export as a static HTML, but that involves uploading and downloading files.
In your webui, you can get a shareable link to a chart by encoding the JSON spec into a LZ compressed string, which is then stored directly in the URL. Brilliant! I can share this URL with coworkers and it's super easy.
Currently, I can go through this flow:
chart.to_json()
from AltairI would like to make this more streamlined, so there is something like
Chart.to_url()
which gives me the link directly.The problem is that the web UI uses a custom implementation of LZ compression, and while there is a python port it is outdated and doesn't work (doesn't decode from URI). So from python, I don't have a good way of encoding the JSON spec into the URL.
To make this work, I think we would need to:
.to_url()
method toaltair.Chart
. But I can write my own helper function for this, so not really needed.The text was updated successfully, but these errors were encountered: