-
-
Notifications
You must be signed in to change notification settings - Fork 413
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
fix display(d, m, x) where m expects a json string #756
base: master
Are you sure you want to change the base?
Conversation
Fix queryverse/VegaLite.jl#127 After the fix the following works out of the box in new versions of jupyterlab, generating an interactive VegaLite visualization, without additional packages except Ijulia. ``` spec = raw""" { "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": "point", "encoding": { "x": {"field": "a", "type": "ordinal"}, "y": {"field": "b", "type": "quantitative"} } } """ display("application/vnd.vegalite.v2+json", spec) ```
Ultimately one should rethink how IJulia should support MIME types. But this fixes things for me now.
src/inline.jl
Outdated
for mime in ipy_mime | ||
@eval begin | ||
function display(d::InlineDisplay, ::MIME{Symbol($mime)}, x) | ||
send_ipython(publish[], | ||
msg_pub(execute_msg, "display_data", | ||
Dict( | ||
"metadata" => metadata(x), # optional | ||
"data" => Dict($mime => limitstringmime(MIME($mime), x))))) | ||
"data" => _display_dict(MIME($mime), $mime, x)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than MIME($mime)
, you should just give the argument ::MIME{Symbol($mime)}
a name, e.g. m
, and use that. This way _display_dict
will be dispatched statically here.
src/inline.jl
Outdated
for mime in ipy_mime_json | ||
@eval begin | ||
_display_dict(m::MIME{Symbol($mime)}, m_str, x) = Dict(m_str=>JSON.JSONText(limitstringmime(m, x))) | ||
Base.Multimedia.istextmime(::MIME{Symbol($mime)}) = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm worried that this will conflict with other packages, since we don't "own" this type. (i.e. it is type piracy)
Maybe define _istextmime(::MIME{Symbol($mime)}) = true
here, along with a fallback definition
_istextmime(m) = istextmime(m)
and then call _istextmime
rather than textmime
elsewhere in IJulia.
src/inline.jl
Outdated
@@ -8,6 +8,7 @@ const ipy_mime = [ | |||
"application/vnd.dataresource+json", | |||
"application/vnd.vegalite.v2+json", | |||
"application/vnd.vega.v3+json", | |||
"application/vnd.vega.v4+json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also needs to be handled in the display_dict
function, I think.
It's NOT working Yet! I'm on leave so sorry if I am delaying you. @stevengj After looking into #755 I think work should go into better support of MIME types in general. This fix will not be necessary by then. The latest commits demonstrates how I would like to achieve this. I think it is possible to achieve:
Using traits I think one can achieve these easily and cleanly. But I am struggling to find time to contribute more aside from this still buggy draft. Maybe I can have some time by the weekend. I am more than happy to see any of you to pick up the effort. All credit goes to @stevengj and @travigd of course. |
Should work now, but with some loose ends:
Am open to comments/opinions/etc. |
@cnliao Apologies if if I'm off base, but, if your goal is still to just be display arbitrary data presented as a specific MIME type, couldn't we just have a function displayraw(x::MIME, s) end style function? In particular, you could have displayraw(MIME("application/vnd.vegalite.v2+json"), JSONText(spec)) I think the implementation would just be something along the lines of sending a JSON data bundle with only that MIME key defined. |
@travigd After reading the Julia doc on multimedia display, people( at least myself) expect I also think there is an issue with the test case of vnd.ijulia.friendly-binary. |
I haven't fully reviewed this, but just want to make sure the following is still true for VegaLite.jl: if someone just uses the package in the usual way in say JupyterLab, IJulia will still send both the vega-lite MIME version and a PNG back to JupyterLab, right? That is quite important, so that notebooks that are created in JupyterLab also view properly in the traditional notebook that doesn't support the vega-lite MIME type. |
@davidanthoff True, kind of. The png is always in the resulting .ipynb file, but I don't think Ijulia generates that. I guess that ipython takes care of always generating an "image/png" entry under the "outputs" key of the cell even if you only send it a json specification (like via |
@cnliao That's not quite right. The notebook doesn't do any converting itself, the only thing that's included in the notebook is that the kernel (IJulia in this case) sends. Which is why it's generally better to define a new MIME type to be included in the bundle that to just send that one specific MIME type (so the notebook can select the richest it can render). All of which is to say the IJulia is what generates (or at least that triggers the code that generates) the PNG data that's transmitted from the kernel and ultimately embedded within the notebook |
@travigd AFAIK the call to display just call send_ipython to send no more data than a json string. FYI I am on jupyterlab 0.35. |
@davidanthoff, this PR is a bit messed up because of merge conflicts, I think, making it confusing right now. But yes, the My understanding is that the intention of this PR (once it is cleaned up), is not to affect |
@stevengj Do you think it will be better if I open another PR and provide a fix to the explicit mime variant of display? Or continue with this ? I think it’s now more of a refactor of #755. Personally I think the solution provided here is cleaner. But I am very much like to hear your suggestions. For the Vega lite mime type, even if you call the explicit mime variant of display, the png is still included in the resulting ipynb file. I think it is jupyterlab that takes care of that rather than Ijulia. |
I think the user is going to have to differentiate JSON vs non-JSON data manually. Maybe display("text/plain", "foo bar") should send a MIME bundle of the form { "text/plain": "foo bar" } Whereas you'd like to see (I think) display("application/vnd.vegalite.v2+json", "{...}") yielding a MIME bundle of the form { "application/vnd.vegalite.v2+json": { ... } } There are some heuristics (does the MIME contain |
@travigd
yielding a MIME bundle of the form
Because
already yields a MIME bundle of that form (with more MIME types). For that to work, VegaLite.jl only has to overload |
Ah, okay. I'm not sure that there is going to be a good way around that besides a The thorn seems, to me, to be that it's hard to determine whether or not tl;dr: how about """
Return true if the MIME type when `Base.show`'d returns valid JSON.
If true, the JSON is embeded within the Jupyter display_data dict rather than being
encoded as a string.
"""
isjsonmime(::MIME) = false
isjsonmime(m::AbstractString) = isjsonmime(MIME(m))
isjsonmime(::MIME"application/vnd.vegalite.v2+json") = true and modify function jupyter_mimerepr(m::MIME, x)
if isjsonmime(m)
return JSONText(limitmimestring(m, x))
end
return limitmimestring(m, x)
end
function display(d::InlineDisplay, ::MIME{Symbol($mime)}, x)
send_ipython(publish[],
msg_pub(execute_msg, "display_data",
Dict(
"metadata" => metadata(x), # optional
"data" => Dict($mime => jupyter_mimerepr(MIME($mime), x))
))
)
end (and also refactor some of #755 to avoid duplication). |
@travigd
Which one is better style is still open to discussion I think. Moreover, I think display_dict should also call these methods. edit: |
Fix queryverse/VegaLite.jl#127.
Should be reconsidered after #755
After the fix the following works out of the box in new versions of
jupyterlab, generating an interactive VegaLite visualization, without
additional packages except Ijulia.