Skip to content

Commit 85dbcf9

Browse files
committed
Allow updating of existing display data
1 parent 4f67be1 commit 85dbcf9

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

docs/src/library/public.md

+1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ IJulia.set_max_stdio
5151
## Multimedia display
5252
```@docs
5353
IJulia.display_data
54+
IJulia.update_display_data
5455
```

src/inline.jl

+64-10
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,27 @@ _format_mime_key(k) = error("MIME bundle keys should be instances of String or M
3434
_format_mimebundle(d::Dict{String}) = d
3535
_format_mimebundle(d::AbstractDict) = Dict(_format_mime_key(k) => v for (k, v) in pairs(d))
3636

37+
38+
"""Create JSON content for "display_data" or "redisplay_data" message, properly formatting arguments."""
39+
function _display_msg(mimebundle::AbstractDict, metadata::AbstractDict, display_id::Union{Integer, AbstractString, Nothing})
40+
content = Dict{String, Any}("data" => _format_mimebundle(mimebundle), "metadata" => _format_mimebundle(metadata))
41+
if display_id !== nothing
42+
content["transient"] = Dict("display_id" => display_id)
43+
end
44+
return content
45+
end
46+
47+
function _display_msg(mime::String, data, metadata::AbstractDict, display_id::Union{Integer, AbstractString, Nothing})
48+
bundle = Dict{String, Any}(mime => data)
49+
md = Dict{String, Any}(mime => metadata)
50+
mime != "text/plain" && (bundle["text/plain"] = "Unable to display data with MIME type $mime") # Fallback
51+
return _display_msg(bundle, md, display_id)
52+
end
53+
54+
3755
"""
38-
display_data(mime::Union{MIME, String}, data, metadata::AbstractDict=Dict())
39-
display_data(mimebundle::AbstractDict, metadata::AbstractDict=Dict())
56+
display_data(mime::Union{MIME, String}, data, metadata::AbstractDict=Dict(); display_id=nothing)
57+
display_data(mimebundle::AbstractDict, metadata::AbstractDict=Dict(); display_id=nothing)
4058
4159
Publish encoded multimedia data to be displayed all Jupyter front ends.
4260
@@ -65,6 +83,11 @@ for the keys used by IPython, notable ones are `width::Int` and `height::Int` to
6583
of displayed images. When using the second form of the function the argument should be a dictionary
6684
of dictionaries keyed by MIME type.
6785
86+
`display_id` is an arbitrary integer or string which can be used to update this display at a later
87+
time using [`update_display_data`](@ref). This can be used to create simple animations by updating
88+
the display at regular intervals, or to update a display created in a different cell.
89+
An empty MIME bundle can be passed to initialize an empty display that can be updated later.
90+
6891
6992
# Examples
7093
@@ -105,19 +128,50 @@ Adjust the size of the displayed image by passing a metadata dictionary:
105128
```julia
106129
IJulia.display_data("image/png", data_enc, Dict("width" => 800, "height" => 600))
107130
```
131+
132+
Updating existing display data using the `display_id` argument and [`update_display_data`](@ref):
133+
134+
```julia
135+
IJulia.display_data("text/plain", "Before update", display_id="my_id")
136+
137+
# After some time or from a different cell:
138+
IJulia.update_display_data("my_id", "text/plain", "After update")
139+
```
108140
"""
109-
function display_data(mimebundle::AbstractDict, metadata::AbstractDict=Dict())
110-
content = Dict("data" => _format_mimebundle(mimebundle), "metadata" => _format_mimebundle(metadata))
141+
function display_data(mimebundle::AbstractDict, metadata::AbstractDict=Dict(); display_id::Union{Integer, AbstractString, Nothing}=nothing)
142+
content = _display_msg(mimebundle, metadata, display_id)
143+
flush_all() # so that previous stream output appears in order
144+
send_ipython(publish[], msg_pub(execute_msg, "display_data", content))
145+
end
146+
147+
function display_data(mime::Union{MIME, AbstractString}, data, metadata::AbstractDict=Dict(); display_id::Union{Integer, AbstractString, Nothing}=nothing)
148+
content = _display_msg(string(mime), data, metadata, display_id)
111149
flush_all() # so that previous stream output appears in order
112150
send_ipython(publish[], msg_pub(execute_msg, "display_data", content))
113151
end
114152

115-
function display_data(mime::Union{MIME, AbstractString}, data, metadata::AbstractDict=Dict())
116-
mt = string(mime)
117-
d = Dict{String, Any}(mt => data)
118-
md = Dict{String, Any}(mt => metadata)
119-
mt != "text/plain" && (d["text/plain"] = "Unable to display data with MIME type $mt") # Fallback
120-
display_data(d, md)
153+
154+
"""
155+
update_display_data(display_id, mime::Union{MIME, AbstractString}, data, metadata::AbstractDict=Dict())
156+
update_display_data(display_id, mimebundle::AbstractDict, metadata::AbstractDict=Dict())
157+
158+
Update multimedia data previously displayed with [`display_data`](@ref) using
159+
the `display_id` argument.
160+
161+
Note that in the Jupyter notebook/lab this function need not be called from the
162+
same cell as the original call to `display_data`. The updated data also does
163+
not need to contain the same MIME types as the original.
164+
"""
165+
function update_display_data(display_id::Union{Integer, AbstractString}, mimebundle::AbstractDict, metadata::AbstractDict=Dict())
166+
content = _display_msg(mimebundle, metadata, display_id)
167+
flush_all()
168+
send_ipython(publish[], msg_pub(execute_msg, "update_display_data", content))
169+
end
170+
171+
function update_display_data(display_id::Union{Integer, AbstractString}, mime::Union{MIME, AbstractString}, data, metadata::AbstractDict=Dict())
172+
content = _display_msg(string(mime), data, metadata, display_id)
173+
flush_all()
174+
send_ipython(publish[], msg_pub(execute_msg, "update_display_data", content))
121175
end
122176

123177

0 commit comments

Comments
 (0)