optimised visualisation for short range breathing interactions

This commit is contained in:
Luis Aleixo 2022-03-15 10:41:22 +00:00
parent 2fe013a855
commit b67b2ccf16
3 changed files with 26 additions and 25 deletions

View file

@ -107,14 +107,13 @@ def calculate_report_data(model: models.ExposureModel):
for time in times
]
concentrations = []
for time in times:
sr_breathing_concentrations = []
if len(short_range_intervals) != 0:
for index, (start, stop) in enumerate(short_range_intervals):
# For visualization issues, add short range breathing activity to the initial long range concentrations
if start <= time <= stop and model.short_range.activities[index] == 'Breathing':
concentrations.append(np.array(model.concentration(float(time))).mean())
if model.short_range.activities[index] == 'Breathing':
sr_breathing_concentrations.append(np.array(model.concentration(float(stop))).mean())
break
concentrations.append(np.array(model.concentration_model.concentration(float(time))).mean())
highest_const = max(short_range_concentrations)
prob = np.array(model.infection_probability()).mean()
@ -132,7 +131,7 @@ def calculate_report_data(model: models.ExposureModel):
"exposed_presence_intervals": [list(interval) for interval in model.exposed.presence.boundaries()],
"cumulative_doses": list(cumulative_doses),
"short_range_concentrations": short_range_concentrations,
"concentrations": concentrations,
"concentrations": sr_breathing_concentrations,
"highest_const": highest_const,
"prob_inf": prob,
"emission_rate": er,

View file

@ -402,7 +402,8 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
// Used for controlling the short range interactions
let button_full_exposure = document.getElementById("button_full_exposure");
let button_long_exposure = document.getElementById("button_long_exposure");
let show_sr_legend = button_full_exposure || Math.round(Math.max(...concentrations)) == Math.round(Math.max(...short_range_concentrations))
var data_for_graphs = {
'concentrations': [],
'short_range_concentrations': [],
@ -480,7 +481,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.attr('fill', '#1f77b4')
.attr('fill-opacity', '0.1');
if (button_full_exposure || button_long_exposure) {
if (show_sr_legend) {
var legendShortRangeAreaIcon = vis.append('rect')
.attr('width', 20)
.attr('height', 15)
@ -503,7 +504,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.style('font-size', '15px')
.attr('alignment-baseline', 'central');
if (button_full_exposure || button_long_exposure) {
if (show_sr_legend) {
var legendShortRangeText = vis.append('text')
.text('Short range interaction(s)')
.style('font-size', '15px')
@ -511,7 +512,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
}
// Legend bounding
if (button_full_exposure || button_long_exposure) legendBBox_height = 90;
if (show_sr_legend) legendBBox_height = 90;
else legendBBox_height = 68;
var legendBBox = vis.append('rect')
.attr('width', 255)
@ -569,7 +570,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
var brush = d3.brushY();
function update_concentration_plot(data, long_range_data, data_for_graphs) {
function update_concentration_plot(data) {
yRange.domain([0., Math.max(...data)]);
yAxisEl.transition().duration(1000).call(yAxis);
@ -581,7 +582,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.merge(draw_line.select('.line'))
.transition()
.duration(1000)
.attr("d", lineFunc(long_range_data));
.attr("d", lineFunc(data_for_graphs.short_range_concentrations));
// Area.
exposed_presence_intervals.forEach((b, index) => {
@ -589,7 +590,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.y0(graph_height - 50)
.y1(d => yRange(d.concentration)
);
drawArea[index].transition().duration(1000).attr('d', exposedArea[index](long_range_data.filter(d => {
drawArea[index].transition().duration(1000).attr('d', exposedArea[index](data_for_graphs.short_range_concentrations.filter(d => {
return d.time >= b[0] && d.time <= b[1]
})));
});
@ -600,7 +601,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.y0(graph_height - 50)
.y1(d => yRange(d.concentration));
drawShortRangeArea[index].transition().duration(1000).attr('d', shortRangeArea[index](long_range_data.filter(d => {
drawShortRangeArea[index].transition().duration(1000).attr('d', shortRangeArea[index](data_for_graphs.short_range_concentrations.filter(d => {
return d.time >= b[0] && d.time <= b[1]
})));
});
@ -639,14 +640,14 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.select('.line')
.transition()
.duration(1000)
.attr("d", lineFunc(long_range_data));
.attr("d", lineFunc(data_for_graphs.short_range_concentrations));
// Area.
exposed_presence_intervals.forEach((b, index) => {
exposedArea[index].x(d => xTimeRange(d.time))
.y0(graph_height - 50)
.y1(d => yRange(d.concentration));
drawArea[index].transition().duration(1000).attr('d', exposedArea[index](long_range_data.filter(d => {
drawArea[index].transition().duration(1000).attr('d', exposedArea[index](data_for_graphs.short_range_concentrations.filter(d => {
return d.time >= b[0] && d.time <= b[1]
})));
});
@ -657,7 +658,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
.y0(graph_height - 50)
.y1(d => yRange(d.concentration));
drawShortRangeArea[index].transition().duration(1000).attr('d', shortRangeArea[index](long_range_data.filter(d => {
drawShortRangeArea[index].transition().duration(1000).attr('d', shortRangeArea[index](data_for_graphs.short_range_concentrations.filter(d => {
return d.time >= b[0] && d.time <= b[1]
})));
});
@ -755,7 +756,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
legendAreaText.attr('x', graph_width + 4 * size)
.attr('y', margins.top + 3 * size);
if (button_full_exposure || button_long_exposure) {
if (show_sr_legend) {
legendShortRangeAreaIcon.attr('x', graph_width + size * 2.5)
.attr('y', margins.top + 3.6 * size);
legendShortRangeText.attr('x', graph_width + 4 * size)
@ -784,7 +785,7 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
legendAreaText.attr('x', 2 * size)
.attr('y', graph_height + 2.6 * size);
if (button_full_exposure || button_long_exposure) {
if (show_sr_legend) {
legendShortRangeAreaIcon.attr('x', size * 0.50)
.attr('y', graph_height * 1.175 + size);
legendShortRangeText.attr('x', 2 * size)
@ -804,14 +805,14 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
if (button_full_exposure) {
button_full_exposure.addEventListener("click", () => {
update_concentration_plot(short_range_concentrations, data_for_graphs.short_range_concentrations, data_for_graphs.short_range_concentrations);
update_concentration_plot(short_range_concentrations);
button_full_exposure.disabled = true;
button_long_exposure.disabled = false;
});
}
if (button_long_exposure) {
button_long_exposure.addEventListener("click", () => {
update_concentration_plot(concentrations, data_for_graphs.short_range_concentrations, data_for_graphs.concentrations);
update_concentration_plot(concentrations);
button_full_exposure.disabled = false;
button_long_exposure.disabled = true;
});
@ -852,12 +853,12 @@ function draw_plot(svg_id, times, concentrations, short_range_concentrations, cu
// Draw for the first time to initialize.
redraw();
update_concentration_plot(short_range_concentrations, data_for_graphs.short_range_concentrations, data_for_graphs.short_range_concentrations);
update_concentration_plot(short_range_concentrations);
// Redraw based on the new size whenever the browser window is resized.
window.addEventListener("resize", e => {
redraw();
update_concentration_plot(short_range_concentrations, data_for_graphs.short_range_concentrations, data_for_graphs.short_range_concentrations);
update_concentration_plot(short_range_concentrations);
});

View file

@ -89,8 +89,9 @@
{% endblock report_summary_footnote %}
</div>
<p id="section1">* The results are based on the parameters and assumptions published in the CERN Open Report <a href="https://cds.cern.ch/record/2756083"> CERN-OPEN-2021-004</a>.</p>
{% if form.short_range_option == "short_range_yes" %}
<button class="btn btn-sm btn-primary" id="button_full_exposure" disabled>Show full exposure</button><button class="btn btn-sm btn-primary ml-0" id="button_long_exposure">Hide high concentration</button>
{% if (form.short_range_option == "short_range_yes") and (concentrations|max|int != short_range_concentrations|max|int ) %}
<button class="btn btn-sm btn-primary" id="button_full_exposure" disabled>Show full exposure</button>
<button class="btn btn-sm btn-primary ml-0" id="button_long_exposure">Hide high concentration</button>
{% endif %}
<div id="concentration_plot" style="height: 400px"></div>
<script type="application/javascript">