We can now extend 05 - Include an IFrame.ipynb to pass data to the iframe using either the query string or using window.postMessage. In this case we'll use https://soasta.github.io/julia-d3-tutorial/d3/07-d3-external-data.html?data=<data> as our URL.
Our createIFrame and updateIFrame functions remain the same.
In [15]:
function createIFrame()
displayid = "demo-iframe-" * string(rand())
display(
"text/html",
"""
<!-- First create an empty iframe that's 500px high and has this id -->
<iframe
id="$(displayid)"
height="500"
style="border:none;"
src="about:blank">
</iframe>
<!-- Next create a JavaScript function with the same name as the node -->
<script>
window["$(displayid)"] = function(url) {
var iframe = document.getElementById("$(displayid)");
if(iframe) {
iframe.width = iframe.parentNode.offsetWidth * 0.98;
iframe.src = url;
}
};
</script>
"""
)
return displayid
end
Out[15]:
In [16]:
function updateIFrame(displayid::AbstractString, url::AbstractString)
display(
"text/html",
"""<script>window["$(displayid)"]("$(url)");</script>"""
)
end
Out[16]:
In [25]:
function updateIFrame(displayid::AbstractString, data::Array{Int64, 1})
display(
"text/html",
"""
<script>
(function() {
var iframe = document.getElementById("$(displayid)");
if(iframe) {
iframe.contentWindow.postMessage($(JSON.json(data)), "*");
}
}())
</script>
"""
)
end
Out[25]:
In [18]:
id = createIFrame()
# Note that we do not include the [] for data here since this is not JSON, it's just a csv
updateIFrame(id, "https://soasta.github.io/julia-d3-tutorial/d3/07-d3-external-data.html?data=36,90,168,370,589,867,951,873,838,752,637,542,479,359,303,291,199,186,146,119,115,100,77,90,67,753")
In [26]:
updateIFrame(id, Int64[0,0,0,2,6,5,10,11,15,18,25,11,19,8,4,8,3,10,6,6,2,2,1,1,1,24])
In [27]:
using DataFrames
df = readtable("data.csv");
# Function to set histogram thresholds after dropping outliers based on IQR
function getSymmetricThresholds(results::DataFrame; timer::Symbol=:timers_t_done)
summary = summarystats(results[timer])
fw = (summary.q75-summary.q25)*1.5
low = round(Int64, max(summary.min, summary.q25-fw))
high = round(Int64, min(summary.max, summary.q75+fw))+1
thresholds::Array{Int64, 1} = []
nthresholds=25
range = high - low
for i in 0:nthresholds-1
push!(thresholds, round(Int64, low + i * range/nthresholds))
end
push!(thresholds, high)
if high < round(Int64, summary.max)
push!(thresholds, round(Int64, summary.max))
end
return thresholds
end
Out[27]:
In [32]:
thresholds = getSymmetricThresholds(df)
groups = by(
df,
:user_agent_family,
rows -> DataFrame(
count = size(rows, 1),
median = median(rows[:timers_t_done]),
hist = JSON.json(hist(rows[:timers_t_done], thresholds)[2])
)
)
sort!(groups, rev=true, cols=[:count])
Out[32]:
In [29]:
groups[groups[:user_agent_family] .== "Firefox", :hist][1]
Out[29]:
In [30]:
# Take the histogram (string) out of the dataframe, and convert it to a numeric array
groupdata = JSON.parse(groups[groups[:user_agent_family] .== "Firefox", :hist][1])
# Pass that array to the IFrame
updateIFrame(id, groupdata)
The output shows up in the iframe above, so scroll up to see it
In fact, we could draw multiple histograms, one for each of the groups that we created
In [33]:
for i in 1:min(10, size(groups, 1))
local id = createIFrame()
local data = groups[i, :hist]
updateIFrame(id, "https://soasta.github.io/julia-d3-tutorial/d3/07-d3-external-data.html?data=$(data)")
display("text/html", """
<p style="border-top: dashed 1px #ddd; border-bottom: solid 2px #000; padding-bottom: 3em;">
<strong>$(groups[i, :user_agent_family]):</strong>
<em>$(groups[i, :count])</em> records, median load time: <em>$(groups[i, :median])</em>ms
</p>
"""
)
end
In [ ]: